skip to Main Content

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


  1. As @Anoop LL suggests, the issue arises because clicking the surrounding div element manually toggles the checkbox state via JavaScript but doesn’t trigger the change event that would normally occur when the checkbox itself is clicked. To resolve this, explicitly trigger the change event programmatically after toggling the checkbox.

    The updated JavaScript code using JQuery could be:

    $(document).ready(function () {
        $('.ma_checkbox_module').on('click', function (e) {
            if (e.target.tagName === "DIV") {
                let checkbox = $(this).find('input');
                checkbox.prop('checked', !checkbox.prop('checked')).click();
            }
        });
    });
    

    Indeed:

    1. click() ensures the change event is fired programmatically after manually toggling the checked property of the checkbox.
    2. Toggle logic: 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.

    Login or Signup to reply.
  2. 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:

    You can use .stretched-link on <label>s to make the whole list group item clickable.

    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:

    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    z-index: 1;
    content: "";
    

    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 or relative positioning.

    If you need help understanding, read about the topic @ MDN.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search