Pregunta

I am modifying existing code, so I can only affect the elements that exist rather an building it right. I am iterating over all spans that have the class reqd, and if so, I'm either taking the immediate previous sibling (example 1) or the previous sibling's first child of type input (example 2) and appending jQuery validate attributes to it.

Using prev() was for example #1, which was easy. I have to use prevUntil() for examples 2 and 3 to isolate better where I am targeting the DOM.

My issue is with example #2. While I can reach class="regfieldlabel I cannot get it to traverse its children. Example #3 is like #2 except with an empty span tag in the middle.

//Example code 1
<input type="text" name="str_cvv" value="" maxlength="3" size="4" id="CVV">
<span class="reqd">*</span>

//Example code 2
<span class="regfieldlabel">
      <input type="text" name="nameOnCard" size="30" maxlength="50" id="cardName" value="">
</span>
<span class="reqd">*</span>

//Example code 3
<span class="regfieldlabel">
      <input type="text" name="nameOnCard" size="30" maxlength="50" id="cardName" value="">
</span>
<span class="regfieldlabel"> </span>
<span class="reqd">*</span>

<script>
$(function() {
    $("span").each(function(){
        //Highlight all fields that have a red asterisk at the end for validation
        if ($(this).hasClass('reqd')) {
            $(this).prev().attr('data-rule-required', true).attr('data-msg-required', 'This field is required');
            $(this).prevUntil('.regfieldlabel').find('input').attr('data-rule-required', true).attr('data-msg-required', 'This field is required');

        }
    });
});
</script>
¿Fue útil?

Solución

You don't want to use prevUntil, from the docs you will see:

Description: Get all preceding siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object.

As a result, $(this).prevUntil('.regfieldlabel') is actually empty.

For Example 2, you still want to use just prev:

$(this).prev('.regfieldlabel').find('input')

For a general solution, you will have to check which situation you are in, in order to do the correct thing:

$("span.reqd").each(function(){

    var $this = $(this);
    var $prev = $this.prev();
    var $input = $([]); // init to empty

    if($prev.is("input")){
        // EXAMPLE 1
        $input = $prev;

    } else if($prev.is(".regfieldlabel")){
        var $innerInput = $prev.find("input");

        if($innerInput.length > 0){
            // EXAMPLE 2
            $input = $innerInput;
        } else {
            $prev = $prev.prev(".regfieldlabel");
            $innerInput = $prev.find("input");

            if($innerInput.length > 0){
                // EXAMPLE 3
                $input = $innerInput;
            } else {
                // unknown case, maybe do something here
            }
        }
    } else {
        // unknown case, maybe do something here
    }

    $input.attr('data-rule-required', true).attr('data-msg-required', 'This field is required');

});

http://jsfiddle.net/DVSeg/2/

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top