javascripthtmljquerycheckboxbootstrap-5

How to make the entire checkbox module clickable in Bootstrap 5


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/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/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 (goes well by using the keyboard, it'the click that needs to be managed).

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 the checkbox triggers the event change.

How to make it work perfectly without changing the HTML code?


Solution

  • 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.