Question

Disons que j'ai un formulaire HTML. Chaque entrée / sélection / zone de texte aura un <label> correspondant avec l'attribut for défini sur l'id de son compagnon. Dans ce cas, je sais que chaque entrée n’aura qu’une seule étiquette.

Étant donné un élément d'entrée en javascript & # 8212; via un événement onkeyup, par exemple & # 8212; Quelle est la meilleure façon de trouver son étiquette associée?

Était-ce utile?

La solution

Commencez par rechercher des étiquettes dans la page, puis attribuez une référence à l'étiquette à partir de l'élément de formulaire actuel:

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];         
    }
}

Ensuite, vous pouvez simplement aller:

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

Pas besoin d'un tableau de recherche:)

Autres conseils

Si vous utilisez jQuery, vous pouvez faire quelque chose comme ceci

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

Si vous n'utilisez pas jQuery, vous devez rechercher le libellé. Voici une fonction qui prend l'élément en argument et renvoie le libellé associé

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];
   }
}

Il y a une propriété labels dans le norme HTML5 qui pointe vers les étiquettes associées à un élément d'entrée.

Vous pouvez donc utiliser quelque chose comme ceci (support de la propriété native <=> mais avec un repli pour récupérer les étiquettes si le navigateur ne le prend pas en charge) ...

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;
};

Encore plus facile si vous utilisez 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;
};

Je suis un peu surpris que personne ne semble savoir que vous êtes parfaitement autorisé à faire:

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

Qui ne sera pas retenu par les réponses suggérées, mais étiquetera correctement l'entrée .

Voici un code qui prend ce cas en compte:

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

Utilisation:

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

Quelques notes:

  • Le code a été écrit pour la clarté et non pour la performance. Des alternatives plus performantes peuvent être disponibles.
  • Ce code permet d’obtenir les étiquettes de plusieurs éléments en une fois. Si ce n'est pas ce que vous voulez, adaptez-le si nécessaire.
  • Cela ne résout pas les problèmes tels que aria-labelledby si vous deviez utiliser cela (laissé au lecteur comme un exercice).
  • L'utilisation de plusieurs étiquettes est une tâche délicate lorsqu'il s'agit de prendre en charge différents agents utilisateurs et technologies d'assistance, alors testez-le bien et utilisez-le à vos risques et périls, etc.
  • .
  • Oui, vous pouvez également implémenter cela sans utiliser jQuery. : -)

Plus tôt ...

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;
    }
}

Plus tard ...

var myLabel = lookup[myInput.id];

Commentaire Snarky: Oui, vous pouvez également le faire avec JQuery. : -)

avec jQuery vous pourriez faire quelque chose comme

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

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

Ceci répond à la question de la manière la plus simple et la plus simple. Cela utilise javascript vanille et fonctionne sur tous les navigateurs appropriés du flux principal.

Si vous souhaitez utiliser querySelector (et vous pouvez, même jusqu'à IE9 et parfois IE8!), Une autre méthode devient viable.

Si votre champ de formulaire a un ID et que vous utilisez l'attribut for du libellé, cela devient assez simple avec le JavaScript moderne:

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);
});

Certains ont remarqué plusieurs étiquettes. s'ils utilisent tous la même valeur pour l'attribut querySelectorAll, utilisez simplement querySelector au lieu de <=> et passez en boucle pour obtenir tout ce dont vous avez besoin.

$("label[for='inputId']").text()

Cela m'a aidé à obtenir l'étiquette d'un élément d'entrée en utilisant son ID.

La réponse de Gijs a été précieuse pour moi, mais malheureusement l'extension ne fonctionne pas.

Voici une extension réécrite qui fonctionne, elle peut aider quelqu'un:

jQuery.fn.getLabels = function () {
    return this.map(function () {
        var parentLabels = $(this).parents('label').get();
        var associatedLabels = this.id ? associatedLabels = $("label[for='" + this.id + "']").get() : [];
        return parentLabels.concat(associatedLabels);
    });
};

Il est en réalité beaucoup plus facile d'ajouter un identifiant à l'étiquette dans le formulaire lui-même, par exemple:

<label for="firstName" id="firstNameLabel">FirstName:</label>

<input type="text" id="firstName" name="firstName" class="input_Field" 
       pattern="^[a-zA-Z\s\-]{2,25}$" maxlength="25"
       title="Alphabetic, Space, Dash Only, 2-25 Characters Long" 
       autocomplete="on" required
/>

Ensuite, vous pouvez simplement utiliser quelque chose comme ceci:

if (myvariableforpagelang == 'es') {
   // set field label to spanish
   document.getElementById("firstNameLabel").innerHTML = "Primer Nombre:";
   // set field tooltip (title to spanish
   document.getElementById("firstName").title = "Alfabética, espacio, guión Sólo, 2-25 caracteres de longitud";
}

Le javascript doit être dans une fonction body onload pour fonctionner.

Juste une pensée, fonctionne à merveille pour moi.

Comme cela a déjà été mentionné, la réponse (actuellement) la mieux notée ne tient pas compte de la possibilité d’incorporer une entrée dans une étiquette.

Puisque personne n'a posté de réponse sans JQuery, voici le mien:

var labels = form.getElementsByTagName ('label');
var input_label = {};
for (var i = 0 ; i != labels.length ; i++)
{
    var label = labels[i];
    var input = label.htmlFor
              ? document.getElementById(label.htmlFor)
              : label.getElementsByTagName('input')[0];
    input_label[input.outerHTML] = 
        (label.innerText || label.textContent); // innerText for IE8-
}

Dans cet exemple, par souci de simplicité, la table de recherche est directement indexée par les éléments HTML en entrée. Ceci n’est guère efficace et vous pouvez l’adapter à votre guise.

Vous pouvez utiliser un formulaire comme élément de base ou l'intégralité du document si vous souhaitez obtenir des étiquettes pour plusieurs formulaires à la fois.

Aucune vérification n'est effectuée pour le code HTML incorrect (entrées multiples ou manquantes à l'intérieur des étiquettes, entrée manquante avec l'identifiant htmlFor, etc.), mais n'hésitez pas à les ajouter.

Vous pouvez également couper les textes de l'étiquette, car les espaces de fin sont souvent présents lorsque l'entrée est incorporée dans l'étiquette.

avez-vous essayé d'utiliser document.getElementbyID ('id') où id est l'identifiant du libellé ou la situation dans laquelle vous ne savez pas lequel vous recherchez

Utilisez un sélecteur JQuery:

$("label[for="+inputElement.id+"]")

Pour les futurs chercheurs ... Voici une version jQuery de la réponse acceptée par FlySwat:

var labels = $("label");
for (var i = 0; i < labels.length; i++) {
    var fieldId = labels[i].htmlFor;
    if (fieldId != "") {
        var elem = $("#" + fieldId);
        if (elem.length != 0) {
            elem.data("label", $(labels[i]));   
        }
    }
}

Utilisation de:

$("#myFormElemId").data("label").css("border","3px solid red");

Je sais que c’est vieux, mais j’ai eu du mal à trouver des solutions et j’ai tout reconstitué. J'ai testé cela sur Windows (Chrome, Firefox et MSIE) et OS X (Chrome et Safari) et je pense que c'est la solution la plus simple. Cela fonctionne avec ces trois styles de fixation d’une étiquette.

<label><input type="checkbox" class="c123" id="cb1" name="item1">item1</label>

<input type="checkbox" class="c123" id="cb2" name="item2">item2</input>

<input type="checkbox" class="c123" id="cb3" name="item3"><label for="cb3">item3</label>

Utilisation de jQuery:

$(".c123").click(function() {
    $cb = $(this);
    $lb = $(this).parent();
    alert( $cb.attr('id') + ' = ' + $lb.text() );
});

Mon JSFiddle: http://jsfiddle.net/pnosko/6PQCw/

J'ai fait pour mon propre besoin, peut être utile pour quelqu'un: JSFIDDLE

$("input").each(function () {
    if ($.trim($(this).prev('label').text()) != "") {
        console.log("\nprev>children:");
        console.log($.trim($(this).prev('label').text()));
    } else {
        if ($.trim($(this).parent('label').text()) != "") {
            console.log("\nparent>children:");
            console.log($.trim($(this).parent('label').text()));
        } else {
            if ($.trim($(this).parent().prev('label').text()) != "") {
                console.log("\nparent>prev>children:");
                console.log($.trim($(this).parent().prev('label').text()));
            } else {
                console.log("NOTFOUND! So set your own condition now");
            }
        }
    }
});

Je suis un peu surpris que personne ne suggère d'utiliser la méthode de relation CSS?

dans une feuille de style, vous pouvez référencer une étiquette à partir du sélecteur d'élément:

<style>

//for input element with class 'YYY'
input.YYY + label {}

</style>

si la case à cocher a un identifiant de 'XXX' alors l'étiquette serait trouvée par jQuery par:

$('#XXX + label');

Vous pouvez également appliquer .find ('+ label') pour renvoyer l'étiquette à partir d'un élément de case à cocher jQuery, c'est-à-dire utile lors de la mise en boucle:

$('input[type=checkbox]').each( function(){
   $(this).find('+ label');
});

Toutes les autres réponses sont extrêmement obsolètes!

Tout ce que vous avez à faire est de:

input.labels

HTML5 est compatible avec tous les principaux navigateurs depuis de nombreuses années déjà. Il n'y a absolument aucune raison pour que vous ayez à le fabriquer vous-même ou à le polyfiller! Utilisez littéralement input.labels pour résoudre tous vos problèmes.

La meilleure solution fonctionne parfaitement, mais dans la plupart des cas, il est excessif et inefficace de parcourir tous les label éléments.

Voici une fonction efficace pour obtenir le input élément associé à <=> l'élément:

function getLabelForInput(id)
{
    var el = document.getElementById(id);
    if (!el)
        return null;
    var elPrev = el.previousElementSibling;
    var elNext = el.nextElementSibling;
    while (elPrev || elNext)
    {
        if (elPrev)
        {
            if (elPrev.htmlFor === id)
                return elPrev;
            elPrev = elPrev.previousElementSibling;
        }
        if (elNext)
        {
            if (elNext.htmlFor === id)
                return elNext;
            elNext = elNext.nextElementSibling;
        }
    }
    return null;
}

Pour moi, cette ligne de code était suffisante:

el = document.getElementById(id).previousElementSibling;

Dans la plupart des cas, le <=> sera très proche ou proche de l'entrée, ce qui signifie que la boucle dans la fonction ci-dessus n'a à itérer qu'un très petit nombre de fois.

Une solution très concise utilisant des fonctionnalités ES6 telles que la déstructuration et les retours implicites pour le transformer en une doublure pratique serait:

const getLabels = ({ labels, id }) => labels || document.querySelectorAll(`label[for=${id}]`)

Ou simplement pour obtenir une étiquette, pas une liste de noeuds:

const getFirstLabel = ({ labels, id }) => labels && labels[0] || document.querySelector(`label[for=${id}]`)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top