Reputation: 3605
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?
Upvotes: -1
Views: 57
Reputation: 178375
Here is how. Clicking the radio OR the label will show the ID.
No need for closest
here, but closest WILL return the element itself if it matches the selector
In Bootstrap it also 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>
Upvotes: 1
Reputation: 9213
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>
Upvotes: 1