Reputation: 5
I often times easily implemented event delegation with the "click" event on parent elements of something with code like
HTML:
<div>
<span>
<input
type="radio"
id="all0"
name="difficulty-ask"
class="difficultyaskclass"
value="all"
checked="checked"
/>
<label for="all0">All</label>
<input
type="radio"
id="2easy1"
name="difficulty-ask"
class="difficultyaskclass"
value="easy"
/>
<label for="2easy1">Easy</label>
<input
type="radio"
id="2med2"
name="difficulty-ask"
class="difficultyaskclass"
value="medium"
/>
<label for="2med2">Medium</label>
<input
type="radio"
id="2hard3"
name="difficulty-ask"
class="difficultyaskclass"
value="hard"
/>
<label for="2hard3">Hard</label>
</span>
</div>
JS:
parentelement.addEventlistener('click', (event) => {
if(event.target.classList.contains('targetelement'){Code..}};
(parentelement is just a regular div, in which the radio buttons are placed)
How does it work now with the 'change' event for example for radio buttons if they switch state?
I made it work first by just looping through all of them and then add an eventListener to each. But this is obviously not the desired solution, i definitely need some event delegation there.
Upvotes: 0
Views: 95
Reputation: 34217
This can be done pretty simply; here I also added some buttons to show the value and also clear the output - all so you can see the output and also show how to clear the radio value with code.
const container = document.querySelector(".container-parent");
const output = document.querySelector(".output");
const clear = document.querySelector(".clear-radio");
function handleChange(event) {
output.innerHTML += `<div class="line">You changed to a ${event.currentTarget.tagName} element<br/>` +
`Change was "${event.target.value}" value</div>`;
}
function handleClearRadio(event) {
const radios = document.getElementsByName("radioflyer");
const cked = [...radios].filter((el) => {
return !!el.checked;
});
const hasChecked = !!cked.length;
let v;
if (hasChecked) {
v = cked[0].value;
cked[0].checked = false;
}
/*could be done in a loop but not needed for radios as cked[0].checked = false; works fine
for (let i = 0; i < radios.length; i++) {
radios[i].checked = false;
}
*/
output.innerHTML += `<div class="line">You cleared radios: ${hasChecked}<br/>` +
`Clear was "${v}" value</div>`;
}
container.addEventListener("change", handleChange, {
capture: true
});
clear.addEventListener("click", handleClearRadio, {
capture: true
});
document.querySelector(".clear-output").addEventListener("click", function(event) {
output.innerHTML = "Cleared";
});
.output {
border: solid 1px #00ff00;
}
.output .line {
border: solid 1px #0000ff;
margin: 0.5em;
}
.container-parent {
border: solid 1px #00ff00;
padding: 0.5em;
margin-bottom: 1em;
}
<form>
<fieldset>
<legend>Please select your preferred wagon order:</legend>
<div class="container-parent">
<label><input type="radio" class="radio-wins" value="first" name="radioflyer" />First</label>
<label><input type="radio" class="radio-wins" value="second" name="radioflyer" />Second</label>
<label><input type="radio" class="radio-wins" value="third" name="radioflyer" />Third</label>
</div>
<button type="button" class="clear-radio">Clear Radio</button>
<button type="button" class="clear-output">Clear Output</button>
<div class="output">
Output will go here
</div>
</fieldset>
</form>
Same as above but JUST the questions code
const container = document.querySelector(".container-parent");
function handleChange(event) {
//do something on change
console.log(`Change was "${event.target.value}" value`);
}
container.addEventListener("change", handleChange, {
capture: true
});
.container-parent {
border: solid 1px #00ff00;
padding: 0.5em;
margin-bottom: 1em;
}
<div class="container-parent">
<span>
<input
type="radio"
id="all0"
name="difficulty-ask"
class="difficultyaskclass"
value="all"
checked="checked"
/>
<label for="all0">All</label>
<input
type="radio"
id="2easy1"
name="difficulty-ask"
class="difficultyaskclass"
value="easy"
/>
<label for="2easy1">Easy</label>
<input
type="radio"
id="2med2"
name="difficulty-ask"
class="difficultyaskclass"
value="medium"
/>
<label for="2med2">Medium</label>
<input
type="radio"
id="2hard3"
name="difficulty-ask"
class="difficultyaskclass"
value="hard"
/>
<label for="2hard3">Hard</label>
</span>
</div>
Upvotes: 0
Reputation: 22365
you may use input
event, which is also valid for any forms elements
demo:
const myForm = document.forms['my-form'];
myForm.addEventListener('submit', e =>
{
e.preventDefault(); // disable submit - page reload
const formValues = Object.fromEntries(new FormData(myForm).entries());
console.log( formValues );
setTimeout(console.clear,3000);
})
myForm.addEventListener('input', e =>
{
if (!e.target.matches('input[type="radio"]')) return;
console.log(myForm['difficulty-ask'].value);
setTimeout(console.clear,1300);
});
label { display: block; cursor: pointer; }
fieldset { width: fit-content; }
<form name="my-form">
<fieldset>
<legend> difficulty </legend>
<label>
<input name="difficulty-ask" type="radio" value="all" checked >
All
</label>
<label>
<input name="difficulty-ask" type="radio" value="easy" >
Easy
</label>
<label>
<input name="difficulty-ask" type="radio" value="medium" >
Medium
</label>
<label>
<input name="difficulty-ask" type="radio" value="hard" >
Hard
</label>
</fieldset>
<button>submit</button>
</form>
Upvotes: 1
Reputation: 1747
You can also use click or also change as you have 2 choices value. You can use event delegation combined with call() method. Here I added event delegation to input type radio only and also added an input type checkbox in HTML
const div = document.querySelector('div')
console.log(div)
div.addEventListener('change',(e)=>{
let target = e.target
if(target.matches("input[type='radio']")){
check.call(e.target,e)
}
})
function check(){
console.log(this.value)
}
<div>
<span>
<input
type="radio"
id="all0"
name="difficulty-ask"
class="difficultyaskclass"
value="all"
checked="checked"
/>
<label for="all0">All</label>
<input
type="radio"
id="2easy1"
name="difficulty-ask"
class="difficultyaskclass"
value="easy"
/>
<label for="2easy1">Easy</label>
<input
type="radio"
id="2med2"
name="difficulty-ask"
class="difficultyaskclass"
value="medium"
/>
<label for="2med2">Medium</label>
<input
type="radio"
id="2hard3"
name="difficulty-ask"
class="difficultyaskclass"
value="hard"
/>
<label for="2hard3">Hard</label>
<label for="2med45">checkbox</label>
<input
type="checkbox"
id="2hard36"
name="difficulty-ask1"
class="difficultyaskclass5"
value="hardtoveryhard"
/>
<label for="2hard36">Hard</label>
</span>
</div>
Upvotes: 0