I'm trying to check if each element of an ul list is visible using the jquery.visible plugin. The problem is that the script does not handle each "li" element as independent, so putting this:
var element = $("ul li");
if (element.visible(true)) {
element.removeClass("hidden");
}
Removes the "hidden" class of all elements at the same time.
Any ideas?
You are initializing element as an array, so the name is misleading, and it may be throwing you off later in the code.
You want something like this (untested):
var arrElements = $("ul li");
arrElements.each(function() {
if ($(this).visible(true)) {
$(this).removeClass("hidden");
}
});
Note that I am using the each method and $(this) to act on only one li element at a time.
How about checking just the css property:
if(element.css('display') != 'none')
Related
I want to find every specific LI element on a page, look through it for particular class, pull out that class, change it a bit and then set their values as variables.
There are up to 12 li items on a page at one time, and each have different values of the 'was' price. I want to grab that 'was' price and use within that li element only.
Here is what I have so far:
js:
jQuery(document).ready(function () {
jQuery("#productList ul.gridStyle li").each(function () {
var wasPriceMinusWasRemoval = jQuery('#productList p.was').text().replace(/\u00A3/g, '');
var wasPrice = wasPriceMinusWasRemoval.replace("Was ", "");
console.log(wasPrice); // ==> "149.99Was 119.99" (should be just 149.99)
// generate a specific tag using .attr() dependent on
// wasPrice value inside this li element
});
});
Question is, where to go from here? Use of index?
Try to use the this reference inside the .each() function,
var wasPriceMinusWasRemoval = jQuery('p.was',this).text().replace(/\u00A3/g, '');
Having a bit of trouble when using this:
$('.instrumentSelect').click(function(){
var thisElement = $(this).index();
$('.instrumentSelect').eq(thisElement).addClass('active');
$('.active').removeClass('active');
});
removes class just fine, I console logged var thisElement and returns the correct index, just not appending the class to it. Fire bug does not return an error.
I'm not sure what you're trying to do, but removing the class first and adding it later makes more sense. Also, why are you using index and eq() when you can add a class with $(this)?
Try this:
$('.instrumentSelect').click(function(){
$('.active').removeClass('active');
$(this).addClass('active');
});
$('.instrumentSelect').click(function(){
var thisElement = $(this).index();
$('.instrumentSelect').eq(thisElement).addClass('active');
$('.active').not($(this)).removeClass('active');
});
or more simply you invert those lines like this
$('.active').removeClass('active');
$('.instrumentSelect').eq(thisElement).addClass('active');
You are adding it and then removing it. You have to exclude the object you are manipulating.
Probably you're trying to clear .active class before adding it to current item
$('.active').removeClass('active');
$('.instrumentSelect').eq(thisElement).addClass('active');
Is it possible using JavaScript to dynamically remove just a few li elements from a ul, given the id's of the li elements?
UPDATE about the actual issue:
I've the following list.
<ul id="attributes" data-role="listview">
<li id="attrib01">Attribute1</li>
<li id="attrib02">Attribute2</li>
<li id="attrib03">Attribute3</li>
<li id="attrib04">Attribute4</li>
<li id="attrib05">Attribute5</li>
</ul>
After a ajax request/response, if a particular attribute is "undefined", I want to remove it from the list.
if(typeof data.attrib1 === "undefined")
$("#attrib01").remove();
I've made sure I'm receiving the correct ajax response. So, the problem now is, that when I remove attrib4, attrib[1-3] are being removed as well. Any idea why this might be happening?
Try
var elem = document.getElementById('id');
elem.parentNode.removeChild(elem);
If you get the element then find its parent then remove the element. from the parent as follows:
element = document.getElementById("element-id");
element.parentNode.removeChild(element);
It is necessary to go through the parent so this is unavoidable.
$('#id').remove() is the correct way to remove a single element. Note that element IDs must be unique in html, and that invocation must be wrapped in a DOM ready function.
This is a working example based on your html. It loops through all the list-items and removes the one whose id is not present in the data object:
var data = {
attrib01: "Number 1",
attrib02: "Number 2",
attrib04: "Number 4"
};
$(document).ready(function() {
$("ul > li").each(function() {
alert(this.id in data); //check if value is defined
if(!(this.id in data)) {
$(this).remove();
// This also works:
//$('#'+this.id).remove();
}
});
});
It is also possible to target and remove only a single element (Demo) by simply doing:
$(document).ready(function() {
$("#attrib04").remove();
});
Be careful with your IDs -- they must match exactly. attrib04 != attrib4
This will make the li elements invisible:
document.getElementById("id_here").style.visibility = "hidden";
Disclaimer: they will still be in the DOM
To remove elements from the DOM use JQuery's .remove() method:
$("#id_here").remove();
http://api.jquery.com/remove/
I'm having some trouble figuring out how to add elements to a parent object on a click event.
The result that i'm hoping to achieve is this:
<ul>
<li><button>B1</button>
<ul class="newul">
<li><button>B1.1</button>
<ul class="newul">
<li><button>1.1.1</button></li>
<li><button>1.1.2</button></li>
</ul>
</li>
<li><button>B1.1</button></li>
</ul>
</li>
<li><button>B2</button></li>
<li><button>B3</button></li>
</ul>
Let's say I click button B2. I want a new UL added to the parent LI of that button and then be able to add new LI elements to the newly created UL. I hope that makes sense!
So basically, click button, add new UL with class "newul" to the LI you're currently in -> add new LI's to that newly created UL.
The jquery I'm currently using is as follows:
$('button').click(function(){
//Get parent..
var parent = $(this).parent();
//Add a new UL to the parent and save it as newul
var newul = parent.add("ul");
//Add the class to the new UL
newul.addClass('newul');
//Add a new li to the new UL
newli = newul.add('li');
//Add a button to the new LI
newli.append('<button></button>');
});
Unfortunately, this is having completely undesired effects and sticks buttons everywhere all over the place. I'd appreciate any help you can offer.
Here's a visible example of what i'm after. The top part is the effect id like to achieve.
Example of desired result
Even though #am not i am has the correct code. There is no explanation of why your code fails, and I think that's the answer you are asking for.
There are several problems in your code:
First
//Add a new UL to the parent and save it as newul
var newul = parent.add("ul");
The 'ul' is a selector and so is going to search the DOM for other <ul> elements, rather than create a new one. Also, parent.add() method is returning the parent object, not the ul's that you selected.
Correct code:
//Add a new UL to the parent and save it as newul
var newul = $("<ul>").appendTo(parent);
Second:
//Add a new li to the new UL
newli = newul.add('li');
Same problem again, and since newul is actually still the parent you're getting all types of craziness. Also, you're missing a var, but maybe I just don't get your closure.
Correct code:
//Add a new li to the new UL
var newli = $("<li>").appendTo(newul);
That's all. If you fix that in your code, it'll work.
However, unless you really need those references to persist, better performance is usually achieved if you pass the whole thing as a string:
$('button').click( function() {
$(this).parent()
.append(
$('<ul class="newul"><li><button></li></ul>')
);
});
Edit
And if you wanted all the new buttons to have the same functionality, use the on() method and a class for your buttons:
$('body').on('click', 'button.ul-appending', function() {
$(this).parent()
.append(
$('<ul class="newul"><li><button class="ul-appending"></li></ul>')
);
});
You could change the 'body' selector to something much more specific so this doesn't get queried on every click on your page. Just make sure to add the class ul-appending to all the existing buttons that aren't generated by this handler.
JSFiddle
One issue I see here is that the new buttons created will not have the click event bound to them. I fix this by using on and setting the event as a delegate. In doing so I give the outer ul an id of container. I also check to make sure you haven't already added a ul element and append one if it isn't inside the li. Here is a working example.
$('#container').on("click", "button.newbtn", function(){
var parent = $(this).closest('li');
var childUl = parent.children('ul');
if(childUl.length === 0) {
parent.append("<ul class='newul'></ul>");
childUl = parent.children('ul');
}
childUl.append($("<li><button class='newbtn'>" + $(this).html() + "." + (childUl.children().length + 1) + "</button></li>"));
});
$('button').click(function(){
//Get parent..
var parent = $(this).parent();
//Add a new UL to the parent and save it as newul
var newul = $("<ul/>");
//Add the class to the new UL
newul.addClass('newul');
//Add a new li to the new UL
var newli = $('<li/>');
//Add a button to the new LI
newli.append('<button></button>');
// add ul to parent li
parent.append( newul.append( newli ) );
});
The issue here is that you're using .add() instead of .after().
.add() adds the passed element to the current selection. .after() adds the passed elements after the current selection.
Using .after(), we can simplify your script into a nice little one-liner:
$('button').click(function(){
$(this).after('<ul class="newul"><li><button></button></li></ul>');
});
Since .after() inserts content next to the current element, there's no need to get the .parent(). .after() can take a complete string of HTML, so there's no need to use jQuery to manipulate the class and add the child elements.
Example.
Use .on function for dynamically added elements.
You can use something like this.
$(document).ready(function(){
i = 1;
$('body').on("click","button",function(event){
$(this).after('<ul class="newul"><li><button>TestButton'+i+'</button></li></ul>');
i++;
});
});
Here is the DEMO. Adjust button with your css and button values accordingly.
I have a live search and a list element is given a class of hover I am then trying to get the next li element after the hover class upon pressing the down arrow and adding the hover class to that element. Here is what I have:
if(e.keyCode == 40){
var current = results.find('li.hover');
current.removeClass();
current.parent().next('li').addClass('hover');
return false;
}
It just will not add a class to the next element. It finds the current class just fine. Not sure what I am doing wrong. Appreciate it!
Use e.which, not e.keyCode. jQuery normalizes the property (IE doesn't support e.keyCode):
if(e.which == 40){
As for your selector, try this:
results.find('li.hover').removeClass().next('li').addClass('hover')
.next() looks for the next sibling matching the selector, so there is no need to call .parent().
You are looking for the LI.hover, after that you go to the parent (which is the UL) and then select the next LI after the UL.
Change this:
current.parent().next('li').addClass('hover');
To:
current.next('li').addClass('hover');
current.parent().next('li') is probably not doing what you want.
Since current is a jQuery object of li tags, I assume that it's parent is a ul tag. If that's the case, then next('li') is looking for a first sibling of the ul tag that's an li tag which it will never find.
It's unclear to me which li you want to add the hover class to so I'm not sure exactly what to recommend to do what you want.
Do not you just want to do that :
if(e.keyCode == 40){
var current = results.find('li.hover');
current.removeClass();
current.next('li').addClass('hover');
return false;
}
without parent() ?
current.nextSibling should refer to the next li element in the list