skip to Main Content

I’m using Bootstrap group radio button on which I would like to write event delegation.

<div class="btn-group" role="group" aria-label="Basic radio toggle button group">
  <input type="radio" class="btn-check" name="btnradio" id="btnradio1" autocomplete="off" checked>
  <label class="btn btn-outline-primary" for="btnradio1">Radio 1</label>

  <input type="radio" class="btn-check" name="btnradio" id="btnradio2" autocomplete="off">
  <label class="btn btn-outline-primary" for="btnradio2">Radio 2</label>

  <input type="radio" class="btn-check" name="btnradio" id="btnradio3" autocomplete="off">
  <label class="btn btn-outline-primary" for="btnradio3">Radio 3</label>
</div>

Since the labels are not nested in the button, the following is not returning the inputs.

event.target.closest('.btn-check');

Is there a proper way to write event delegation on this type of non-nested elements?

2

Answers


  1. Here is how. Clicking the radio OR the label will show the ID. No need for closest here

    In Bootstrap it still works

    document.querySelector('.btn-group').addEventListener('click', (e) => {
      const tgt = e.target;
      if (tgt.matches('.btn-check')) console.log(tgt.id)
    });
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
    
    <div class="btn-group" role="group" aria-label="Basic radio toggle button group">
      <input type="radio" class="btn-check" name="btnradio" id="btnradio1" autocomplete="off" checked>
      <label class="btn btn-outline-primary" for="btnradio1">Radio 1</label>
    
      <input type="radio" class="btn-check" name="btnradio" id="btnradio2" autocomplete="off">
      <label class="btn btn-outline-primary" for="btnradio2">Radio 2</label>
    
      <input type="radio" class="btn-check" name="btnradio" id="btnradio3" autocomplete="off">
      <label class="btn btn-outline-primary" for="btnradio3">Radio 3</label>
    </div>

    If you have buttons with child elements, you DO need closest

    Clicking the button text OR the icon will show the ID

    document.querySelector('.btn-group').addEventListener('click', (e) => {
      const tgt = e.target.closest('.btn'); // would not work on the icon without closest
      if (tgt) console.log(tgt.id)
    });
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
    
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
    
    <div class="btn-group" role="group" aria-label="Basic button group">
      <button type="button" class="btn btn-outline-primary"  id="btn1">Text</button>
      <button type="button" class="btn btn-outline-primary"  id="btn2" ><i class="fa fa-exclamation-circle" aria-hidden="true"></i></button>
    </div>
    Login or Signup to reply.
  2. In this code, i use the event delegation technique to listen for click events on the parent container with the class btn-group.
    When a click event occurs, we check if the clicked element is an <input> element with the type "radio", and if so, we log its ID to the console

      document.querySelector('.btn-group').addEventListener('click', (event) => {
        if (event.target.tagName === 'INPUT' && event.target.type === 'radio') {
          console.log(event.target.id);
        }
      });
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
    
    <div class="btn-group" role="group" aria-label="Basic radio toggle button group">
      <input type="radio" class="btn-check" name="btnradio" id="btnradio1" autocomplete="off" checked>
      <label class="btn btn-outline-primary" for="btnradio1">Radio 1</label>
    
      <input type="radio" class="btn-check" name="btnradio" id="btnradio2" autocomplete="off">
      <label class="btn btn-outline-primary" for="btnradio2">Radio 2</label>
    
      <input type="radio" class="btn-check" name="btnradio" id="btnradio3" autocomplete="off">
      <label class="btn btn-outline-primary" for="btnradio3">Radio 3</label>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search