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.
Related
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>
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>
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
I managed to do on checking Parent Checkbox to check all Child Checkboxes but i dont know how to do on checking any child checkbox to check the parent checkbox and if all the child checkboxes are unchecked then the Parent checkbox needs to be unchecked.
1. I did on checking Parent Checkbox to check all Child Checkboxes (completed)
2. on checking any child checkbox also checks parent checkbox (not complete)
3. if all the child checkboxes are unchecked then the Parent checkbox unchecks(not complete).
This is how far i got:
$(function () {
$("input[type='checkbox']").change(function () {
$(this).siblings('ul')
.find("input[type='checkbox']")
.prop('checked', this.checked);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<li style="display: block;"><input type="checkbox">Lead1 <br>
<ul>
<li style="display: block;"><input type="checkbox"> All Leads <br></li>
<li style="display: block;"><input type="checkbox"> Recent Leads <br></li>
<li style="display: block;"><input type="checkbox"> My Leads <br></li>
</ul>
</li>
<li style="display: block;"><input type="checkbox">Lead2 <br>
<ul>
<li style="display: block;"><input type="checkbox"> first <br></li>
<li style="display: block;"><input type="checkbox"> second <br></li>
<li style="display: block;"><input type="checkbox"> third <br></li>
</ul>
</li>
Please Help me to solve this as i am new to jquery and js.
You can have another handler which will check whether any checkbox in the same level is checked if so check the parent checkbox
$(function() {
$("li:has(li) > input[type='checkbox']").change(function() {
$(this).siblings('ul').find("input[type='checkbox']").prop('checked', this.checked);
});
$("input[type='checkbox'] ~ ul input[type='checkbox']").change(function() {
$(this).closest("li:has(li)").children("input[type='checkbox']").prop('checked', $(this).closest('ul').find("input[type='checkbox']").is(':checked'));
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<ul>
<li style="display: block;">
<input type="checkbox">Lead1
<br>
<ul>
<li style="display: block;">
<input type="checkbox">All Leads
<br>
</li>
<li style="display: block;">
<input type="checkbox">Recent Leads
<br>
</li>
<li style="display: block;">
<input type="checkbox">My Leads
<br>
</li>
</ul>
</li>
<li style="display: block;">
<input type="checkbox">Lead2
<br>
<ul>
<li style="display: block;">
<input type="checkbox">first
<br>
</li>
<li style="display: block;">
<input type="checkbox">second
<br>
</li>
<li style="display: block;">
<input type="checkbox">third
<br>
</li>
</ul>
</li>
</ul>
Add a class parent to the parent li and then do it like following.
$("input[type='checkbox']").change(function () {
var ul = $(this).closest('ul');
var checked = ul.find('input[type="checkbox"]:checked').length > 0;
$(this).closest('.parent').find('input[type="checkbox"]').first().prop('checked', checked);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li class="parent" style="display: block;">
<input type="checkbox">Lead1 <br>
<ul>
<li style="display: block;"><input type="checkbox"> All Leads <br></li>
<li style="display: block;"><input type="checkbox"> Recent Leads <br></li>
<li style="display: block;"><input type="checkbox"> My Leads <br></li>
</ul>
</li>
<li class="parent" style="display: block;">
<input type="checkbox">Lead2 <br>
<ul>
<li style="display: block;"><input type="checkbox"> first <br></li>
<li style="display: block;"><input type="checkbox"> second <br></li>
<li style="display: block;"><input type="checkbox"> third <br></li>
</ul>
</li>
So I'm creating a progress bar, but I'm running into a little problem.
The rule I'm trying to implement:
for each li.page check if li.question = li.question.done, if true .addClass .done to this
So in the HTML below, #p1 should have class done, #p2 and #p3 shouldn't.
The current JS results in adding class .done to all .page li's in the page if one .page has all questions done.
Hope someone can help me get this to work, all help is appreciated!
This is the html:
<ul class="pages">
<li id="p1" class="page">
<ul class="questions">
<li id="q2" class="question done">1</li>
<li id="q3" class="question done">2</li>
<li id="q4" class="question done">3</li>
</ul>
</li>
<li id="p2" class="page">
<ul class="questions">
<li id="q5" class="question current">4</li>
</ul>
</li>
<li id="p3" class="page">
<ul class="questions">
<li id="q6" class="question done">5</li>
<li id="q7" class="question">6</li>
</ul>
</li>
</ul>
And this JS:
var doneCheck = function(){
$(".page").each(function () {
questionsInPage = $(this).closest(".questions").find("li").length;
questionsDone = $(this).closest(".questions").find("li.done").length;
var done = questionsDone == questionsInPage;
$(".page").each(function() {
if (done) {
$(this).parent().addClass('done');
};
});
});
}
For each page I would check the number of li against the number of elements with class question and done. If they match set page to done.
var doneCheck = function() {
$(".page").each(function() {
if($('.question.done', this).length==$('ul li',this).length)
$(this).addClass('done');
});
}
doneCheck();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="pages">
<li id="p1" class="page">
<ul class="questions">
<li id="q2" class="question done">1</li>
<li id="q3" class="question done">2</li>
<li id="q4" class="question done">3</li>
</ul>
</li>
<li id="p2" class="page">
<ul class="questions">
<li id="q5" class="question current">4</li>
</ul>
</li>
<li id="p3" class="page">
<ul class="questions">
<li id="q6" class="question done">5</li>
<li id="q7" class="question">6</li>
</ul>
</li>
</ul>
Instead of finding all the done questions, count the number of not done questions. If it's zero, all the questions are done. Use this to set the done property of the page.
function doneCheck() {
$(".page").each(function() {
var allDone = $(this).find(".questions li.question:not(.done)").length == 0;
$(this).toggleClass("done", allDone);
});
}
$("#check").click(doneCheck);
.page.done {
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="pages">
<li id="p1" class="page">
<ul class="questions">
<li id="q2" class="question done">1</li>
<li id="q3" class="question done">2</li>
<li id="q4" class="question done">3</li>
</ul>
</li>
<li id="p2" class="page">
<ul class="questions">
<li id="q5" class="question current">4</li>
</ul>
</li>
<li id="p3" class="page">
<ul class="questions">
<li id="q6" class="question done">5</li>
<li id="q7" class="question">6</li>
</ul>
</li>
</ul>
<button id="check">Check</button>
FYI, you can't use == to compare the results of two selectors. If you want to test whether they're equivalent, use .is:
if (questionsDone.is(questionsInPage)
But your second loop is wrong, because it sets the class on all .page elements based on the done status of the current page of the loop.