skip to Main Content

I use Bootstrap to design my forms. There is a checkbox and an associated label. My goal is to change the value of the checkbox by clicking on the checkbox and to be able to edit the text of the label by clicking on the label.
My problem now is that no matter which element I click on, whether label or checkbox, the same event is always called. However, I would like to separate these events.

I have tried it with different event handlers and I have also removed the for attribute.
I assume that the classes "custom-control-input" and "custom-control-label" are hindering me. But I want to keep the styling.

Can anyone tell me what else I can try? I would hate to write new styles and maintain them just because of this one use case.

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/js/bootstrap.bundle.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/css/bootstrap-reboot.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/css/bootstrap-grid.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/js/bootstrap.min.js"></script>


<script>
  $(function() {
    $('.examples label').on('click', function(e) {
      debugger;
      console.log('Listener: Label Clicked');
    });
    $('.examples input').on('click', function(e) {
      console.log('Listener: CheckBox Clicked');
    });
  });

  function onClickLabel(e, label) {
    console.log('Label Clicked')
  }

  function onClickCheckBox(e, cb) {
    console.log('CheckBox Clicked')
  }
</script>

<div class="examples">


  <div class="mb-3">
    <h3>Does work, but ugly</h3>
    <div>
      <input type="checkbox" class="" onClick="onClickCheckBox(event, this)">
      <label class="" onClick="onClickLabel(event, this)">Check this custom checkbox</label>
    </div>
  </div>  

  <div class="mb-3">
    <h3>Always triggers the checkbox</h3>
    <div>
      <input id="cb1" type="checkbox" class="" onClick="onClickCheckBox(event, this)">
      <label for="cb1" class="" onClick="onClickLabel(event, this)">Check this custom checkbox</label>
    </div>
  </div>

  <div class="mb-3">
    <h3>Triggers everything</h3>
    <div class="custom-control custom-checkbox">
      <input id="cb0" type="checkbox" class="custom-control-input" onClick="onClickCheckBox(event, this)">
      <label for="cb0" class="custom-control-label" onClick="onClickLabel(event, this)">Check this custom checkbox</label>
    </div>
  </div>

  <div class="mb-3">
    <h3>Always triggers the label</h3>
    <div class="custom-control custom-checkbox">
      <input type="checkbox" class="custom-control-input" onClick="onClickCheckBox(event, this)">
      <label class="custom-control-label" onClick="onClickLabel(event, this)">Check this custom checkbox</label>
    </div>
  </div>
</div>

2

Answers


  1. You can prevent the label default and propagation then trigger the click using either the "for" attribute or a custom data attribute with a selector. Examples:

    $(function() {
      $('.examples .editable-label').on('click', handleLabelClick);
      $('.examples .input[type="checkbox"].custom-control-input').on('click', handleCheckboxClick);
    });
    
    function handleLabelClick(event) {
      event.stopPropagation();
      event.stopImmediatePropagation();
      event.preventDefault();
      this.focus();
      const forMe = '#' + $(this).attr("for");
      const target = $(this).data("target") && $(this).data("target").length ? $(this).data("target") : forMe;
      $(target).trigger('click');
    }
    
    function handleCheckboxClick(event) {
      console.log('CheckBox Clicked');
    }
    .editable-label {
      border: solid 1px #00FF00;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/js/bootstrap.bundle.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/css/bootstrap-reboot.min.css" rel="stylesheet" />
    <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/css/bootstrap.min.css" rel="stylesheet" />
    <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/css/bootstrap-grid.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/js/bootstrap.min.js"></script>
    
    <div class="examples">
      <div class="mb-3 custom-control custom-checkbox">
        <h3>Does work, but ugly</h3>
        <div>
          <input type="checkbox" class="custom-control-input" name="ugly" id="ugly" />
          <label class="editable-label custom-control-label" for="ugly" contenteditable="true">Check this custom checkbox</label>
        </div>
      </div>
    
      <div class="mb-3">
        <h3>Always triggers the checkbox</h3>
        <div class="custom-control custom-checkbox">
          <input id="cb1" type="checkbox" class="custom-control-input" />
          <label for="cb1" class="editable-label custom-control-label" contenteditable="true">Check this custom checkbox</label>
        </div>
      </div>
    
      <div class="mb-3">
        <h3>Triggers everything</h3>
        <div class="custom-control custom-checkbox">
          <input id="cb0" type="checkbox" class="custom-control-input" />
          <label for="cb0" class="custom-control-label editable-label" contenteditable="true" data-target="#cb0">Check this custom checkbox</label>
        </div>
      </div>
    
      <div class="mb-3">
        <h3>Always triggers the label</h3>
        <div class="custom-control custom-checkbox">
          <input id="checkbox-3" type="checkbox" class="custom-control-input" />
          <label class="custom-control-label editable-label" contenteditable="true" data-target="#checkbox-3">Check this custom checkbox</label>
        </div>
      </div>
    </div>
    Login or Signup to reply.
  2. By defining ‘onClick="onClickLabel(event, this)"’ you are creating an event, and at the same time you are creating the event in the html. Try removing onClick

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/js/bootstrap.bundle.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/css/bootstrap-reboot.min.css" rel="stylesheet" />
    <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/css/bootstrap.min.css" rel="stylesheet" />
    <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/css/bootstrap-grid.min.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/4.6.2/js/bootstrap.min.js"></script>
    
    
    <script>
      $(function() {
        $('.examples label').on('click', function(e) {
          debugger;
          console.log('Listener: Label Clicked');
        });
        $('.examples input').on('click', function(e) {
          console.log('Listener: CheckBox Clicked');
        });
      });
    
      function onClickLabel(e, label) {
        console.log('Label Clicked')
      }
    
      function onClickCheckBox(e, cb) {
        console.log('CheckBox Clicked')
      }
    </script>
    
    <div class="examples">
    
    
      <div class="mb-3">
        <h3>Does work, but ugly</h3>
        <div>
          <input type="checkbox" class="" onClick="onClickCheckBox(event, this)">
          <label class="">Check this custom checkbox</label>
        </div>
      </div>  
    
      <div class="mb-3">
        <h3>Always triggers the checkbox</h3>
        <div>
          <input id="cb1" type="checkbox" class="" onClick="onClickCheckBox(event, this)">
          <label for="cb1" class="">Check this custom checkbox</label>
        </div>
      </div>
    
      <div class="mb-3">
        <h3>Triggers everything</h3>
        <div class="custom-control custom-checkbox">
          <input id="cb0" type="checkbox" class="custom-control-input">
          <label for="cb0" class="custom-control-label">Check this custom checkbox</label>
        </div>
      </div>
    
      <div class="mb-3">
        <h3>Always triggers the label</h3>
        <div class="custom-control custom-checkbox">
          <input type="checkbox" class="custom-control-input" onClick="onClickCheckBox(event, this)">
          <label class="custom-control-label">Check this custom checkbox</label>
        </div>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search