Find first parent element with specific first-level descendant - javascript

I am trying get first parent (Only) of selected element which have Input type Checkbox as first-level descendant.
HTML
$('input[type="checkbox"]').change(function(e) {
$(this)
.parent()
.parents("li:has(input[type='checkbox'])")
.find(">span")
.css("background-color", "yellow");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<ul class="UL1">
<li class="LI1">
<input class="checkbox1" type="checkbox" />
<span>LI1</span>
<ul class="UL2">
<li class="LI3">
<input class="checkbox2" type="checkbox" />
<span>LI3</span>
</li>
<li class="LI4">
<input class="checkbox3" type="checkbox" />
<span>LI4</span>
<ul class="UL3">
<li class="LI5">
<span>LI5</span>
</li>
<li class="LI6">
<span>LI6</span>
<ul class="UL4">
<li class="LI7">
<span>LI7</span>
</li>
<li class="LI8">
<input class="checkbox4" type="checkbox" />
<span>LI8</span>
</li>
<li class="LI9">
<span>LI9</span>
</li>
</ul>
</li>
<li class="LI10">
<span>LI10</span>
</li>
</ul>
</li>
<li class="LI11">
<span>LI11</span>
</li>
</ul>
</li>
<li class="LI12">
<input class="checkbox5" type="checkbox" />
<span>LI12</span>
</li>
</ul>
</div>
NOTE: In this code I am highlighting span only as an example, but my actual purpose of having parent with checkbox is different.
Here when selecting "LI8" checkbox, I need its parent that has Checkbox. according to this I should receive "LI4" but when I am using ".parents(). it is giving me all parents including "LI" not having Checkbox.
Does anybody know how can I get only first parent that has checkbox as first-level descendant? In my scenario on selection of "LI8", only "LI4" should return and "LI6" and "LI1" must ignore. Thank you.

li:has(input[type='checkbox']) will select all lis that contain an input at any level.
Use the direct descendant selector (>) here: .parents("li:has(>input[type='checkbox'])") to select those lis that have a child input.
You can then limit the selection to a single item using .first().
$('input[type="checkbox"]').change(function(e) {
$(this)
.parent()
.parents("li:has(>input[type='checkbox'])")
.first()
.find(">span")
.css("background-color", "yellow");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<ul class="UL1">
<li class="LI1">
<input class="checkbox1" type="checkbox" />
<span>LI1</span>
<ul class="UL2">
<li class="LI3">
<input class="checkbox2" type="checkbox" />
<span>LI3</span>
</li>
<li class="LI4">
<input class="checkbox3" type="checkbox" />
<span>LI4</span>
<ul class="UL3">
<li class="LI5">
<span>LI5</span>
</li>
<li class="LI6">
<span>LI6</span>
<ul class="UL4">
<li class="LI7">
<span>LI7</span>
</li>
<li class="LI8">
<input class="checkbox4" type="checkbox" />
<span>LI8</span>
</li>
<li class="LI9">
<span>LI9</span>
</li>
</ul>
</li>
<li class="LI10">
<span>LI10</span>
</li>
</ul>
</li>
<li class="LI11">
<span>LI11</span>
</li>
</ul>
</li>
<li class="LI12">
<input class="checkbox5" type="checkbox" />
<span>LI12</span>
</li>
</ul>
</div>

Related

jQuery switching lists with same class

I created a bit complex list and I wish after clicking on element with class ".recipes", display it inside paragraph but after clicking on button prev or next, I wish to switch to previous or next element with same class name. I know already how to switch the list if they are next to each other but after putting them inside different parents it seems more complicated:
<div>
<button class="prev">prev</button>
<button class="next">next</button>
<p class="showRecipies"></p>
<ul class="listOfRecipies">
<li>
<ul class="particularRecipie">
<li class="timeOfPreparation">3:20</li>
<li class="recipies">Drinks</li>
</ul>
</li>
<li>
<ul class="particularRecipie">
<li class="timeOfPreparation">3:20</li>
<li class="recipies">Vegetables</li>
</ul>
</li>
<li>
<ul class="particularRecipie">
<li class="timeOfPreparation">3:20</li>
<li class="recipies">Meat</li>
</ul>
</li>
<li>
<ul class="particularRecipie">
<li class="timeOfPreparation">3:20</li>
<li class="recipies">Fruits</li>
</ul>
</li>
<li>
<ul class="particularRecipie">
<li class="timeOfPreparation">3:20</li>
<li class="recipies">Others</li>
</ul>
</li>
</ul>
</div>
To show clicked element:
$(".recipies").on("click", function() {
$(".recipies.active").add($(this)).toggleClass("active");
var recipieValue = $(this).text();
var showRecipies = document.querySelector(".showRecipies");
showRecipies.innerHTML = recipieValue;
});
and to show previous element with class "recipes" I got from another person on this forum is here however because classes have different parents now, it doesn't work, I thought that i can add more parents() and because of that find previous or next ".recipes" but it didn't work out:
$(".prev").click(function() {
var isFirst = $(".recipies.active").is(":first-child");
if(isFirst){
$(this).parent().find(".recipies:last").trigger("click");
} else {
$(".recipies.active").prev().trigger("click");
}
});
Check this out:
$(".recipies").on("click", function() {
$(".recipies.active").add($(this)).toggleClass("active");
var recipieValue = $(this).text();
var showRecipies = document.querySelector(".showRecipies");
showRecipies.innerHTML = recipieValue;
});
$(".prev").click(function() {
var isFirst = $(".recipies.active").text() == $($(".recipies").get(0)).text();
if (isFirst) {
$(this).parent().find(".recipies:last").trigger("click");
} else {
$(".recipies.active").parent().parent().prev().find(".recipies").trigger("click");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>
<button class="prev">prev</button>
<button class="next">next</button>
<p class="showRecipies"></p>
<ul class="listOfRecipies">
<li>
<ul class="particularRecipie">
<li class="timeOfPreparation">3:20</li>
<li class="recipies">Drinks</li>
</ul>
</li>
<li>
<ul class="particularRecipie">
<li class="timeOfPreparation">3:20</li>
<li class="recipies">Vegetables</li>
</ul>
</li>
<li>
<ul class="particularRecipie">
<li class="timeOfPreparation">3:20</li>
<li class="recipies">Meat</li>
</ul>
</li>
<li>
<ul class="particularRecipie">
<li class="timeOfPreparation">3:20</li>
<li class="recipies">Fruits</li>
</ul>
</li>
<li>
<ul class="particularRecipie">
<li class="timeOfPreparation">3:20</li>
<li class="recipies">Others</li>
</ul>
</li>
</ul>
</div>

Get parent child label/value upon checkbox selection of child li elements

I'm trying to get the value of the lvl1 and lvl2 li labels upon selection of the checkbox of their respective child li.
<ul class="list" >
<li class="lvl1">
<a><h4>Level-1</h4></a>
<ul>
<li class="lvl2">
<a><label>Level-2</label></a>
<ul>
<li class="lvl3">
<input type="checkbox" class="childbox" value="Level-3 Value1"/>
</li>
</ul>
</li>
</ul>
<ul>
<li class="lvl2">
<a><label>Level-2</label></a>
<ul>
<li class="lvl3">
<input type="checkbox" class="childbox" value="Level-3 Value2"/>
</li>
</ul>
</li>
</ul>
</li>
</ul>
I want to get the value upon checkbox for their respective parents-child relationship
Click first checkbox to get this value.
Level-1 > Level-2 > Level-3 Value 1
Click 2nd checkbox to get the below value.
Level-1 > Level-2 > Level-3 Value 2
you can add on change event and get all li parents of changed input to get the info about the li 'level' I added this as data attribute:
$(document).ready(function(){
$('.childbox').change(function(){
var parents="";
var current_value=$(this).val();
$(this).parents('li').each(function( index ) {
parents= $(this).data('level-name')+" > "+parents;
});
console.log(parents+" : "+current_value);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<ul class="list" >
<li class="lvl1" data-level-name='Level 1'>
<a><h4>Level-1</h4></a>
<ul>
<li class="lvl2" data-level-name='Level 2'>
<a><label>Level-2</label></a>
<ul>
<li class="lvl3" data-level-name='Level 3'>
<input type="checkbox" class="childbox" value="Level-3 Value1"/>
</li>
</ul>
</li>
</ul>
<ul>
<li class="lvl2" data-level-name='Level 2'>
<a><label>Level-2</label></a>
<ul>
<li class="lvl3" data-level-name='Level 3'>
<input type="checkbox" class="childbox" value="Level-3 Value2"/>
</li>
</ul>
</li>
</ul>
</li>
</ul>
I wrote up some example code as to how to do it. I would use relative selectors to accomplish this.
$("input[type=checkbox]").change(function () {
console.log($(this).closest(".lvl2").find("label").html())
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="list" >
<li class="lvl1">
<a><h4>Level-1</h4></a>
<ul>
<li class="lvl2">
<a><label>Level-2</label></a>
<ul>
<li class="lvl3">
<input type="checkbox" class="childbox" value="Level-3 Value1"/>
</li>
</ul>
</li>
</ul>
<ul>
<li class="lvl2">
<a><label>Level-3</label></a>
<ul>
<li class="lvl3">
<input type="checkbox" class="childbox" value="Level-3 Value2"/>
</li>
</ul>
</li>
</ul>
</li>
</ul>
Try this .i was added code for 'leve1,level2' and label,input value.you could select as your wish
$('input:checkbox').click(function(){
console.log($(this).closest('.lvl1').text())
console.log($(this).closest('.lvl2').find('label').text())
console.log($(this).val())
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="list">
<li class="lvl1">
<a>
<h4>Level-1</h4>
</a>
<ul>
<li class="lvl2">
<a><label>Level-2</label></a>
<ul>
<li class="lvl3">
<input type="checkbox" class="childbox" value="Level-3 Value1" />
</li>
</ul>
</li>
</ul>
<ul>
<li class="lvl2">
<a><label>Level-2</label></a>
<ul>
<li class="lvl3">
<input type="checkbox" class="childbox" value="Level-3 Value2" />
</li>
</ul>
</li>
</ul>
</li>
</ul>

Unexpected behavior of $parent.$index in AngularJS

I have a code like this :
<script type="text/ng-template" id="something.html">
<div>
Hey!
</div>
</script>
<div ng-repeat="colum in columns">
<ul>
<li ng-repeat="list in column" id="{{$parent.$index}}" ng-include="something.html">
</li>
</ul>
</div>
The ids are assigned as 1, 2, 3, 4 on the li elements. I am expecting that if columns has 4 elements then the ids for li inside a ul element should be 0,0,0,0.
Rendered DOM is something like :
<div>
<ul>
<li id="0">
</li>
<li id="1">
</li>
</ul>
</div>
<div>
<ul>
<li id="0">
</li>
<li id="1">
</li>
</ul>
</div>
My expected DOM :
<div>
<ul>
<li id="0">
</li>
<li id="0">
</li>
</ul>
</div>
<div>
<ul>
<li id="1">
</li>
<li id="1">
</li>
</ul>
</div>
Apologies if I missed something obvious.

jQuery - find all first siblings of each node

HTML:
<ul class="treeview">
<li>
<a data-toggle="collapse" href=".options1"> <!-- this one -->
Item 1
</a>
<ul class="collapse options1">
<li>
<a data-toggle="collapse" href=".sublevel1"></a> <!-- this one -->
<input type="checkbox" value="option1" />
<a data-toggle="collapse" href=".sublevel1">Item 1-1</a> <!-- not this one -->
<ul class="collapse sublevel1">
<li>
Item 1-1-1
<ul>
<li><input type="checkbox" value="option1" />
Item 1-1-1-1
</li>
<li><a data-toggle="collapse" href=".collapse1-1-1-1-1"></a> <!-- this one -->
<input type="checkbox" value="option1" />
<a data-toggle="collapse" href=".collapse1-1-1-1-1">Item 1-1-1-2</a> <!-- not this one -->
<ul class="collapse collapse1-1-1-1-1">
<li>Item 1-1-1-2-1
<ul>
<li><input type="checkbox" value="option1" />Item 1-1-1-2-1-1</li>
<li><a data-toggle="collapse" href=".collapse1-1-1-1-1-1-1"></a><input type="checkbox" value="option1" />
<a data-toggle="collapse" href=".collapse1-1-1-1-1-1-1">Item 1-1-1-2-1-2</a>
<ul class="collapse collapse1-1-1-1-1-1-1">
<li>Item 1-1-1-2-1-2-1
<ul>
<li><input type="checkbox" value="option1" />Item 1-1-1-2-1-2-1-1</li>
<li><input type="checkbox" value="option1" />Item 1-1-1-2-1-2-1-2</li>
<li><input type="checkbox" value="option1" />Item 1-1-1-2-1-2-1-3</li>
<li><input type="checkbox" value="option1" />Item 1-1-1-2-1-2-1-4</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><input type="checkbox" value="option1" />Item 1-2</li>
<li><input type="checkbox" value="option1" />Item 1-3</li>
<li><input type="checkbox" value="option1" />Item 1-4</li>
</ul>
</li>
</ul>
jQuery:
$('.treeview ul').not('ul:not([class])').siblings('a')
.prepend("<span>XYZ</span>");
As you can see, I'm already looking for all <ul>'s which don't have ANY classname, and then looking for <a> siblings, but I only need the first sibling (before the input checkbox).
Here's a jsFiddle to help you out: https://jsfiddle.net/st2yehgr/1/ (tip: all the item that have double 'XYZ', I only want the first one)
Can anyone help me here?? Cheers! :)
You can try this
$('.treeview li>a:first-child')
.prepend("<span>XYZ</span>");
Check this fiddle
Answered by :#mplungjan
$('.treeview ul').not('ul:not([class])').each(function() {
$(this).find("a").first().prepend("<span>XYZ</span>");
});
His fiddle: https://jsfiddle.net/qtrhu249/1/ (which I then updated the html to also cover the first level [wrapped everything in a div]).
$('.collapse li').find( "input[type='checkbox']" ).prev().prepend("<span>XYZ</span>")
Try this

how to check all the children check

Hi I have the following structure:
<ul class="main">
<li class="toggle">
<input type="checkbox"> information
</li>
<ul>
<li class="modulo">
<input type="checkbox"> General
</li>
<ul>
<li class="example1">
<input type="checkbox">
</li>
<li class="example2">
<input type="checkbox">
</li>
</ul>
</ul>
</ul>
I now need to know how to set all the children checkboxes to "checked" when the main parent checkbox is checked by the user
Im using jQuery, thanks
Your can change markup like following:
<ul class="main">
<li class="toggle">
<input type="checkbox"> information
<ul>
<li class="example1">
<input type="checkbox">
</li>
<li class="example2">
<input type="checkbox">
</li>
</ul>
</li>
<li class="modulo">
<input type="checkbox"> General
<ul>
<li class="example1">
<input type="checkbox">
</li>
<li class="example2">
<input type="checkbox">
</li>
</ul>
</li>
</ul>
jQuery
$('ul.main > li > :checkbox').change(function() {
$(this).next('ul').find(':checkbox').prop('checked', this.checked);
});
If you correct your markup:
<ul class="main">
<li class="toggle">
<input type="checkbox"> information
<ul>
<li class="modulo">
<input type="checkbox"> General
<ul>
<li class="example1">
<input type="checkbox">
</li>
<li class="example2">
<input type="checkbox">
</li>
</ul>
</li>
</ul>
</li>
</ul>
...this should do it:
$(".main input[type='checkbox']").click(function() {
$(this).parent().find("input[type='checkbox']").prop("checked", this.checked);
});
Live example | source
Then you'll want to handle the converse case (unchecking the parent if you uncheck an ancestor so all ancestors are no longer checked), but I leave that as an exercise for you.
This toggles the checks: http://jsfiddle.net/
I'd suggest you indent your code for more easy reading too.

Categories

Resources