I’m trying from a long time to make the whole module clickable, not only the checkbox or the label.
If you search on stackoverflow about this you can find the question
How to Make Entire Custom Checkbox/Div Clickable — Not Just the Label + Input
but it’s not my case.
It’s a custom checkbox and I want to use a normal one.
So at the end watch at my try with this code in the snippet (some JavaScript & JQuery)
var checkboxes = []; //There are multiple checkboxes so an array it's needed to simplify [pretend nothing happened 😅]
checkboxes[0] = document.body.querySelector('#HEYY');
checkboxes[0].addEventListener('change', (e) => {
console.log('CLICKED@'+Date.now());
});
$(document).ready(function() {
$('.ma_checkbox_module').on('click', function(e) {
//e.preventDefault();
//e.stopPropagation();
if (e.target.tagName == "DIV") {
let checkbox = $(this).find('input');
if (checkbox.prop('checked') == true) {
checkbox.prop('checked', false);
} else {
checkbox.prop('checked', true);
}
}
});
});
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<center><!-- center tag it's deprecated, but who cares -->
<div class="user-select-none" style="background-color: #983229;">
<div class="form-check ma_checkbox_module d-inline-block" style="background-color: #111111;">
<input class="form-check-input" type="checkbox" value="" id="HEYY">
<label class="form-check-label ms-3" for="HEYY" style="color: white;">HEYY</label>
<!-- class .ms-3 is added specifically to create more space to simplify understanding of the example, but it's the same also if you remove it -->
</div>
</div>
</center>
As you can see it works good, but the event it’s not triggered in some cases.
If you click on a specific point between the label and the checkbox, the checkbox changes state but the change
event it’s not triggered. Instead, clicking on the label or checkbox triggers the change
.
How to make it work perfectly without changing the HTML code?
2
Answers
As @Anoop LL suggests, the issue arises because clicking the surrounding
div
element manually toggles the checkbox state via JavaScript but doesn’t trigger thechange
event that would normally occur when the checkbox itself is clicked. To resolve this, explicitly trigger thechange
event programmatically after toggling the checkbox.The updated JavaScript code using JQuery could be:
Indeed:
click()
ensures thechange
event is fired programmatically after manually toggling thechecked
property of the checkbox.checkbox.prop('checked', !checkbox.prop('checked'))
cleanly switches the checkbox’s state without needing additional conditionals.When you toggle the checkbox manually, you’re responsible for also firing any associated events.
Now, clicking anywhere in the clickable module, including the gap between the label and the checkbox, will properly toggle the checkbox and trigger the
change
event.There is a super simple way to do this: The
stretched-link
Bootstrap class. Refer to this section in the documentation. Skip until you read:As you can see, the example provided there check or unchecks the checkbox by clicking anywhere in the container list item, not just on the label or the checkbox.
How stretched-link Works
This works by inserting
::after
and styling it like this:I’m not going to give an entire lesson on this technique, just know this: This creates a transparent on-top layer that covers the most immediate parent that has
absolute
orrelative
positioning.If you need help understanding, read about the topic @ MDN.