I tried to implement a simple website which have 5 checkboxes.
If user clicks "All" checkbox then all the other checkbox will be checked or unchecked depends on the value of the "All" checkbox.
$(document).ready(function() {
$("#all").click(function(event) {
console.log("all");
$("input[name=vehicle]").each(function() {
$(this).click();
});
});
});
function checkVehicle(event, id) {
// console.log(event);
console.log(id);
}
<script src="https://code.jquery.com/jquery-3.7.1.min.js"
integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
<input type="checkbox" id="all" name="all" />
<label for="all">All</label>
<input type="checkbox" id="car" name="vehicle" onclick="checkVehicle(event, 1)" />
<label>Car</label>
<input type="checkbox" id="bike" name="vehicle" onclick="checkVehicle(event, 2)" />
<label>Bike</label>
<input type="checkbox" id="truck" name="vehicle" onclick="checkVehicle(event, 3)" />
<label>Truck</label>
<input type="checkbox" id="tank" name="vehicle" onclick="checkVehicle(event,4)" />
<label>Tank</label>
The problem is when I click "All" checkbox the checkVehicle for each other checkbox is called 3 times.
I am interested in knowing the reason behind this behaviour rather than how to fix it.
I could solve the problem by using one of the below methods.
First one is instead of triggering click event on jQuery element I could trigger it on DOM element.
$(document).ready(function() {
$("#all").click(function(event) {
console.log("all");
$("input[name=vehicle]").each(function() {
$(this)[0].click();
});
});
});
function checkVehicle(event, id) {
console.log(event);
console.log(id);
}
Second one is instead of registering event inline I could register it programmatically.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://code.jquery.com/jquery-3.7.1.min.js"
integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
<title>Document</title>
</head>
<body>
<script src="index.js"></script>
<input type="checkbox" id="all" name="all" />
<label for="all">All</label>
<input type="checkbox" id="car" name="vehicle" />
<label>Car</label>
<input type="checkbox" id="bike" name="vehicle" />
<label>Bike</label>
<input type="checkbox" id="truck" name="vehicle" />
<label>Truck</label>
<input type="checkbox" id="tank" name="vehicle" />
<label>Tank</label>
</html>
And here is my index.js
$(document).ready(function() {
$("#all").click(function(event) {
console.log("all");
$("input[name=vehicle]").each(function() {
$(this).click();
});
});
$("input[name=vehicle]").click(function() {
console.log("personal");
});
});
2
Answers
As the comments clarified, if you only want the properties to be checked, then you should be able to do
$("input[name=vehicle]").prop("checked", $(this).prop("checked"))
without the loop, jQuery will handle that for you:But, if you only wonder what happens under the hood, then take a look at this snippet:
You will notice that without the jQuery object of
$(this)
, the simple.click()
ofthis
will do what you want. So it’s clearly related what "this" means inside your.each()
callback. Note that this second script will negate your checkboxes, so if you manually checked a checkbox first and then click on all to check all, then the one you checked will be unchecked, which is unlikely to be your intention. You can enhance it like this:When you call $(this).trigger(‘click’); inside the $("#all").click(function(event) { … }); handler, it simulates a click event on each checkbox.
You could try by set
prop
value checked and then fire the function checkVehicle’