admin管理员组文章数量:1302267
I am new to JS and I have a page with 2 filters, I am stuck and I am trying to:
check automatically the (All) checkbox if every other checkbox of the filter are checked.
when a user unchecked a checkbox, automatically uncheck the (All) checkbox.
I am trying the following code but it is not really working...
HTML:
<div id="filter1">
<form action='#'>
<input type="checkbox" value="all" class="select-all" checked>(All)
<br>
<input type="checkbox" value="v1" class="checkboxlistitem" checked>F1: Value1
<br>
<input type="checkbox" value="v2" class="checkboxlistitem" checked>F1: Value2
<br>
<input type="checkbox" value="v3" class="checkboxlistitem" checked>F1: Value3
<br>
<input type="checkbox" value="v4" class="checkboxlistitem" checked>F1: Value4
<br>
<input type="submit" value="Apply">
</form>
</div>
<div id="filter2">
<form action='#'>
<input type="checkbox" value="all" class="select-all" checked>(All)
<br>
<input type="checkbox" value="v1" class="checkboxlistitem" checked>F2: Value1
<br>
<input type="checkbox" value="v2" class="checkboxlistitem" checked>F2: Value2
<br>
<input type="checkbox" value="v3" class="checkboxlistitem" checked>F2: Value3
<br>
<input type="checkbox" value="v4" class="checkboxlistitem" checked>F2: Value4
<br>
<input type="submit" value="Apply">
</form>
</div>
JS:
$(".checkboxlistitem").change(function() {
$(".select-all").prop("checked", $(".checkboxlistitem:checked").length == $(".checkboxlistitem").length);});
JSFIDDLE:
/
Let me know if you need clarifications, Thanks in advance, Max
I am new to JS and I have a page with 2 filters, I am stuck and I am trying to:
check automatically the (All) checkbox if every other checkbox of the filter are checked.
when a user unchecked a checkbox, automatically uncheck the (All) checkbox.
I am trying the following code but it is not really working...
HTML:
<div id="filter1">
<form action='#'>
<input type="checkbox" value="all" class="select-all" checked>(All)
<br>
<input type="checkbox" value="v1" class="checkboxlistitem" checked>F1: Value1
<br>
<input type="checkbox" value="v2" class="checkboxlistitem" checked>F1: Value2
<br>
<input type="checkbox" value="v3" class="checkboxlistitem" checked>F1: Value3
<br>
<input type="checkbox" value="v4" class="checkboxlistitem" checked>F1: Value4
<br>
<input type="submit" value="Apply">
</form>
</div>
<div id="filter2">
<form action='#'>
<input type="checkbox" value="all" class="select-all" checked>(All)
<br>
<input type="checkbox" value="v1" class="checkboxlistitem" checked>F2: Value1
<br>
<input type="checkbox" value="v2" class="checkboxlistitem" checked>F2: Value2
<br>
<input type="checkbox" value="v3" class="checkboxlistitem" checked>F2: Value3
<br>
<input type="checkbox" value="v4" class="checkboxlistitem" checked>F2: Value4
<br>
<input type="submit" value="Apply">
</form>
</div>
JS:
$(".checkboxlistitem").change(function() {
$(".select-all").prop("checked", $(".checkboxlistitem:checked").length == $(".checkboxlistitem").length);});
JSFIDDLE:
https://jsfiddle/Max06270/5scgbnww/
Let me know if you need clarifications, Thanks in advance, Max
Share Improve this question edited Aug 18, 2016 at 22:33 Max06270 asked Aug 18, 2016 at 22:27 Max06270Max06270 671 silver badge9 bronze badges 4- What about it isn't working? When I run your Fiddle, the only thing I see happening that I wouldn't want to happen is that both "All" checkboxes get unchecked. – Cole Twitchell Commented Aug 18, 2016 at 22:31
- Yes that is the first thing. Also if you unselect everything and you select chexboxes one by one exept the (All), (All) checkbox is not getting checked by iteself. – Max06270 Commented Aug 18, 2016 at 22:35
-
Both problems are happening because your filters use the same classes for their elements. Splitting them up to use separate classes will fix this, for example:
class="select-all-1"
andclass="select-all-2"
. You'll also have to modify thecheckboxlistitem
classes and repeat that JS function for your other filter and its classes. – Cole Twitchell Commented Aug 18, 2016 at 22:40 - Hum... my app has actually 15 filters, I was expecting to find a global solution. Thanks for your help – Max06270 Commented Aug 18, 2016 at 22:42
3 Answers
Reset to default 5You're jquery selectors were too generic, so they were affecting both forms. Below should be a working example of what you want:
$(".select-all").change(function () {
$(this).siblings().prop('checked', $(this).prop("checked"));
});
$(".checkboxlistitem").change(function() {
var checkboxes = $(this).parent().find('.checkboxlistitem');
var checkedboxes = checkboxes.filter(':checked');
if(checkboxes.length === checkedboxes.length) {
$(this).parent().find('.select-all').prop('checked', true);
} else {
$(this).parent().find('.select-all').prop('checked', false);
}
});
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="filter1">
<form action='#'>
<input type="checkbox" value="all" class="select-all" checked>(All)<br>
<input type="checkbox" value="v1" class="checkboxlistitem" checked>F1: Value1<br>
<input type="checkbox" value="v2" class="checkboxlistitem" checked>F1: Value2<br>
<input type="checkbox" value="v3" class="checkboxlistitem" checked>F1: Value3<br>
<input type="checkbox" value="v4" class="checkboxlistitem" checked>F1: Value4<br>
<input type="submit" value="Apply">
</form>
</div>
<br>
<div id="filter2">
<form action='#'>
<input type="checkbox" value="all" class="select-all" checked>(All)<br>
<input type="checkbox" value="v1" class="checkboxlistitem" checked>F2: Value1<br>
<input type="checkbox" value="v2" class="checkboxlistitem" checked>F2: Value2<br>
<input type="checkbox" value="v3" class="checkboxlistitem" checked>F2: Value3<br>
<input type="checkbox" value="v4" class="checkboxlistitem" checked>F2: Value4<br>
<input type="submit" value="Apply">
</form>
</div>
https://jsfiddle/0epu6Lnn/
Fixing the form you have:
Your selectors of $('.checkboxlistitem')
and $('.checkboxlistitem:checked')
select all elements with those classes, and are therefor selecting the checkboxes in both forms. To fix this they need context.
Within jQuery's event callbacks, this
refers to the element that the event is fired on. That means that we can use relative selectors to find the appropriate elements:
// find the nearest ancestor that's a form
$form = $(this).closest('form');
// find all the `.checkboxlistitem` elements within the form
$checkboxes = $form.find('.checkboxlistitem');
// find the all checkbox within the form
$all = $form.find('.select-all');
// if there are any unchecked checkboxes the all option should be unchecked
$all.prop('checked', !$checkboxes.not(':checked').length);
// leaving this as it was in the jsfiddle
// Select/Unselect all chexboxes of the form
$(".select-all").change(function () {
$(this).siblings().prop('checked', $(this).prop("checked"));
});
$('.checkboxlistitem').change(function () {
var $form,
$checkboxes,
$all;
// find the nearest ancestor that's a form
$form = $(this).closest('form');
// find all the `.checkboxlistitem` elements within the form
$checkboxes = $form.find('.checkboxlistitem');
// find the all checkbox within the form
$all = $form.find('.select-all');
// if there are any unchecked checkboxes the all option should be unchecked
$all.prop('checked', !$checkboxes.not(':checked').length);
});
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="filter1">
<form action='#'>
<input type="checkbox" value="all" class="select-all" checked>(All)
<br>
<input type="checkbox" value="v1" class="checkboxlistitem" checked>F1: Value1
<br>
<input type="checkbox" value="v2" class="checkboxlistitem" checked>F1: Value2
<br>
<input type="checkbox" value="v3" class="checkboxlistitem" checked>F1: Value3
<br>
<input type="checkbox" value="v4" class="checkboxlistitem" checked>F1: Value4
<br>
<input type="submit" value="Apply">
</form>
</div>
<div id="filter2">
<form action='#'>
<input type="checkbox" value="all" class="select-all" checked>(All)
<br>
<input type="checkbox" value="v1" class="checkboxlistitem" checked>F2: Value1
<br>
<input type="checkbox" value="v2" class="checkboxlistitem" checked>F2: Value2
<br>
<input type="checkbox" value="v3" class="checkboxlistitem" checked>F2: Value3
<br>
<input type="checkbox" value="v4" class="checkboxlistitem" checked>F2: Value4
<br>
<input type="submit" value="Apply">
</form>
</div>
This is great and all, but lets take it up a notch by improving the accessibility of your form and the behavior of partially plete checkbox lists.
Form accessibility
Labels
As-is your checkboxes have no labels.
You added text after them, certainly, but a screen reader has no way of knowing what each checkbox represents.
To fix this, use <label>
elements.
<form action="#">
<label>
<input type="checkbox" value="all" class="select-all" checked>
(All)
</label>
<br>
<label>
<input type="checkbox" value="v1" class="checkboxlistitem" checked>
F1: Value1
</label>
<br>
...
</form>
They can either have the checkbox nested or have their [for]
attributes point to the [id]
attributes of the <input>
elements, or both.
<form action="#">
<input type="checkbox" id="f1-all" value="all" class="select-all" checked> <label for="f1-all">(All)</label>
<br>
<input type="checkbox" id="f1-v1" value="v1" class="checkboxlistitem" checked> <label for="f1-v1">F1: Value1</label>
<br>
...
</form>
Hierarchy
There's a different hierarchical relationship between the "all" checkbox and the individual F#: Value#
checkboxes.
To fix this, use <fieldset>
and <legend>
elements.
<form action="#">
<fieldset>
<legend>
<label>
<input type="checkbox" value="all" checked>
<span>Select All in Filter 1</span>
</label>
</legend>
<label>
<input type="checkbox" value="v1" checked>
<span>F1: Value1</span>
</label>
<br>
...
</fieldset>
</form>
Line separation
You're currently using <br>
elements to separate the fields onto different lines.
<p>
elements are often used.
<form action="#">
<fieldset>
<legend>...</legend>
<p>
<label>
<input type="checkbox" value="v1" checked>
<span>F1: Value1</span>
</label>
</p>
...
</fieldset>
</form>
Names
You're using the [value]
attributes, which is good, but none of the <input>
elements have [name]
attributes, which means that the data won't be sent to the server, and calling jQuery's .serialize()
on the forms won't get you the appropriate data.
Set the [name]
on the checkboxes that have important values (the "all" checkbox won't be necessary):
<form action="#">
<fieldset>
<legend>...</legend>
<p>
<label>
<input type="checkbox" name="v1" value="1" checked>
<span>F1: Value1</span>
</label>
</p>
...
</fieldset>
</form>
Alternatively, you can set all the [name]
attributes to filter
and rely on the various values to produce query strings such as filter=v1&filter=v2
, but this is an advanced technique that's likely going to run into bugs with querystring parsing, so proceed with caution.
Partially Complete Checkbox Lists
While it's nice to be able to automatically uncheck the "all" checkbox, when some checkboxes are checked and other checkboxes are unchecked the unchecked state doesn't exactly make sense for the "all" checkbox. It's not at "none" and it's not at "all".
Enter the indeterminate state.
Checkboxes have a third state that's only accessible from JavaScript that was designed for exactly this situation.
You can set a given checkbox to the indeterminate state by toggling its indeterminate
property:
document.querySelector('input[type="checkbox"]').indeterminate = true;
or with jQuery:
$('input[type="checkbox"]').first().prop('indeterminate', true);
Checking whether the list is in an indeterminate state can be done by differentiating between:
- No checkboxes checked
- All checkboxes checked
- Some checkboxes checked and unchecked
In practice this might look something like:
checkedCount = $checkboxes.filter(':checked').length;
if (!checkedCount) {
// no checkboxes checked
$all.prop({
checked: false,
indeterminate: false
});
} else if (checkedCount === $checkboxes.length) {
// all checkboxes checked
$all.prop({
checked: true,
indeterminate: false
});
} else {
// some checkboxes checked and unchecked
$all.prop({
indeterminate: true
});
}
All Together Now
A fully fleshed out implementation of all of the above looks like:
$('.filter').on('change', '[value="all"]', function () {
var $form,
$checkboxes,
$all;
$form = $(this).closest('form');
$checkboxes = $form.find('[name="filter"]');
$all = $form.find('[value="all"]');
$checkboxes.prop('checked', $all.prop('checked'));
}).on('change', '[name="filter"]', function () {
var $form,
$checkboxes,
$all,
checkedCount;
$form = $(this).closest('form');
$checkboxes = $form.find('[name="filter"]');
$all = $form.find('[value="all"]');
checkedCount = $checkboxes.filter(':checked').length;
if (!checkedCount) {
// no checkboxes checked
$all.prop({
checked: false,
indeterminate: false
});
} else if (checkedCount === $checkboxes.length) {
// all checkboxes checked
$all.prop({
checked: true,
indeterminate: false
});
} else {
// some checkboxes checked and unchecked
$all.prop({
indeterminate: true
});
}
});
<script src="https://ajax.googleapis./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="filter1" class="filter">
<form action='#'>
<fieldset>
<legend>
<label>
<input type="checkbox" value="all" checked>
<span>Select All in Filter 1</span>
</label>
</legend>
<p>
<label>
<input type="checkbox" name="filter" value="v1" checked>
<span>F1: Value1</span>
</label>
</p>
<p>
<label>
<input type="checkbox" name="filter" value="v2" checked>
<span>F1: Value2</span>
</label>
</p>
<p>
<label>
<input type="checkbox" name="filter" value="v3" checked>
<span>F1: Value3</span>
</label>
</p>
<p>
<label>
<input type="checkbox" name="filter" value="v4" checked>
<span>F1: Value4</span>
</label>
</p>
</fieldset>
<input type="submit" value="Apply">
</form>
</div>
<div id="filter2" class="filter">
<form action='#'>
<fieldset>
<legend>
<label>
<input type="checkbox" value="all" checked>
<span>Select All in Filter 2</span>
</label>
</legend>
<p>
<label>
<input type="checkbox" name="filter" value="v1" checked>
<span>F2: Value1</span>
</label>
</p>
<p>
<label>
<input type="checkbox" name="filter" value="v2" checked>
<span>F2: Value2</span>
</label>
</p>
<p>
<label>
<input type="checkbox" name="filter" value="v3" checked>
<span>F2: Value3</span>
</label>
</p>
<p>
<label>
<input type="checkbox" name="filter" value="v4" checked>
<span>F2: Value4</span>
</label>
</p>
</fieldset>
<input type="submit" value="Apply">
</form>
</div>
for those that want to use vanilla js:
const checkboxes = document.getElementsByClassName("checkboxlistitem");
const selectAllBtn = document.getElementById("select-all");
for (let i = 0; i < checkboxes.length; i++) {
checkboxes[i].addEventListener("change", () => {
for (let i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked === false) {
selectAllBtn.checked = false;
break;
} else {
selectAllBtn.checked = true;
}
}
});
}
// select all button
selectAllBtn.addEventListener("change", (event) => {
for (let i = 0, n = checkboxes.length; i < n; i++) {
checkboxes[i].checked = event.target.checked;
}
});
<div id="filter1">
<form action='#'>
<input type="checkbox" value="all" id="select-all" checked>(All)<br>
<input type="checkbox" value="v1" class="checkboxlistitem" checked>F1: Value1<br>
<input type="checkbox" value="v2" class="checkboxlistitem" checked>F1: Value2<br>
<input type="checkbox" value="v3" class="checkboxlistitem" checked>F1: Value3<br>
<input type="checkbox" value="v4" class="checkboxlistitem" checked>F1: Value4<br>
<input type="submit" value="Apply">
</form>
</div>
本文标签: javascriptAuto checkuncheck the quotAllquot checkboxStack Overflow
版权声明:本文标题:javascript - Auto checkuncheck the "All" checkbox - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741710828a2393830.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论