Find Html Label Associated with a Given Input

Let's say I have an html form. Each input/select/textarea will have a corresponding <label> with the for attribute set to the id of it's companion. In this case, I know that each input will only have a single label.

Given an input element in javascript — via an onkeyup event, for example — what's the best way to find it's associated label?

3

21 Answers

If you are using jQuery you can do something like this

$('label[for="foo"]').hide ();

If you aren't using jQuery you'll have to search for the label. Here is a function that takes the element as an argument and returns the associated label

function findLableForControl(el) {
   var idVal = el.id;
   labels = document.getElementsByTagName('label');
   for( var i = 0; i < labels.length; i++ ) {
      if (labels[i].htmlFor == idVal)
           return labels[i];
   }
}
0

First, scan the page for labels, and assign a reference to the label from the actual form element:

var labels = document.getElementsByTagName('LABEL');
for (var i = 0; i < labels.length; i++) {
    if (labels[i].htmlFor != '') {
         var elem = document.getElementById(labels[i].htmlFor);
         if (elem)
            elem.label = labels[i];         
    }
}

Then, you can simply go:

document.getElementById('MyFormElem').label.innerHTML = 'Look ma this works!';

No need for a lookup array :)

3

There is a labels property in the HTML5 standard which points to labels which are associated to an input element.

So you could use something like this (support for native labels property but with a fallback for retrieving labels in case the browser doesn't support it)...

var getLabelsForInputElement = function(element) {
    var labels = [];
    var id = element.id;

    if (element.labels) {
        return element.labels;
    }

    id && Array.prototype.push
        .apply(labels, document.querySelector("label[for='" + id + "']"));

    while (element = element.parentNode) {
        if (element.tagName.toLowerCase() == "label") {
            labels.push(element);
        }  
    }

    return labels;
};

// ES6
var getLabelsForInputElement = (element) => {
    let labels;
    let id = element.id;

    if (element.labels) {
        return element.labels;
    }

    if (id) {
        labels = Array.from(document.querySelector(`label[for='${id}']`)));
    }

    while (element = element.parentNode) {
        if (element.tagName.toLowerCase() == "label") {
            labels.push(element);
        }  
    }

    return labels;
};

Even easier if you're using jQuery...

var getLabelsForInputElement = function(element) {
    var labels = $();
    var id = element.id;

    if (element.labels) {
        return element.labels;
    }

    id && (labels = $("label[for='" + id  + "']")));

    labels = labels.add($(element).parents("label"));

    return labels;
};
2

I am a bit surprised that nobody seems to know that you're perfectly allowed to do:

<label>Put your stuff here: <input value="Stuff"></label>

Which won't get picked up by any of the suggested answers, but will label the input correctly.

Here's some code that does take this case into account:

$.fn.getLabels = function() {
    return this.map(function() {
        var labels = $(this).parents('label');
        if (this.id) {
            labels.add('label[for="' + this.id + '"]');
        }
        return labels.get();
    });
};

Usage:

$('#myfancyinput').getLabels();

Some notes:

  • The code was written for clarity, not for performance. More performant alternatives may be available.
  • This code supports getting the labels of multiple items in one go. If that's not what you want, adapt as necessary.
  • This still doesn't take care of things like aria-labelledby if you were to use that (left as an exercise to the reader).
  • Using multiple labels is a tricky business when it comes to support in different user agents and assistive technologies, so test well and use at your own risk, etc. etc.
  • Yes, you could also implement this without using jQuery. :-)
1

document.querySelector("label[for=" + vHtmlInputElement.id + "]");

This answers the question in the simplest and leanest manner. This uses vanilla javascript and works on all main-stream proper browsers.

2

Earlier...

var labels = document.getElementsByTagName("LABEL"),
    lookup = {},
    i, label;

for (i = 0; i < labels.length; i++) {
    label = labels[i];
    if (document.getElementById(label.htmlFor)) {
        lookup[label.htmlFor] = label;
    }
}

Later...

var myLabel = lookup[myInput.id];

Snarky comment: Yes, you can also do it with JQuery. :-)

10

All the other answers are extremely outdated!!

All you have to do is:

input.labels

HTML5 has been supported by all of the major browsers for many years already. There is absolutely no reason that you should have to make this from scratch on your own or polyfill it! Literally just use input.labels and it solves all of your problems.

2

with jquery you could do something like

var nameOfLabel = someInput.attr('id');
var label = $("label[for='" + nameOfLabel + "']");
1

If you're willing to use querySelector (and you can, even down to IE9 and sometimes IE8!), another method becomes viable.

If your form field has an ID, and you use the label's for attribute, this becomes pretty simple in modern JavaScript:

var form = document.querySelector('.sample-form');
var formFields = form.querySelectorAll('.form-field');

[].forEach.call(formFields, function (formField) {
    var inputId = formField.id;
    var label = form.querySelector('label[for=' + inputId + ']');
    console.log(label.textContent);
});

Some have noted about multiple labels; if they all use the same value for the for attribute, just use querySelectorAll instead of querySelector and loop through to get everything you need.

Solution One <label>: One <input>

Using HTML 5.2 reference Considering the <label> pointing to <input> using for=, the labels element will be a non empty array, and act as a link to the <label> element, accessing all properties of it, including its id=.

function myFunction() {
  document.getElementById("p1").innerHTML = "The first label associated with input: <b>" + document.getElementById("input4").labels[0].id + "</b>";

}
<form>
  <label id="theLabel" for="input4">my id is "theLabel"</label>
  <input name="name1" id="input4" value="my id is input4">
  <br>
</form>

<p>Click the "click me" button to see the label properties</p>

<button onclick="myFunction()">click me</button>


<p id="p1"></p>

James H. Sterling

James H. Sterling

Environmental Science & Climate Journalist

James Sterling reports on renewable energy developments, climate policy, ecological conservation, and green tech innovations around the globe.