Mark Walters
Mark Walters

Reputation: 12400

jQuery traversal - finding previous label to current input

Just a quick question as I haven't been using jQuery for that long.

Is there a neater/quicker way to get to the html for a label in this scenario.

Here is a dumbed down version as an example,

<tr>
   <td>
       <label>Please fill in name:</label>
   </td>
   <td>
       <input type="text" id="txtName" class="validate" />
   </td>
</tr>
<tr>
   <td>
       <label>Date of Birth:</label>
   </td>
   <td>
       <input type="text" id="txtDOB" class="validate" />
   </td>
</tr>

This is the jquery snippet i'm using currently to grab the html for the labels.

$(document).ready(function(){
   $('.validate').each(function(){
      if(!$(this).val())
      {
          var label = $(this).parent().prev().find('label').html();
          alert(label);
      }
   }); 
});

Any ideas are appreciated

Upvotes: 1

Views: 2501

Answers (5)

Scott M
Scott M

Reputation: 71

I use this;

<script type="text/javascript">
$(document).ready(function(){
$("select").change(function(){

if($(this).val() == "A")    
var label = $(this).parent().prev("label").text();
alert(label);

});
});
</script> 

Upvotes: 0

Mohammed Swillam
Mohammed Swillam

Reputation: 9242

yes, there is another neat way to do so by using Closest() instead of Parent()

Consider the following code:

$(document).ready(function(){
   $('.validate').each(function(){
      if(!$(this).val())
      {
          var label = $(this).closest("tr").find('label').html();
          alert(label);
      }
   }); 
});

Closest(): Get the first element that matches the selector, beginning at the current element and progressing up through the DOM tree.

Upvotes: 3

Tjkoopa
Tjkoopa

Reputation: 2378

You should be using the 'for' attribute on the labels, not only is it semantic/accessible it gives you a shorter selector:

<table>
  <tr>
      <td>
        <label for="txtName">Please fill in name:</label>
      </td>
      <td>
        <input type="text" id="txtName" class="validate" />
      </td>
  </tr>
  <tr>
      <td>
        <label for="txtDOB">Date of Birth:</label>
      </td>
      <td>
        <input type="text" id="txtDOB" class="validate" />
      </td>
  </tr>
</table>

$(document).ready(function(){
  $('.validate').each(function(){
    if(!$(this).val())
    {
      var label = $('label[for="'+$(this).attr('id')+'"]').html();
      alert(label);
    }
  }); 
});​

Upvotes: 0

Jamiec
Jamiec

Reputation: 136174

I'll add this as an answer, even though it's a sort of diversion from your question:

You are using table-based layout for non-tabular data, you should have layout such as

<div>
<label>Please fill in name:</label>
<input type="text" id="txtName" class="validate" />
</div>
<div>
<label>Date of Birth:</label>
<input type="text" id="txtDOB" class="validate" />
</div>

in which case the jQuery becomes super-simple:

$('.validate').each(function(){
      if(!$(this).val())
      {
          var label = $(this).prev('label').html();
          alert(label);
      }
   }); 

Live example: http://jsfiddle.net/MDFEm/

Upvotes: 1

linuxeasy
linuxeasy

Reputation: 6499

Yes, you can a bit shorten it:

$(document).ready(function(){
   $('.validate').each(function(){
      if(!$(this).val())
      {
          var label = $(this).parents('tr').find('label').html(); 
          alert(label);
      }
   }); 
});

Upvotes: 0

Related Questions