I have the following jquery method:
$('.niGridTable table tr').addClass('selected').end().click(function (event) {
event = event || window.event;
var isClassExist = false;
var closesedTable = $(event.target).closest('tr').find('.selected_row');
if (closesedTable.length > 0) {
isClassExist = true;
if (event.ctrlKey) {
for (var i = 0; i < closesedTable.length; i++) {
if ($(closesedTable[i]).hasClass('selected_row')) {
$(closesedTable[i]).removeClass('selected_row');
}
}
}
}
if (!event.ctrlKey) {
if ($('td').hasClass('selected_row')) {
$('td').removeClass('selected_row');
}
}
if (!isClassExist) {
$('.table-striped > tbody > tr:hover > td').addClass('selected_row');
}
});
I want to write such code as angular way.like...
element.on('click', function (event) {
}
In my directive I have changed my question said jquery to Angularjs. In this case I have use angular.element.
$timeout(function () {
//get all row for set selected row class
var trs = iElement.find('tr');
for (var index = 0; index < trs.length; index++) {
var tableTr = angular.element(trs[index]);
//remove prvious click event
tableTr.unbind('click');
tableTr.bind('click', function (event) {
event = event || window.event;
event.stopPropagation();
event.preventDefault();
//if target row contain previos selection then remove such selection
var isClassExist = false;
var targetTd = angular.element(event.target);
var targetTr = targetTd.parent();
if (targetTr.hasClass('selected_row')) {
targetTr.removeClass('selected_row');
isClassExist = true;
}
//if another row contain selection then remove their selection but if control button pressed then it will not work
var closesedTable = iElement.find('tr');
if (closesedTable.length > 0) {
if (!event.ctrlKey) {
for (var i = 0; i < closesedTable.length; i++) {
var eachRow = angular.element(closesedTable[i]);
if (eachRow.hasClass('selected_row')) {
eachRow.removeClass('selected_row');
}
}
}
}
//set selection
if (!isClassExist) {
targetTr.addClass('selected_row');
}
////get selected rows
//for (var j = 0; j < trs.length; j++) {
// gridOption['selectedRow'].push();
//}
});
}
}, 0);
Related
I want to delete after clicking the product button, but it does not work properly I do not know why. It does not remove the correct object from the table
document.addEventListener('click', function(e) {
if (e.target.id === 'removeItem') {
var divWithItem = document.getElementsByClassName('containerBasket__allProducts__product');
// Pobieram name itemu
var nameItem = e.target.parentElement.parentElement.getAttribute('name');
var thisItemDiv = e.target.parentElement.parentElement;
var thisItem = JSON.parse(products[nameItem]);
products.splice(thisItem, 1);
localStorage.setItem('product', JSON.stringify(products));
thisItemDiv.remove();
for (var i = 0; i < products.length; i++) {
for (var j = 0; j < divWithItem.length; j++) {
divWithItem[j].setAttribute('name', [j]);
}
}
console.log(products);
}
});
Before looping
After looping
Why does a div with the same name?
I have a very strange problem with some jquery code that scrolls a group of images. It seems to work in all browsers for the first several clicks, advancing the images by a number. And in Safari, it will work perfectly all the way to the end of the slideshow. But in FF and Chrome it will stop after a certain number of images. And this number is NOT always the same for some reason.
For example, on this page FF/Chrome will stop after clicking the next arrow 7 times.
And on this page, FF/Chrome will stop after clicking the next arrow 6 times.
Yet on this page, FF/Chrome will work all the way to the end as expected (and as Safari does all the time).
This is the code that controls the clicking:
<script>$(window).load(function(){
var currentElement = $("#ngg-gallery-list > div:nth-child(2)");
var onScroll = function () {
//get the current element
var container = $("#ngg-galleryoverview");
var wrapper = $("#ngg-gallery-list");
var children = wrapper.children();
var position = 0;
for (var i = 0; i < children.length; i++) {
var child = $(children[i]);
var childLeft = container.offset().left < child.offset().left;
if (childLeft) {
currentElement = child;
return;
}
}
}
var scrollToElement = function ($element) {
var container = $("#ngg-galleryoverview");
var wrapper = $("#ngg-gallery-list");
var children = wrapper.children();
var width = 0;
console.log(children.length);
for (var i = 0; i < children.length; i++) {
var child = $(children[i]);
if (child.get(0) == $element.get(0)) {
if (i == 0) {
width = 300;
}
container.animate({
scrollLeft: width
}, 300);
onScroll();
}
if (child.next().length > 0) {
//make sure we factor in borders/padding/margin in height
width += child.next().offset().left - child.offset().left
} else {
width += child.width();
}
}
}
var next = function(event) {
event.preventDefault();
scrollToElement(currentElement);
}
var prev = function(event) {
event.preventDefault();
var container = $("#ngg-galleryoverview");
if (currentElement.prev().length > 0) {
if (container.offset().left == currentElement.prev().offset().left) {
currentElement = currentElement.prev().prev().length > 0 ? currentElement.prev().prev() : currentElement.prev();
} else {
currentElement = currentElement.prev();
}
}
scrollToElement(currentElement);
}
$("#ngg-galleryoverview").on('scroll', onScroll);
$("#nexty").click(next);
$("#prevy").click(prev);
});
</script>
I'm stumped.
Well, making my code look more like what I found here fixed the problem. (Even if I am not entirely sure why). Hoping it helps someone else, here is the final code:
<script>
$(document).ready(function () {
var currentElement = $("#ngg-galleryoverview > div:nth-child(1)");
var onScroll = function () {
var container = $("#ngg-galleryoverview");
var children = $(".list");
for (var i = 0; i < children.length; i++) {
var child = $(children[i]);
var childLeft = container.offset().left < child.offset().left;
if (childLeft) {
currentElement = child;
//console.log(currentElement);
return;
}
}
};
var scrollToElement = function ($element) {
var container = $("#ngg-galleryoverview");
var children = $(".list");
var width = 0;
for (var i = 0; i < children.length; i++) {
var child = $(children[i]);
if (child.get(0) == $element.get(0)) {
if (i === 0) {
width = 0;
}
container.animate({
scrollLeft: width
}, 500);
onScroll();
}
if (child.next().length > 0) {
width += child.next().offset().left - child.offset().left;
} else {
width += child.width();
}
}
};
var buttonright = function (e) {
scrollToElement(currentElement.next());
};
var buttonleft = function (e) {
var container = $("#ngg-galleryoverview");
if (currentElement.prev().length > 0) {
if (container.offset().left == currentElement.prev().offset().left) {
currentElement = currentElement.prev().prev().length > 0 ? currentElement.prev().prev() : currentElement.prev();
} else {
currentElement = currentElement.prev();
}
}
scrollToElement(currentElement);
};
onScroll();
$("#ngg-galleryoverview").scroll(onScroll);
$("#nexty").click(buttonright);
$("#prevy").click(buttonleft);
});</script>
I am using Bootstrap.
I am not able to figure out how to put this in pure javascript.This will open a div when we click on the accordion.
$(function() {
$("#panelTicketsList .list-group-item").on("click", function() {
$("#panelTicketsList .list-group-item").removeClass('selected');
$(this).addClass('selected');
if ($('#panelTicketsList').hasClass('col-md-12')) {
$('#panelTicketsList').removeClass('col-md-12').addClass('col-md-3');
$('.panelTicketDetail').removeClass('hide');
}
});
});
jsFiddle : https://jsfiddle.net/tqdc6yyL/
var listGroupItems = document.getElementsByClassName('list-group-item');
for (j = 0; j < listGroupItems.length; j++) {
listGroupItems[j].addEventListener("click", function () {
var elements = listGroupItems;
for (i = 0; i < elements.length; i++) {
if (elements[i].className.indexOf("col-md-12") > -1) {
elements[i].className = elements[i].className.replace("col-md-12", "col-md-3");
elements[i].className = elements[i].className.replace("hide", "");
}
}
this.className = this.className + " selected";
});
}
var list = document.getElementById('panelTicketsList');
var items = document.querySelectorAll("#panelTicketsList .list-group-item");
var detail = document.querySelectorAll(".panelTicketDetail");
items.forEach(function(btn){
btn.addEventListener("click", function(){
items.forEach(function(item){ item.classList.remove("selected"); });
this.classList.add("selected");
if(list.classList.contains('col-md-12')) {
list.classList.remove('col-md-12');
list.classList.add('col-md-3');
detail.classList.add("hide");
}
});
If you have to support older browsers like IE8 or IE9, you can't use JS features like forEach or classList. Instead you should use for loop and className.
//Save DOM query in variable for reuse
var panelTicketsList = document.getElementById('panelTicketsList');
var panelTicketsDetails = document.getElementsByClassName('panelTicketDetail');
var listGroupItems = panelTicketsList.getElementsByClassName('list-group-item');
//go through all of the listGroupItems and set click listener
for (var i = 0; i < listGroupItems.length - 1; i++) {
listGroupItems[i].addEventListener("click", function() {
//On click, go through all of listGroupItems and remove selected class
for (var j = 0; j < listGroupItems.length - 1; j++) {
listGroupItems[j].className = listGroupItems[j].className.replace('selected', '');
}
//Add selected class for clicked element
listGroupItems[i].className += 'selected';
//test if main element has class col-md-12
if (panelTicketsList.className.indexOf("col-md-12") > -1) {
//replace clas col-md-12 with col-md-3
panelTicketsList.className = panelTicketsList.className.replace('col-md-12', 'col-md-3');
//go through all of the panelTicketDetails and remove hide class
for (var k = 0; k < panelTicketsDetails.length - 1; k++) {
panelTicketsDetails[k].className = panelTicketsDetails[k].className.replace('hide', '');
}
}
});
}
I need to implement a simple event and dom manipulation, but I can't use jQuery
So I am attaching the event to each single node using for()
document.addEventListener("DOMContentLoaded", function(event) {
var mainList = document.getElementById('mainList');
var mainNodes = document.querySelectorAll('#mainList > li');
for (var i = 0; i < mainNodes.length; i++) {
var node = mainNodes[i];
node.addEventListener('contextmenu', function(e){
e.preventDefault();
var currentActive = document.querySelectorAll('.active');
if(currentActive[0]) { // first item with class 'active'
currentActive[0].className = '';
}
this.className = 'active';
});
var options = node.getElementsByTagName('li');
for (var j = 0; j < options.length; j++) {
var option = options[j];
option.addEventListener('click', function(e){
e.preventDefault();
switch(this.className){
case 'eliminar':
delete(mainList,node);
break;
case 'obrir':
open(mainList,node);
break;
case 'clonar':
clone(mainList,node);
break;
}
node.className = '';
});
}
}
});
The problem here is that even that all elemnts have the event, its allways opened/cloned/deleted the last node,
Doesn't using var node applies only to the current node in the loop?
-fiddle-
http://jsfiddle.net/toniweb/Wx8Jf/34/
Your event handler will be triggered later. When the loop finishes, the node is the last node. You need to create a closure to capture the current node. Something like this:
for (var i = 0; i < mainNodes.length; i++) { (function(node){
//your code
}(mainNodes[i]))
}
Try:
for (var i = 0; i < mainNodes.length; i++) { (function(node){
//Your code
node.addEventListener('contextmenu', function(e){
e.preventDefault();
var currentActive = document.querySelectorAll('.active');
if(currentActive[0]) { // first item with class 'active'
currentActive[0].className = '';
}
this.className = 'active';
});
var options = node.getElementsByTagName('li');
for (var j = 0; j < options.length; j++) {
var option = options[j];
option.addEventListener('click', function(e){
e.preventDefault();
switch(this.className){
case 'eliminar':
delete(mainList,node);
break;
case 'obrir':
open(mainList,node);
break;
case 'clonar':
clone(mainList,node);
break;
}
node.className = '';
});
}
}(mainNodes[i]))
}
Let's have an example:
<table>
<tr class="need"></tr>
<tr class="no-need"></tr> // This is ourElement, needs to be removed
<tr></tr> // This element needs to be removed
<tr class="no-need"></tr> // This element needs to be removed
<tr class="no-need"></tr> // This element needs to be removed
<tr class="need"></tr> // Elements removed until this
</table>
I want to remove those four elements at once.
This is what I've done:
function remove(ourElement) {
var body = ourElement.parentNode,
bodyRows = body.getElementsByTagName('tr');
for (var i = 0; i < bodyRows.length; i++) {
if (bodyRows[i] == ourElement) {
if (!bodyRows[i+1].className) {
body.removeChild(bodyRows[i+1]);
}
}
if (bodyRows[i] > ourElement) {
if (bodyRows[i].className == 'no-need') {
body.removeChild(bodyRows[i]);
}
if (bodyRows[i].className == 'need') {
break;
}
}
}
body.removeChild(ourElement);
}
The function removes only the first empy row after ourElement and the ourElement itself.
As i wrote above, I need to remove those four elements at first run of our function.
Pure Javascript needed.
I just realised you may be looking for a function to delete items inside boundaries lets say:
items between class"need" and class"need" and delete all items inside them. if thats your question the answer is as follows:
function remove( tagElement, boundClass ) {
var tr = document.getElementsByTagName(tagElement),
re = new RegExp("(^|\\s)"+ boundClass +"(\\s|$)"),
bound = false,
r = [];
for( var i=0, len=tr.length; i<len; i++ ) {
if( re.test(tr[i].className) ) {
bound = ( bound === true ) ? false : true;
if(bound) continue;
}
if( bound ) r.push( tr[i] );
}
while( r.length )
r[ r.length - 1 ].parentNode.removeChild( r.pop() );
}
remove( "tr", "need" ); // use it like this
you need something like this:
function remove(ourElement) {
var body = ourElement.parentNode;
var childRows = body.childNodes;
var found = false;
for (var i = 0; i < childRows.length; i++) {
var row = childRows[i];
if(found) {
if(!row.className || row.className == "no-need") {
body.removeChild(row);
i--; // as the number of element is changed
} else if(row.className == "need") {
break;
}
}
if(row == ourElement) {
body.removeChild(ourElement);
found = true;
i--; // as the number of element is changed
}
}
}
You cannot use the < or > operators with DOM elements.
function remove(ourElement) {
var body = ourElement.parentNode,
bodyRows = body.getElementsByTagName('tr'),
lb = false;
for (var i = 0; i < bodyRows.length; i++) {
lb = (lb)?(bodyRows[i] == ourElement):lb;
if(lb){
if (!bodyRows[i].className) {
body.removeChild(bodyRows[i]);
}else if (bodyRows[i].className == 'no-need') {
body.removeChild(bodyRows[i]);
}else if (bodyRows[i].className == 'need') {
break;
}
}
}
}
Try this, every time it removes a child it decreases i to compensate:
function remove(ourElement) {
var body = ourElement.parentNode,
bodyRows = body.getElementsByTagName('tr'),
lb = false;
for (var i = 0; i < bodyRows.length; i++) {
if (!lb && bodyRows[i] != ourElement) {
continue;
} else if(bodyRows[i] == ourElement){
lb = true;
}
if (bodyRows[i].className == 'no-need' || !bodyRows[i].className) {
body.removeChild(bodyRows[i]);
i--;
}
}
}