Reputation: 664
I have a HTML form where I want to check all children after clicking on parent. The parent should be link. So far I managed to do this but the parent contain also checkbox. Here is my code:
<input type="checkbox" name="rights[]" value="1" class='selectAll' data-checkbox-name='c1' /><strong>Parent 1</strong>
<input type="checkbox" name="rights[]" value="2" class='c1' />Child 1.1
<input type="checkbox" name="rights[]" value="2" class='c1' />Child 1.2
<input type="checkbox" name="rights[]" value="1" class='selectAll' data-checkbox-name='c2' /><strong>Parent 2</strong>
<input type="checkbox" name="rights[]" value="2" class='c2' />Child 2.1
<input type="checkbox" name="rights[]" value="2" class='c2' />Child 2.2
<script>
$(':checkbox.selectAll').on('click', function(){
$(':checkbox[class='+ $(this).data('checkbox-name') + ']').prop("checked", $(this).prop("checked")).trigger("change");
});
</script>
So I want to end with parent in anchor. Can someone help me ? Thanks.
Upvotes: 2
Views: 2087
Reputation: 146191
You may try this too (nextUntil('a.selectAll')
will select all checkboxs before a.selectAll
)
$('.selectAll').on('click', function(e){
e.preventDefault();
$(this).nextUntil('a.selectAll').prop('checked', function(){
return !this.checked;
});
});
You may try this alternative, notice data-checkbox-name='c1'
in the a
tag
HTML :
<a href="#" class='selectAll' data-checkbox-name='c1'>Parent</a>
<input type="checkbox" name="rights[]" value="2" class='c1' />Child 1.1
<input type="checkbox" name="rights[]" value="2" class='c1' />Child 1.2
JS :
$('.selectAll').on('click', function(e){
e.preventDefault();
var t = $(this), cls = t.attr('data-checkbox-name');
$(':checkbox.'+cls).prop('checked', function(){
return !this.checked;
});
});
Upvotes: 1
Reputation: 11371
Change the parent to an <a/>
tag. Simple. I took the liberty of making your HTML semantic, like adding labels for the text next to checkbox, etc. So now I have a structure like this :
<div class="set">
<a href="#" class="parent">Parent1</a>
<div>
<input type="checkbox" name="rights[]" value="2" class='c1' id="c1-1" />
<label for="c1-1">Child 1.1</label>
<br/>
<input type="checkbox" name="rights[]" value="2" class='c1' id="c1-2" />
<label for="c1-2">Child 1.2</label>
</div>
</div>
You'd repeat this for as many times as possible. Note the for
attributes in the label. Thats also important because when you click on a label, it'll automatically check/uncheck the checkbox corresponding to it. Your click event is below :
$('.set').on('click', ".parent", function () {
//get the checkboxes from the neighboring <div>
var $checkboxes = $(this).next().children("[type=checkbox]");
//check the state of the checkbox (this will give out only the first checkbox, but thats ok for our cause)
var isChecked = $checkboxes.prop("checked");
//invert the checked property based on isChecked variable.
$checkboxes.prop("checked", !isChecked);
});
The reason I've bound it to .set
is because something called event delegation. Its not important in this question but that makes the code cleaner (in my opinion). The click could also look like this :
$(".parent").click(function() { ..
Demo : http://jsfiddle.net/hungerpain/b6AQr/1/
Upvotes: 1
Reputation: 470
You can use replaceWith
function
$(':checkbox.selectAll').on('click', function(){
$(':checkbox[class='+ $(this).data('checkbox-name') + ']').prop("checked", $(this).prop("checked")).trigger("change");
$(this).replaceWith("<a class='selectAll'>"+$(this).text()+"</a>");
});
Upvotes: 0