Finding closest previous li - javascript

I'm currently trying to select the previous closest list element within an <ul>
My current method works if there is > 1 <li> inside of it.
html:
<ul id="coaches" class="list">
<li><span>bob<a class="close"></a></span></li>
<li class="colored"><span>cobb<a class="close"></a></span></li>
</ul>
js:
$(this).closest("li").fadeOut("normal", function() {
$(this).remove();
});
How can I make it delete the previous closest list element with both the number of list element = 1 and > 1 elements? I tried adding a prev() and prevAll() chained after closest('li') but to no avail. Any ideas?

It should work as you have it in your example..
demo at http://jsfiddle.net/gaby/nZXxD/ for the code as it currently is
demo at http://jsfiddle.net/gaby/nZXxD/1/ for the code with a single li element..
The problem must lie somewhere else..
(are you sure the event is bound correctly? and after the DOM is ready ?)
$(function(){
$('a.close').click(function(){
$(this).closest("li").fadeOut("normal", function() {
$(this).remove();
});
});
});

it just working fine with prev()
check the link http://jsfiddle.net/ABqpN/5/

Assuming $(this) is referring to the "a" tags inside "span" inside "li", and assuming that when you click on the "a" it's parent "li" should get removed, you can do this:
$(this).parent('li').fadeOut("normal", function() {
$(this).remove();
});

Related

How do I target the "this" element of "this's" child?

Hi I am trying to target "this" child descendant of "this."
Below is a list that contains sublists.
What I am trying to accomplish is an understanding of how to select this child of this parent.
Basically when I click on Honda, the sublist expands and I want to console.log the text of each selected element when I click it. For simplification purposes I changed the code to a console.log.
So far what the code below returns is the text for everything within the li.
IE if I click Honda or If I click Accord, the console returns the values "Honda, Accord, and CRV."
How would I traverse "this" to get the text of the clicked child of "this". The "this" of "this".
IE if I select "Accord" using my code below it should return the text "Accord" alone.
Code:
<ul class="main-menu">
CARS
<ul>
<li class="has-subs">
Honda
<ul class="sub-menu">
<li>Accord</li>
<li>CRV</li>
</ul>
</li>
<li class="has-subs">
Ford
<ul class="sub-menu">
<li>Mustang</li>
<li>Explorer</li>
</ul>
</li>
</ul>
$('body').on('click', '.main-menu ul li', function (e) {
e.preventDefault();
$this = $(this);
console.log($this.text());
if ($(this).find("a").text() == "CRV") {
var subMenu = $this.siblings('.sub-menu');
console.log("'THIS' SELECTOR IS WORKING AS INTENDED!");
}
})
Update:
Thanks all for answering! I think it will help to explain further what I am trying to accomplish.
What I am ultimately am trying to get sorted out is that I have a master accordion list with a list of car manufacturers and each manufacturer has a submenu like shown above.
I want to click on a list item, say Honda, it expands only Honda's list and shows their makes ie Accord and CRV. Then when I click on either Accord or CRV, it goes to their respective webpages.
When I click on a Ford, Honda's list should collapse or be hidden and Ford's should expand.
Here's a solution that makes your code work with minimal changes, however note that this setup is problematic since it creates a new (duplicate) event listener on every click.
$('body').on('click', '.main-menu ul li', function (e) {
e.preventDefault();
$this = $(this);
console.log($this.text());
$this.on('click', 'li', function(e) {
if ($(this).find("a").text() == "CRV") {
var subMenu = $this.siblings('.sub-menu');
console.log("'THIS' SELECTOR IS WORKING AS INTENDED!");
}
})
})
As #freedomn-m pointed out, your selectors are probably too broad. I'm not exactly sure what you're ultimately trying to do with the line selecting the sub-menu, but here's an alternate solution that's cleaner:
$('.has-subs>a').click(function(e) {
e.preventDefault();
console.log($(this).parent().text());
});
$('.sub-menu>li>a').click(function(e) {
e.preventDefault();
console.log($(this).text());
});
jsbin: http://jsbin.com/lurutiwago/edit?html,js,console,output
Your current selector
.main-menu ul li
will find all ul/li, under .main-menu, so will match Honda and Accord/CRV.
If you want to only act on the top-level items (Honda), you can change your selector to be more specific:
.main-menu>ul>li
(assuming they're correctly inside .main-menu).
Or, if you only want the lower ones:
.main-menu>ul>li>ul>li
or, in your case, target the 'ul' directly
ul.has-subs>li
or
ul.sub-menu>li

Find element above another using jQuery

I'm trying to find the element using jQuery from the following html.
<ul class="gdl-toggle-box">
<li class="">
<h2 class="toggle-box-title"><span class="toggle-box-icon"></span>Volunteer Form</h2>
<div class="toggle-box-content" style="">
</div>
</li>
</ul>
What I'm looking to do is when the h2 is clicked find the li above the h2 add a class active to it. Tried a few different calls but no luck.
EDIT
The biggest issue is that there are multiple toggle boxes on a page so something like this works on pages with a single toggle but pages with multiple the result is they all open together.
var gdl_toggle_box = jQuery('ul.gdl-toggle-box');
gdl_toggle_box.find('li').each(function(){
jQuery(this).addClass('item');
});
gdl_toggle_box.find('li').not('.active').each(function(){
jQuery(this).children('.toggle-box-content').css('display', 'none');
});
gdl_toggle_box.find('h2').click(function(){
if( jQuery('.item').hasClass('active') ){
jQuery('.item').removeClass('active').children('.toggle-box-content').slideUp();
}else{
jQuery('.item').addClass('active').children('.toggle-box-content').slideDown();
}
});
You can use closest.
closest will match the first parent element that matches the selector traversing up the DOM tree.
Demo
$('h2.toggle-box-title').click(function(){
$(this).closest('li').addClass('active');
});
Try this.
$('h2.toggle-box-title').click(function(){
$(this).parent().addClass('newclass');
});
try this:
$('h2.toggle-box-title').click(function() {
$(this).parent('li').addClass('active');
});
On you click in the button you can use the event:
$("something").parent().find("h2.myClass");
// And if you want you can add class after you find you object
http://api.jquery.com/find/
Selecting an element's parent
In order to select an element parent, you can use the parent() function.
Try this:
$('h2.toggle-box-title').click(function() {
$(this).parent('li').addClass('active');
});
*to be more specific, you target the parent you would like to choose by specifying its selector
Check the jQuery API Documentation here
parent() - Get the parent of each element in the current set of matched elements,
optionally filtered by a selector.

Deleting <li> issue

I'm building a recipe saving application where I have a form that looks like this http://jsfiddle.net/LHPbh/.
As you can see, I have a set of form elements contained in an <li>. You can click Add Ingredient and have more li's added to the field.
My problem is:
The first li is the only one that deletes. If you click Add Ingredient, and then try and delete that one, nothing works?
Is there a way to not have the first li have a delete by it, but all subsequent li's have a delete link on the side? (Just because there should always be at least one ingredient?)
When you call clone(), it isn't duplicating the events. You need to call clone(true) in order for it to do this, as explained in the documentation.
You did not put an event listener on the cloned elements. Also, you should not give the "delete"-link its own id, as those need to be unique.
To make the first ingredient have no delete button, just don't include one in your markup but only dynamically create and append them to the cloned elements:
var deleteButton = $("<a class='float-left'>Delete</a>").click(deleteThis);
$('ul#listadd > li:first')
.clone()
.attr('name', 'ingredient' + newNum)
.append(deleteButton)
.appendTo('ul#listadd');
function deleteThis() {
var li = $(this).closest('li')
li.fadeOut('slow', function() { li.remove(); });
}
Demo at jsfiddle.net
http://jsfiddle.net/LHPbh/2/
$('.deleteThis').live("click", function () {
var li = $(this).closest('li')
li.fadeOut('slow', function() { li.remove(); });
});
It is answer to the 1. point. The problem was, that the eventhandler binding did not happen in newly created elements, because this code runs only on the load of the page. This can be solved by using .live(). And an other problem was, that id-s must be unique. So instead id, here you can use class .deleteThis.
http://jsfiddle.net/LHPbh/19/
This has added answer to the 2. point:
if ($("#listadd li").length == 1) {
return;
}
If the list only contains 1 li element the rest of the callback will not run.
You are adding items that are added to the DOM dynamically, thus jQuery can't access them :)
In this case you can use the following code:
$(document).on('click', '.selector', function(e) {
//code here
});
Secondly, you were loading a quite old version of jQuery.
Thirdly, you were trying to select an element with an ID that already existed, and ID's can only exist one time. I've changed it to a class in the updated example.
Lastly, you were defining the class of the link twice like this:
<a class='float-left' id="deletethis" href='#' class="deletethis">Delete</a>
That also gave a problem, so I changed it to correct markup like this:
<a class='float-left deletethis' href='#'>Delete</a>
Good luck :) I've updated your jsFiddle here:
http://jsfiddle.net/q4pf6/

Removing li elements from ul

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/

How can i know which class was selected via jQuery & JS

I have a list with links:
<li class="link-1">One</li>
<li class="link-2">Two</li>
<li class="link-3">Three</li>
..
user clicks on any link, then with jQuery I want to display the content of the link.. somthing like:
$(".link-??? a").click(function() {
alert($(".link-??? a").html());
})
something like this. I am not going to create X function (as the number of the links), so what can I do? I should replace the ??? in somtehing else..
You could do:
$('li[class^="link"] a').click(...
However this would only work if the li have only one class or if the link-X class is the first in the list.
Inside the handler you can use $(this) to refer to the a element:
alert($(this).text());
Much better would be to give the li elements a common class:
<li class="link">One</li>
<li class="link">Two</li>
<li class="link">Three</li>
$('.link a').click(... will be much more reliable.
Give each element the same class. Then in your javascript reference this within your function. Check out the link below to see a working example
http://jsfiddle.net/kprgr/2/
<li class="link">One</li>
<li class="link">Two</li>
<li class="link">Three</li>
$(".link").click(function() {
alert($(this).find("a").html());
});
Try..
$(".link-??? a").click(function() {
alert(this.innerHTML);
})
Inside the click event, this should refer to the element that was clicked.
You could also do..
alert($(this).html());
..but the first way is simpler, and faster.

Categories

Resources