Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Attach event listener through javascript to radio button

I have several radio buttons with the same name. Like this:

<form name="formA">
<input type="radio" name="myradio" value="A"/>
<input type="radio" name="myradio" value="B"/>
<input type="radio" name="myradio" value="C"/>
<input type="radio" name="myradio" value="D"/>
</form>

Now I have to add event listener through javascript to all the radio buttons. If the below pseudocode is wrong, then please tell me how to do it-

var radios = document.forms["formA"].elements["myradio"];
  for(radio in radios) {
    radio.onclick = function() {
        alert(radio.value);
    }
}
like image 427
Acn Avatar asked Jan 19 '12 06:01

Acn


People also ask

Can you add an event listener to a function in JavaScript?

You can add event listeners to any DOM object not only HTML elements. i.e the window object. The addEventListener() method makes it easier to control how the event reacts to bubbling.

Does radio button have Onchange?

The onchange event occurs when the value of an element has been changed. For radiobuttons and checkboxes, the onchange event occurs when the checked state has been changed.


4 Answers

For in loops in JavaScript return the keys, not the values. To get the for in loop to work, assuming you haven't added custom properties to your array, you'd do:

for(radio in radios) {
    radios[radio].onclick = function() {
        alert(this.value);
    }
}

But you should always loop an array with a regular for loop to avoid accidentally including custom-added enumerable properties:

var radios = document.forms["formA"].elements["myradio"];
for(var i = 0, max = radios.length; i < max; i++) {
    radios[i].onclick = function() {
        alert(this.value);
    }
}
like image 97
Adam Rackis Avatar answered Sep 27 '22 21:09

Adam Rackis


Another option is to attach multiple elements to a single event listener by using delegated handlers

You can attach the parent listener to document or any appropriate parent node. Then you can check the event was raised by the appropriate target using the Element.matches() API or anything on event.target

document.getElementById("languages").addEventListener('click', function (event) {
    if (event.target && event.target.matches("input[type='radio']")) {
        // do something here ...
    }
});

This is roughly equivalent to the following jQuery syntax which uses .on() to provide delegation

$("#languages").on("click", "input[type='radio']", function(event) {
    // do something here ...
});

If you want to extend the EventTarget.addEventListener() prototype, you can wrap with your own method:

window.EventTarget.prototype.addDelegatedListener = function(type, delegateSelector, listener) {
    this.addEventListener(type, function (event) {
        if (event.target && event.target.matches(delegateSelector)) {
            listener.call(event.target, event)
        }
    });
}

Then use like this:

document.addDelegatedListener("click", "input[type='radio']", function(event) {
    // do something here ...
});

Demo in Stack Snippets

// example 1 - regular add event listener
document.getElementById("languages").addEventListener('click', function (event) {
    if ( event.target && event.target.matches("input[type='radio']") ) {
        console.log(event.target.value)
    }
});

// example 2 - reusable delegated listener
window.EventTarget.prototype.addDelegatedListener = function(type, delegateSelector, listener) {
    this.addEventListener(type, function (event) {
        if (event.target && event.target.matches(delegateSelector)) {
            listener.call(event.target, event)
        }
    });
}

let parent = document.getElementById("weekdays")
parent.addDelegatedListener("click", "input[type='radio']", function(event) {
    console.log(this.value)
});
h3 {
    margin-top: 20px;
    margin-bottom: 10px;
    font-size: 1.1em;
}
code {
    background: #e9e9e9;
    padding: 1px 4px;
    border-radius: 3px;
}
label input {
    vertical-align: text-top;
}
<h3>Languages <code>addEventListener</code> + <code>Element.matches</code></h3>
<div id="languages">
  <label><input type="radio" name="languages" value="HTML"> HTML </label>
  <label><input type="radio" name="languages" value="JS"> JS </label>
  <label><input type="radio" name="languages" value="CSS"> CSS </label>
</div>

<h3>Weekdays <code>EventTarget.prototype.addDelegatedListener</code></h3>
<div id="weekdays">
  <label><input type="radio" name="days" value="Mon"> Mon </label>
  <label><input type="radio" name="days" value="Tue"> Tue </label>
  <label><input type="radio" name="days" value="Wed"> Wed </label>
</div>
like image 31
KyleMit Avatar answered Sep 27 '22 21:09

KyleMit


You could add just a single listener that listens to all radio buttons, rather than individual listeners.

using jquery, you could do it like this

$(document).ready(function(){
    $('input[type=radio]').click(function(){
        alert(this.value);
    });
});

Demo

For only the radios within a form with id formA

 $(document).ready(function(){
        $('#formA input[type=radio]').click(function(){
            alert(this.value);
        });
    });

For only radios with an id myradio

$(document).ready(function(){
    $('input[type=radio]').click(function(){
        if (this.id == "myradio")
            alert(this.value);
    });
});

Demo

like image 39
xbonez Avatar answered Sep 27 '22 20:09

xbonez


A good start, but don't use for..in that way as it will iterate over all enumerable properties and you haven't checked to see if they all represent elements.

Much better to use an index:

for (var i=0, iLen=radios.length; i<iLen; i++) {
  radios[i].onclick = function() {...};
} 
like image 23
RobG Avatar answered Sep 27 '22 20:09

RobG