nohope4you nohope4you - 5 months ago 12
jQuery Question

Use .prev() to go outside of table?

I have this function:

function ChangeColor(element) {
$(element).prev("SPAN").css("background-color", "");
if (element.value.length < 1) {
$(element).prev("SPAN").css("background-color", "#FFBED1");
}
}


And this HTML:

<span style="background-color: #FFBED1">
Answer this question:<br>
</span>
<input name=Q1 onchange="ChangeColor(this);"><br><br>

<span style="background-color: #FFBED1">
Answer this question also:
</span>
<table>
<tr>
<td>Question 2</td>
<td><input name=Q2 onchange="ChangeColor(this);"></td>
</tr>
</table>


It doesn't change the background on the
span
before the question in the
table
. Is there a way to make this function work with both
input
elements?

I've tried adding:

if($(element).prev("SPAN").get(0)==undefined) {$(element).parent().prev("SPAN").css("background-color","");}


but that doesn't seem to help or change anything...

Answer

You can use closest() to find the table element, then prev() to get the sibling span from there. You would also need a little logic to cater for the cases where the span is a direct sibling of the input or when the input is in the table. Try this:

function ChangeColor(element) {
    var $span = $(element).prev('span');
    if (!$span.length)
        $span = $(element).closest('table').prev('span');

    $span.css("background-color", "");
    if (element.value.length < 1) {
        $span.css("background-color", "#FFBED1");
    }
} 

Also note that it's much better practice to use unobtrusive JS to attach your event handlers and avoid the use of outdated on* event attributes. As you've tagged the question with jQuery, here's how to do that:

<span class="empty">
    Answer this question:<br />
</span>
<input name="Q1" class="question"><br /><br />

<span class="empty">
    Answer this question also:
</span>
<table>
    <tr>
        <td>Question 2</td>
        <td><input name="Q2" class="question"></td>
    </tr>
</table>
$('.question').change(function() {
    var $q = $(this);
    var $span = $q.prev('span');
    if (!$span.length)
        $span = $q.closest('table').prev('span');

    $span.toggleClass('empty', !$q.val().length);
});

Working example

Note the use of a class over directly applying some CSS to the element which allows us to use the toggleClass() method with a boolean state flag to add/remove the class as required.