Onchange Event Handler for Radio Button (Input Type="Radio") Doesn't Work as One Value

OnChange event handler for radio button (INPUT type=radio) doesn't work as one value

var rad = document.myForm.myRadios;var prev = null;for (var i = 0; i < rad.length; i++) {    rad[i].addEventListener('change', function() {        (prev) ? console.log(prev.value): null;        if (this !== prev) {            prev = this;        }        console.log(this.value)    });}
<form name="myForm">  <input type="radio" name="myRadios"  value="1" />  <input type="radio" name="myRadios"  value="2" /></form>

Javascript OnChange event handler for radio button

You are not selecting the checked input radio, you are just picking the first element with that id, since id should be unique.

You can fix it actually selecting the checked input radio:

   function getit(){        var select = document.querySelector('input[name="f06_w01"]:checked').value;        if(select == 1 || select == 3) { document.getElementById('whitch').style.display = "block"; }        else {             document.getElementById('whitch').style.display = "none";         }    }
<input type="radio" name="f06_w01" value="1" onchange="getit();" required /><input type="radio" name="f06_w01" value="2" onchange="getit();" required /><input type="radio" name="f06_w01" value="3" onchange="getit();" required /><input type="radio" name="f06_w01" value="4" onchange="getit();" required />
<div id="whitch" style="display: none;"><p><b>Whats better?</b></p><p><textarea name="f06_t02" id="f06_t02" cols="80" rows="3"></textarea></p></div>

React 16 Radio Button onChange not working

For a radio button, onChange event will trigger for the radio that was previously checked as well as the one that is currently checked. You can do the following to confirm that the correct radio is checked

updateCategory = (e) => {
if(e.target.checked) {
this.props.updateCategory(e.target.value)
}
}

<form className="form-inline my-2 my-lg-0">
<div className="btn-group" data-toggle="buttons">
<label className="btn btn-secondary active">
<input
type="radio"
name="options"
value='health'
defaultChecked
checked={this.props.checked === "health" }
onChange={this.updateCategory} /> Health
</label>
<label className="btn btn-secondary">
<input
type="radio"
name="options"
value='tattoo'
checked={this.props.checked === "tattoo"}
onChange={this.updateCategory} /> Tattoo
</label>
</div>
</form>

Also, you need to make sure that your input is controlled input with the checked value coming from props or state and not a static one, because if you write checked={true}, your radio button will always stay true. You need to store the checked state and then update it like

checked={this.props.checked}

More info about Controlled Components can be found here.


As an alternative, you can also have the input as uncontrolled components and write them like

<form className="form-inline my-2 my-lg-0">
<div className="btn-group" data-toggle="buttons">
<label className="btn btn-secondary active">
<input
type="radio"
name="options"
value='health'
defaultChecked
onChange={this.updateCategory} /> Health
</label>
<label className="btn btn-secondary">
<input
type="radio"
name="options"
value='tattoo'
onChange={this.updateCategory} /> Tattoo
</label>
</div>
</form>

More info about Uncontrolled Components.

DEMO of Uncontrolled input

document.querySelector('input[name=nameOfradio]:checked').value; but radio not checked

You can check for the existence before asking for the value with this syntax:

document.querySelector("input[name=radioa]:checked")?.value

function myFunction() {

let var1 = document.querySelector("input[name=radioa]:checked")?.value;
let var2 = document.querySelector("input[name=radiob]:checked")?.value;

if (var1 && var2) output = var1 + " and " + var2;
else output = "Please select both a number and a letter";
document.getElementById("change").innerHTML = output;
}
<div>
<p>Wich number will you choose ?</p>
<input id="one" name="radioa" type="radio" value="Number 1" />
<label for="one">The N° 1</label>
<input id="two" name="radioa" type="radio" value="Number 2" />
<label for="two">The N° 2</label>
</div>
<div>
<p>Wich letter will you choose ?</p>
<input id="a" name="radiob" type="radio" value="Letter a" />
<label for="a">The letter a</label>
<input id="b" name="radiob" type="radio" value="Letter b" />
<label for="b">The lettter b</label>
</div>
<div>
<button id="z" onclick="myFunction();">button</button>
</div>
<div>You have chosen :</div>
<div id="change"></div>

onchange on radiobutton not working correctly in IE8

In Internet Explorer (up to at least IE8) clicking a radio button or checkbox to change its value does not actually trigger the onChange event until the the input loses focus.

Thus you need to somehow trigger the blur event yourself.. one suggestiong would be to have a function: as follows:

function radioClick()
{
this.blur();
this.focus();
}


<input type="radio" name="rad" value="1" onclick="radioClick" onchange="alert(1);"/>

Now your onchange event should be triggered but as you can see it is redundant code thus you are better off just using the onclick event handler.

The better solution is to use a modern javascript library like jquery which handles all these quirks for you..

How do I trigger a change event on radio buttons in react-testing-library?

Update

As people pointed out my original solution was wrong.

Nowadays I suggest you use userEvent for better-simulating user interactions.

import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";

test("radio", () => {
const user = userEvent.setup();
render(
<form>
<label>
First <input type="radio" name="radio1" value="first" />
</label>
<label>
Second <input type="radio" name="radio1" value="second" />
</label>
</form>
)

await user.click(screen.getByLabelText("Second"));
});

First, you don't have to call rerender. You use rerender only when you want the component to receive different props. See link.

Whenever you call fireEvent the component will render like it would in your normal app.

It's correct to fire a change event, but you must pass a second parameter with the event data.

This example works:

import React from "react";
import { render, fireEvent } from "react-testing-library";

test("radio", () => {
const { getByLabelText } = render(
<form>
<label>
First <input type="radio" name="radio1" value="first" />
</label>
<label>
Second <input type="radio" name="radio1" value="second" />
</label>
</form>
);

const radio = getByLabelText('First')
fireEvent.change(radio, { target: { value: "second" } });
expect(radio.value).toBe('second')
});


Related Topics



Leave a reply



Submit