Reputation: 6019
I have some checkboxes and I want the text of the label to change when the checkbox is selected:
var listener = function() {
document.addEventListener('change', function(e) {
if (e.target.checked) {
e.target.label.className = "option-selected";
}
}
}
}
HTML if you are interested:
<input id="0A" class="individual-checkbox" type="checkbox" value="A">
<label for="0A">A</label>
<br>
<input id="0B" class="individual-checkbox" type="checkbox" value="B">
<label for="0B">B</label>
Obviously, target.label
doesn't work. How do I access the label of the target and give it a CSS class (purely in JavaScript)?
Upvotes: 0
Views: 10525
Reputation: 2098
this will do the trick:
function addListener(elem) {
// remember: checkboxes never change trair value
elem.addEventListener('click', function () {
var ls = document.getElementsByTagName('label');
for (var l = 0, ll = ls.length, lbl; l < ll; ++l) {
lbl = ls[l];
if ( this.id == lbl.getAttribute("for") )
{
lbl.className = ( this.checked ? "option-selected" : "" );
}
}
});
}
see http://jsfiddle.net/fGSCH/10/
be aware that addListener()
might not work in every browser. but since you used it in the example i will use it too.
Upvotes: 0
Reputation: 708146
To make your jsFiddle work, you have to change the following:
addListener()
function call and you have an extra closing brace.listener()
function to make it run.There are several different ways to target the label. The simplest would be to enclose the input inside the label and then just use .parentNode
to get the label from the checkbox.
HTML:
<label for="0A">
<input id="0A" class="individual-checkbox" type="checkbox" value="A">
A</label>
<br>
<label for="0B">
<input id="0B" class="individual-checkbox" type="checkbox" value="B">
B</label>
code:
var listener = function() {
document.addEventListener('change', function(e) {
if (e.target.checked) {
e.target.parentNode.className = "option-selected";
}
});
}
listener();
Working jsFiddle: http://jsfiddle.net/jfriend00/s2A7W/
If you don't want to change your HTML, then you just need to find the label element that is right after your input element.
You can do that like this:
var listener = function() {
document.addEventListener('change', function(e) {
var label;
if (e.target.checked) {
label = next(e.target, "label");
if (label) {
label.className = "option-selected";
}
}
});
}
listener();
function next(src, tag) {
tag = tag.toUpperCase();
while (src && src.tagName !== tag) {
src = src.nextSibling;
}
return src;
}
Working jsFiddle: http://jsfiddle.net/jfriend00/3wQKa/
FYI, you should probably also restrict the action of your listener to only when a checkbox is actually the target or an element with a particular classname or some other distinguishing feature that makes sure it's a checkbox you want targeted by this code. You are probably safe with e.target.checked
, but I don't like the fact that this event listener responds to all propagated change events in the entire page.
Upvotes: 3
Reputation: 817208
Assuming there is only one label
element associated with the element:
e.target.labels[0].className = "option-selected";
This is an HTML5 property though, I don't know how well it is supported in older browsers. Source: MDN.
Alternatively, if IE8 support is enough for you, you can explicitly search for it with document.querySelector
:
var label = document.querySelector('[for=' + e.target.name + ']');
This only works if you give the input
elements name
attributes (which you really want to do, otherwise the labels are not properly connected to the input elements).
And finally, if the label always comes after the input, you can traverse the DOM:
var label = e.target.nextSibling;
while (label.nodeName !== 'LABEL') {
label = label.nextSibling;
}
If you'd restructure your HTML so that the input element is a child of the label element:
<label for="0A">
<input id="0A" class="individual-checkbox" type="checkbox" value="A">
A
</label>
then you could simply use e.target.parentNode
to get the label. Putting the input element inside the label also connects the label to the input.
Upvotes: 1