Selecting Parent Checkboxes - javascript

I have a page that has a tree structure that has no limit to the number of levels it has. Each level has a tick box I need to be able to allow users to tick which levels they are interested in. If a user clicks on a level then all of the parent levels for that child need to be selected. Also if the parent check box is unticked then all child levels should be unticked.
I tried writing the code below which kind of works however if I click the child it will tick the parent and grandparent but leave the child unselected. I am also unable to unselect items as every-time I select a box it always selects it again.
I keep trying to make changes to the code and have ideas but I think I am going down the wrong direction and wanted to know if there are better solutions available for what I am trying to achieve. Here is the code:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Check Box</title>
<script type="text/javascript" src="js/jquery.js"></script>
<script language="javascript">
$(document).ready(function () {
$(".test").click(function (event) {
event.preventDefault();
});
});
function set_checked(id, checked) {
$("#ID_" + id).attr("checked", checked)
alert(id);
}
function CheckMe(id) {
var IDS = id.replace("ID_", "");
var IDS = IDS.split('_');
for (i = 0; i < IDS.length; i++) {
set_checked(IDS[i], true);
}
}
</script>
</head>
<body>
<div>
<form>
<p>
<input name="ID" type="checkbox" id="ID_123" value="123" onClick="CheckMe('ID_123')" class="test">Grandparent
<br>
<input name="ID" type="checkbox" id="ID_124" value="124" onClick="CheckMe('ID_123_124')"class="test">Parent
<br>
<input name="ID" type="checkbox" id="ID_125" value="125" onClick="CheckMe('ID_123_124_125')"class="test">Child
</p>
<p>
<input type="submit" name="button" id="button" value="Submit">
</p>
</form>
</div>
</body>
</html>
I used jQuery PreventDefault to stop the default actions of the checkbox. I would be most grateful for any direction with this.
Edit:
Here are the options within an unordered list. My example above was misleading as it only had three options as I was trying to test clicking the bottom option and having the parent options clicked without considering that there would be multiple trees.
<form action="" method="get" id="test">
<ul>
<li>
<input type="checkbox" name="ID" value="1">
<label>Level 1</label>
<ul>
<li><input type="checkbox" name="ID" value="2"><label>Level 1.1</label>
<ul>
<li><input type="checkbox" name="ID" value="3"><label>Level 1.1.1</label>
</ul>
</ul>
<ul>
<li><input type="checkbox" name="ID" value="4"><label>Level 1.2</label>
<ul>
<li><input type="checkbox" name="ID" value="5"><label>Level 1.2.1</label>
<li><input type="checkbox" name="ID" value="6"><label>Level 1.2.2</label>
<li><input type="checkbox" name="ID" value="7"><label>Level 1.2.3</label>
<ul>
<li><input type="checkbox" name="ID" value="8"><label>Level 1.2.3.1</label>
<li><input type="checkbox" name="ID" value="9"><label>Level 1.2.3.2</label>
</ul>
<li><input type="checkbox" name="ID" value="10"><label>Level 1.2.4</label>
<li><input type="checkbox" name="ID" value="11"><label>Level 1.2.5</label>
<li><input type="checkbox" name="ID" value="12"><label>Level 1.2.6</label>
</ul>
</ul>
<li><input type="checkbox" name="ID" value="13"><label>Level 2</label>
<ul>
<li><input type="checkbox" name="ID" value="14"><label>Level 2.1</label>
<ul>
<li><input type="checkbox" name="ID" value="15"><label>Level 2.1.1</label>
</ul>
<li><input type="checkbox" name="ID" value="16"><label>Level 2.2</label>
<ul>
<li><input type="checkbox" name="ID" value="16"><label>Level 2.2.1</label>
<li><input type="checkbox" name="ID" value="17"><label>Level 2.2.2</label>
<li><input type="checkbox" name="ID" value="18"><label>Level 2.2.3</label>
<ul>
<li><input type="checkbox" name="ID" value="19"><label>Level 2.2.3.1</label>
<li><input type="checkbox" name="ID" value="20"><label>Level 2.2.3.2</label>
</ul>
<li><input type="checkbox" name="ID" value="21"><label>Level 2.2.4</label>
<li><input type="checkbox" name="ID" value="22"><label>Level 2.2.5</label>
<li><input type="checkbox" name="ID" value="23"><label>Level 2.2.6</label>
</ul>
</ul>
</ul>
<input name="Submit" type="submit" id="Button" value="Submit">
</form>

There are plugins that already provide this functionality.
Try this, as it does exactly what you are looking for.
http://code.google.com/p/checkboxtree/
demo:
http://checkboxtree.googlecode.com/svn/tags/checkboxtree-0.5.2/index.html

Try this code:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Check Box</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"> </script>
<script language="javascript">
$(document).ready(function () {
$(".test").on('click',function () {
var clicked = $(this);
var hermanos = clicked.siblings(".test");
if(clicked.attr("checked")=="checked")
$.each(hermanos, function(index,object){
if($(object).val() < clicked.val())
$(object).attr("checked", "checked");
});
else
$.each(hermanos, function(index,object){
if($(object).val() > clicked.val())
$(object).removeAttr("checked");
});
});
});
</script>
</head>
<body>
<div>
<form>
<p>
<input name="ID" type="checkbox" value="123" class="test">Grandparent
<br>
<input name="ID" type="checkbox" value="124" class="test">Parent
<br>
<input name="ID" type="checkbox" value="125" class="test">Child
</p>
<p>
<input type="submit" name="button" id="button" value="Submit">
</p>
</form>
</div>
</body>

Not sure what you mean with "levels", are the checkboxes nested inside other elements, or are they as in your example, just siblings ?
If the example HTML is correct, remove all your inline JS, and just do this :
$(".test").on('change', function() {
var i = $(this).index(),
c = $(this).is(':checked');
$(".test").filter(function() { return $(this).index() < i; }).prop('checked', c);
});
FIDDLE

Related

How to add ID and label tag to checkbox with jQuery

I have the following HTML code (that I can't access/amend) for one of my many checkboxes:
<input type="checkbox" class="cat_input" name="subcategory1a" value="1">
I want to turn the checkbox into a toggle, for which I understand I need a <label> tag associated with the 'ID' of the checkbox. Unfortunately, the HTML code as per above has only the input tag without ID and no <label> tag.
To create a checkbox toggle I understand I would need a unique ID and associated <label> tag for each checkbox such as for example:
<input type="checkbox" class="cat_input" name="subcategory1a" value="1" ID="checkbox1"> <label for="checkbox1"></label>
I have two questions:
How can I add the ID and <label> tag with jQuery to my existing <input> tag to create a code as per the example?
Given that I have c. 40-50 checkboxes of which each needs its own ID and label tag, is there a way to make the jQuery code compact as opposed to copy paste the code 40-50x?
I would much appreciate your help. Thank you very much in advance!
EDIT
<script>
$('input[type="checkbox"]').each(function(i, v) {
var checkbox = $(this);
checkbox.attr("id", ("checkbox_" + (i + 1)))
checkbox.after($("<label>").attr("for", checkbox.attr("id")));
});
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="geodir-filter-cat gd-type-single gd-field-fieldset"><span>Header</span>
<ul>
<li><input type="checkbox" class="cat_input" name="subcategory1a" value="1" /> </li>
<li><input type="checkbox" class="cat_input" name="subcategory1b" value="1" /> </li>
</l>
</div>
You can iterate over each checkbox and add the label after it.
Example:
$('input[type="checkbox"]').each(function() {
var checkbox = $(this);
checkbox.after($("<label>").attr("for", checkbox.attr("id")));
});
In case your initial input doesn't have an id attribute set, then set it manually first:
$('input[type="checkbox"]').each(function(i, v) {
$(this).attr("id", ("checkbox_" + i))
$(this).after($("<label>").attr("for", $(this).attr("id")));
});
EDIT 1:
Putting this code into <head> is not going to work, as the content that this code addressing is not yet loaded at that time. Either put this code before closing </body> tag or use ready function.
$(function() {
// code above is here
});
According your given markup please see below:
$('.cat_input').each(function() {
var checkbox = $(this);
checkbox.attr('id', 'checkbox'+checkbox.index()); // Adding ID attribute
checkbox.after($("<label for='checkbox"+ checkbox.index() +"'>").text(checkbox.val())); // Adding label with for attribute
});
And HTML I assumed like following:
<input type="checkbox" class="cat_input" name="subcategory1a" value="1">
<input type="checkbox" class="cat_input" name="subcategory1a" value="2">
<input type="checkbox" class="cat_input" name="subcategory1a" value="3">
<input type="checkbox" class="cat_input" name="subcategory1a" value="4">
<input type="checkbox" class="cat_input" name="subcategory1a" value="5">
I always prefer to do it like <label><input /><span></span></label> for me I think its simple to use and to style/css it
$(document).ready(function(){
$('.cat_input').each(function(i){ // index start from 0
i = i + 1;
$(this).val(i).attr('id' , 'checkbox' + i).wrap('<label></label>').closest('label').append('<span>'+i+'</span>');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" class="cat_input" name="subcategory1a" />
<input type="checkbox" class="cat_input" name="subcategory1a" />
<input type="checkbox" class="cat_input" name="subcategory1a" />
<input type="checkbox" class="cat_input" name="subcategory1a" />
<input type="checkbox" class="cat_input" name="subcategory1a" />
<input type="checkbox" class="cat_input" name="subcategory1a" />
<input type="checkbox" class="cat_input" name="subcategory1a" />
<input type="checkbox" class="cat_input" name="subcategory1a" />
the code for first input will be
<label>
<input type="checkbox" class="cat_input" name="subcategory1a" value="1" id="checkbox1"/>
<span>1</span>
</label>

How to get value of dynamically generated checkboxes if the checkbox is true in Angularjs

Hi I am developing angularjs application. I have generated checkboxes dynamically using ng-repeat. My design is as below.
<ul>
<li ng-repeat="screen in screenMap">
<input type="text" ng-model="screen.scrn_name" />
<input type="hidden" value="{{screen.scrn_id}}" />
<input type="checkbox" name="vehicle" value="Read">
<input type="checkbox" name="vehicle" value="Write">
<br>
</li>
</ul>
<input type="button" value="APPLY" ng-click="apply()" />
Below is my js code.
$scope.apply = function () {
}
I want to get array like scrn_name,true,false format. If the checkbox is checked then true else false.
May i know how can i get this? Any help would be appreciated. Thank you.
go through angular checkbox
use ng-true-value and ng-true-value
<ul>
<li ng-repeat="screen in screenMap">
<input type="text" ng-model="screen.scrn_name" />
<input type="hidden" value="{{screen.scrn_id}}"/>
<input type="checkbox" name="vehicle" ng-model="screen.write" ng-true-value="true" ng-false-value="false">
<input type="checkbox" name="vehicle" ng-model="screen.read" ng-true-value="true" ng-false-value="false"><br>
</li>
</ul>
<input type="button" value="APPLY" ng-click="apply()"/>
$scope.apply = function () {
console.log($scope.screenMap);//[{..,read:true,write:false},...]
}

Exclude disabled checkboxes when using Select All

I have checkboxes with labels in table. I have added one checkbox outside the table "Select All" with id "chkbox". Now the below code is working fine. It is
Selecting and Deselecting all the checkboxes in the table. Now there are some pages where some checkboxes are disabled due to business logic. I want these checkboxes should not be affected.
<script type="text/javascript">
var s = jQuery.noConflict();
s(document).ready(function() {
s('#chkbox').change(function() {
var all = s('table').find('input[type="checkbox"]');
if (this.checked) {
all.prop('checked', true);
} else {
all.prop('checked', false);
}
});
});
</script>
Use :not() with :disabled selector.
var all = $('table').find('input[type="checkbox"]:not(:disabled)');
^^^^^^^^^^^^^^^^
This will not select the disabled checkboxes
$('#selectAll').change(function() {
$(':checkbox:not(:disabled)').prop('checked', this.checked);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<input type="checkbox" id="selectAll" />Select All
<ul>
<li>
<input type="checkbox" disabled />
</li>
<li>
<input type="checkbox" />Not disabled</li>
<li>
<input type="checkbox" />Not disabled</li>
<li>
<input type="checkbox" disabled />
</li>
<li>
<input type="checkbox" />Not disabled</li>
</ul>
You can also use :enabled selector.
$('table').find('input[type="checkbox"]:enabled')
$('#selectAll').change(function() {
$(':checkbox:enabled').prop('checked', this.checked);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<input type="checkbox" id="selectAll" /> Select All
<ul>
<li>
<input type="checkbox" disabled />
</li>
<li>
<input type="checkbox" />Not disabled</li>
<li>
<input type="checkbox" />Not disabled</li>
<li>
<input type="checkbox" disabled />
</li>
<li>
<input type="checkbox" />Not disabled</li>
</ul>
Note that: :enabled == :not(:disabled)

Checkbox select using querySelectorAll is not working

I have the following code, mostly from How can I select all checkboxes from a form using pure JavaScript and it's just not working.
Test.html
<html>
<head>
<script>
function select(){
var inputs = document.querySelectorAll("input[type='checkbox']");
for(var i = 0; i < inputs.length; i++) {
inputs[i].checked = true;
}
}
</script>
</head>
<body>
<form id="myId" name="myForm">
<input type="checkbox" value="1"/> 1
<input type="checkbox" value="2"/> 2
<input type="checkbox" value="3"/> 3
<input type="button" onclick="select()" value="Select all"/>
</form>
</body>
</html>
Clicking the button does nothing.
I must be doing something really wrong here but I just can't pick it out.
Try this...
<html>
<head>
<script>
function test(){
var inputs = document.querySelectorAll("input[type='checkbox']");
for(var i = 0; i < inputs.length; i++) {
inputs[i].checked = true;
}
}
</script>
</head>
<body>
<form id="myId" name="myForm">
<input type="checkbox" value="1"/> 1
<input type="checkbox" value="2"/> 2
<input type="checkbox" value="3"/> 3
<input type="button" onclick="test()" value="Select all"/>
</form>
</body>
</html>
Try any other name for function select, rest your code is fine.
select is a native method defined on HTMLInputElement to focus selected input element.
select
Solution1: Change the name of your function.
Solution2: Try onclick="window.select()" insted of onclick="select()"
i suggest you To use Jquery and do like so :
Live Demo
HTML
<ul class="chk-container">
<li><button id="selecctall">select all</button>
<li><input class="checkbox1" type="checkbox" name="check[]" value="item1"> This is Item 1</li>
<li><input class="checkbox1" type="checkbox" name="check[]" value="item2"> This is Item 2</li>
<li><input class="checkbox1" type="checkbox" name="check[]" value="item3"> This is Item 3</li>
<li><input class="checkbox1" type="checkbox" name="check[]" value="item4"> This is Item 4</li>
<li><input class="checkbox1" type="checkbox" name="check[]" value="item5"> This is Item 5</li>
<li><input class="checkbox1" type="checkbox" name="check[]" value="item6"> This is Item 6</li>
<li><input class="checkbox2" type="checkbox" name="check[]" value="item6"> Do not select this</li>
</ul>
Jquery
$(document).ready(function() {
$('#selecctall').mouseup(function(event) { //on click
if(document.activeElement.tagName ==='BUTTON') { // check select status
$('.checkbox1').each(function() { //loop through each checkbox
this.checked = true; //select all checkboxes with class "checkbox1"
});
}else{
$('.checkbox1').each(function() { //loop through each checkbox
this.checked = false; //deselect all checkboxes with class "checkbox1"
});
}
});
});
Simpler and more efficient way

jquery check and uncheck all with action

I have more checkbox input that call function "boxclick" when the user click on this:
<input id="1box" type="checkbox" name="selected[]" onclick="boxclick(this,'1')">
<input id="2box" type="checkbox" name="selected[]" onclick="boxclick(this,'2')">
<input id="3box" type="checkbox" name="selected[]" onclick="boxclick(this,'3')">
<input id="4box" type="checkbox" name="selected[]" onclick="boxclick(this,'4')">
For check/uncheck all i use simple jquery script:
<input type="checkbox" onclick="$('input[name*=\'selected\']').attr('checked', this.checked);" checked="checked">
My problem is when i check/uncheck all the function "boxclick" not run.
// == a checkbox has been clicked ==
function boxclick(box,category) {
if (box.checked) {
show(category);
} else {
hide(category);
}
}
I think you can do:
HTML
<input id="1box" type="checkbox" name="selected[]">
<input id="2box" type="checkbox" name="selected[]">
<input id="3box" type="checkbox" name="selected[]">
<input id="4box" type="checkbox" name="selected[]">
jQuery
If you want to check/uncheck all checkbox:
var checkboxes = $('input[type=checkbox][name^=selected]');
checkboxes.on('click', function() {
checkboxes.prop('checked', this.checked);
});
If you want to make select any one at a time:
var checkboxes = $('input[type=checkbox][name^=selected]');
checkboxes.on('click', function() {
checkboxes.prop('checked', false);
this.checked = !this.checked;
});​
DEMO
Setting attribute of checkboxes to checked does not automatically fake a click event for you! Because you put those boxclick function calls within some "onclick" handlers, you must trigger a fake click event in order for your javascript to think that it clicked all the boxes. To trigger fake click event use $('#whatever').trigger('click'), for instance:
$('input[name*=\'selected\']').trigger('click');
If you want check/uncheck all functionality, you must say "ok, master checkbox, please listen for whenever I am checked or unchecked. When that happens, please set checked attribute of my slave boxes (your other boxes on the page) to match the master's current checked attribute." Like this:
function checkAllorUncheckAll(event){
var chiefCheckbx = event.currentTarget;
var myBoxes = $('input[name*=\'selected\']');
myBoxes.prop( "checked", $(chiefCheckbx).prop("checked") ).trigger('click');
}
$('#masterCheckBox').on('change',checkAllorUncheckAll);
I guess
$('input[name*=\'selected\']').attr('checked',
this.checked).trigger('click');
should do the trick here
Demo
http://jsfiddle.net/H37cb/
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js" /></script>
<script type="text/javascript">
$(document).ready(function(){
$('input[name="all"],input[name="title"]').bind('click', function(){
var status = $(this).is(':checked');
$('input[type="checkbox"]', $(this).parent('li')).attr('checked', status);
});
});
</script>
<div id="wrapper">
<li style="margin-top: 20px">
<input type="checkbox" name="all" id="all" /> <label for='all'>All</label>
<ul>
<li><input type="checkbox" name="title" id="title_1" /> <label for="title_1"><strong>Title 01</strong></label>
<ul>
<li><input type="checkbox" name="selected[]" id="box_1" value="1" /> <label for="box_1">Sub Title 01</label></li>
<li><input type="checkbox" name="selected[]" id="box_2" value="2" /> <label for="box_2">Sub Title 02</label></li>
<li><input type="checkbox" name="selected[]" id="box_3" value="3" /> <label for="box_3">Sub Title 03</label></li>
<li><input type="checkbox" name="selected[]" id="box_4" value="4" /> <label for="box_4">Sub Title 04</label></li>
</ul>
</li>
</ul>
<ul>
<li><input type="checkbox" name="title" id="title_2" /> <label for="title_2"><strong>Title 02</strong></label>
<ul>
<li><input type="checkbox" name="selected[]" id="box_5" value="5" /> <label for="box_5">Sub Title 05</label></li>
<li><input type="checkbox" name="selected[]" id="box_6" value="6" /> <label for="box_6">Sub Title 06</label></li>
<li><input type="checkbox" name="selected[]" id="box_7" value="7" /> <label for="box_7">Sub Title 07</label></li>
</ul>
</li>
</ul>
</li>
</div>

Categories

Resources