JQuery: получить непосредственно предыдущий брат или родительский элемент

У меня есть форма с несколькими входами и соответствующей меткой рядом с ними (слева).

Когда я проверяю входные данные, я хочу показать сообщение, использующее соответствующую метку, чтобы сказать, какой вход неправильный.

У меня есть рабочий скрипт, показывающий метки, как я хочу, но он ломается, если мой ввод не является прямым братом метки, а вместо этого дочерним братом...

Вот код для иллюстрации:

HTML:

<form>
<label class="autoFormLabel obligatorio">* calle : </label>
<input id="calle2" class="autoForm obligatorio" type="text" value="" name="calle2">
<br>
<label class="autoFormLabel obligatorio">* CP : </label>
<input id="CP" class="autoForm obligatorio" type="text" value="" name="CP">
<br>
<label id="label_colonia" class="autoFormLabel obligatorio">* Colonia : </label>
<span id="span_combo_colonias">
    <select id="Colonia" class="obligatorio autoForm" name="Colonia">
    <option selected="" value="0">-- seleccione --</option>
        <option  value="1">one</option>
        <option  value="2">two</option>
    </select>
</span>
<br>
<label class="autoFormLabel obligatorio">* Delegacion : </label>
<input id="delegacion" class="autoForm obligatorio" type="text" value="" name="delegacion" >
<br>

    <input type="button" id="val" value="Val" />

</form>

JS:

function validate(){
    $(":input.obligatorio:enabled").each(function( i, el ){ // solo considerar los enableds            
        if( $(this).val() == "" || $(this).val() == "0" || $(this).val() == 0){

            label = $(this).prev("label").html(); //A: works for all but select            
            //label = $(this).parent().prev("label").html(); //B: works for select, but not the others         
            //label = $(this).closest("label").html(); //C: why doesn't work for select?

            alert("El campo:\n\n"+label+"\n\nno puede ir vacio");
            $(this).focus();
            return false;
        }       
    });
}

и вот скрипка, чтобы играть с

все входы имеют соответствующую метку родного брата, кроме <select>, который находится внутри <span>, который сам по себе является братом своего лейбла.

мой селектор label = $(this).prev("label").html(); прекрасно работает для всех входов, кроме для выбора, потому что он содержится внутри диапазона (мне это нужно так, потому что такой выбор является динамическим и вставляется в такой диапазон через AJAX)

Я знаю, что мог бы заставить его работать с другим селектором для случая выбора, например так: label = $(this).parent().prev("label").html();но в идеале я хотел бы иметь только один селектор, чтобы получить все метки, независимо от того, насколько глубоким является их соответствующий ввод.

Я также пробовал с селектором.closest(), но он не работает, я не уверен, почему, но я думаю, что это не так, потому что метка не является наследницей выбора (это брат или родитель его, [скажем, "дядя"])

Итак, какой селектор я мог бы использовать для всех случаев, чтобы получить ближайший предыдущий ярлык к входу, несмотря на то, что он является родителем, родным братом, родным братом или даже пра-пра-пра-прародителем, что угодно... (у меня мог быть похоронен ввод в течение нескольких пролетов рядом с его ярлыком, или что-то еще)

Другими словами, как я могу пройти DOM "вверху и влево" и получить первое вхождение селектора, независимо от того, являются ли они родителями ИЛИ братьями и сестрами?

1 ответ

Использование for атрибут на ваших ярлыках:

<label for="calle2" class="autoFormLabel obligatorio">* calle : </label>
<input id="calle2" class="autoForm obligatorio" type="text" value="" name="calle2"/>
...

Затем захватите текст метки, используя следующий селектор jQuery:

label = $('[for="'+this.id+'"]').html();

JSFiddle


Jet другой способ хранения метки "сообщения" в data атрибут input /select вместо поиска элементов в DOM:

<input id="calle2" data-label="Calle" class="autoForm obligatorio" type="text" value="" name="calle2"/>

JQuery:

label = $(this).attr('data-label');

JSFiddle

Другие вопросы по тегам