Dealing with event delegation on elements that are not nested

Working with Bootstrap group radio buttons where I need to implement 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="btnradito3">Radio 3</label>
</div>

Encountering an issue as the labels are not directly nested within the input element.

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

Any suggestions on how to properly implement event delegation in this scenario?

Answer №1

Follow this method: By clicking either the radio button or its corresponding label, you can display the ID. No need to use closest in this case, but if it matches the selector, closest will return the element itself.

This functionality also works in Bootstrap.

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/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ea8885859e999e988b9aaadfc4d8c4d9">[email protected]</a>/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 your buttons have child elements, using closest is necessary.

To display the ID, click on either the button text or the icon.

document.querySelector('.btn-group').addEventListener('click', (e) => {
  const tgt = e.target.closest('.btn'); // wouldn't work on the icon without closest
  if (tgt) console.log(tgt.id)
});
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="284a47475c5b5c5a4958681d061a061b">[email protected]</a>/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>

Answer №2

By utilizing the event delegation technique, I have set up a click event listener on the parent container with the class btn-group. When a click event is detected, the code checks if the clicked element is an <input> element with the type "radio". If it is, the code logs the ID of that element 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/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="27454848535453554657671209150914">[email protected]</a>/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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The issue of not being able to go fullscreen with a YouTube iframe nested within another iframe

I have a YouTube video embedded inside another iframe, but I am facing an issue where the fullscreen feature is not working even after enabling all the required attributes. If the video isn't displaying properly in the code snippet below, you can vie ...

There was an error during module build process: ReferenceError occurred due to an unrecognized plugin "import" specified in "base" at position 0

I have encountered an error while working on my ReactJS project using create-react-app. The error arose after I added and removed a package called "react-rte". Now, every time I try to start my project, I get the following error: Error in ./src/index.js Mo ...

What are the benefits of using `observer` over `inject` when passing data to a React component in MobX?

After reading MobX documentation, it appears that using observer on all components is recommended. However, I have discovered that by utilizing the inject method, I am able to achieve more precise control over which data triggers a re-render of my componen ...

Autocomplete Dropdown Options

I am trying to create a dependent autocomplete drop-down that displays suggestions based on any typed letter, rather than just the first letter. For example, if I type "Yo," it should show "New York" in the dropdown. Below is the code I have been using, ...

Edit the contents within HTML strings without altering the HTML structure

If I have a string of HTML, it might look something like this... <h2>Header</h2><p>all the <span class="bright">content</span> here</p> I am interested in manipulating the string by reversing all the words. For example ...

Adjust the size of the font for the placeholder text

I've been attempting to adjust the font size of the placeholder text. I added the font size property to the listed classes below, but for some reason, it's not taking effect. Could you please advise me on how to resolve this issue so that I can ...

Organizing numerical values within for loops

I'm having trouble determining prime numbers and non-prime numbers. When I follow the logic of looping through numbers from 2 to 100, it makes sense for primes. However, when I start at 0 and loop by y + itself, it seems counterintuitive to me. For ex ...

Display content exclusively within a modal specifically designed for mobile devices

I want to implement a feature where a button triggers a modal displaying content, but only on mobile devices. On desktop, the same content should be displayed in a div without the need for a button or modal. For instance: <div class="container&quo ...

Numerous Levels of Dropdown Menus

I am looking to implement a feature on a web page where users can select multiple vehicles using JQuery. The idea is that selecting the brand in the first dropdown will populate the second dropdown with the models available for that specific brand. The ...

Guide on handling asynchronous data return within a reducer

I'm struggling to properly handle the state when receiving data from the back-end of my application. This is the code I have: if (action.type === actionTypes.getList) { const id = action.payload.userId; Axios.post(`${apiUrl}/lists`, { ...

Clearing a Vue.js filter: a step-by-step guide

Below is my Vue Js code where I have successfully implemented a filter to API array elements. However, I am facing an issue when trying to set up a button that clears the filter upon clicking, restoring the page to its original state without any changes. ...

Utilizing Async/Await in conjunction with Vuex dispatch functionality

I'm currently working on creating a loader for specific components within my application. Here is the code snippet for one of my components: mounted() { this.loading = true; this.getProduct(); }, meth ...

Import a precise model from a glb file

Greetings! I am relatively new to working with ThreeJS and just getting the hang of it. After going through some tutorials, I have successfully managed to load glb files and render them in my browser with ease. Recently, I downloaded a GLB file from that ...

Obtaining Data from CRM 2011 with the Power of jQuery and JavaScript

Currently, I am facing an issue while attempting to retrieve data from CRM 2011 using jQuery. Despite my efforts, I am unable to successfully fetch the desired data. Below is the code that I have been working on: function GetConfigurations() { var oDataP ...

Resetting values in Javascript and JQuery when clicking a button

I've recently implemented a feature on my website header where clicking on the search button reveals a search bar, and clicking on the account button reveals an account bar. With some valuable assistance from Madalin, I was able to achieve this functi ...

Utilizing Express JS to keep users on the same page upon submitting a form

Although this may seem like a simple query with available tutorials, I am struggling to locate the specific information. I utilized express-generator to create an app and included a basic form in a route. views/form.ejs <div> <h1>This is < ...

What reasons could be preventing the state from updating correctly in Vuex?

Currently, I am working on a project where I am utilizing vuex along with axios to retrieve data from the backend. The issue arises when I try to access the state - even though the updated state is displayed successfully when I console-log it, there seems ...

What is the best way to alter something based on the current date?

My goal is to dynamically change a message based on how close a specific date is. The objective is to update an element of a webpage to display "Renewal Unnecessary" when the date is more than 3 months away, "Renewal upcoming" when the date is less than 3 ...

Ending a session in Node.js with Express and Socket.io

I've been grappling with this issue for a few days now and I'm just not able to wrap my head around it. I need to end my session when I navigate away from the webpage, but the error message I keep receiving (which ultimately crashes the server) r ...

Scraping a JavaScript page using Python without requiring a browser installation

Currently, I am facing a challenge in scraping an HTML element from a webpage. The content within this element is dynamically generated by Javascript, making it impossible to retrieve using a simple requests.GET: response = requests.get(url). While explor ...