Guido Lemmens 2
Guido Lemmens 2

Reputation: 2307

jquery Tree Traversal prev() in TD's

I'm trying to check/unckeck a selectbox by jquery in a previous TD. I have tried for hours several combination with prev(), parent(), closest(), but still without result... Here is the example code:

<table>
 <tr>
 <td><input type="checkbox" class="resultcheck"></td>
 <td><label class="resultchecklabel">Text 1</label></td>
 </tr>

 <tr>
 <td><input type="checkbox" class="resultcheck"></td>
 <td><label class="resultchecklabel">Text 2</label></td>
 </tr>

</table>

<script>
$('.resultchecklabel').live('click', function() {
 if ($(this).prev('td input:checked').val() != null) 
 {
  $(this).prev('td').prev("input").removeAttr("checked");
 }
 else
 {
  $(this).prev('td').prev("input").attr("checked","checked");
 }
});
</script>

Who can help me to solve this question? Many thanks!

Upvotes: 3

Views: 6920

Answers (3)

Adam Kiss
Adam Kiss

Reputation: 11859

real life solution

use ID in conjuction with for:

 <td><input type="checkbox" id="resultcheck1"></td>
 <td><label for="resultcheck1">Text 2</label></td>

and screw the javascript :]

Tree traversal:

You must think of it as a tree. that said, think about scope (what you have as $(this)):

Id you want to go from resultchecklabel to resultcheck, you have to go up to td=>previous td=>it's child resultcheck.

Translated to tree relations: parent=>previous sibling=>child. now, it's easy to translate this english to jQuery, since it's really straightforward:

var $dest = $(this).parent('td').prev().children('.resultcheck')

As you see, when you think in intensions of movement on the tree, it's pretty much english with parentheses.

example:

http://jsbin.com/evupu/2

Upvotes: 3

tvanfosson
tvanfosson

Reputation: 532715

@Adam and @peterendidit hit the nail on the head -- javascript/jQuery not needed here.

The reason that your code wasn't working though, is probably because this in your context is the label element, while the td are siblings of each other, not the label. I think this would have done what you wanted and would suffice if you had more complicated requirements -- say additional styling, etc.

var cb = $(this).closest('td')  // containing TD
                .prev('td')     // previous TD
                .find('input'); // input within TD
if (cb.find(':checked').length == 0) { // not checked
    cb.attr('checked','checked');
}
else {
    cb.removeAttr('checked');
}

Upvotes: 9

PetersenDidIt
PetersenDidIt

Reputation: 25620

Labels don't need fancy javascript to be connected to input elements. Just give the input an ID and use the for attribute on the label:

<table>
 <tr>
 <td><input type="checkbox" class="resultcheck" id="resultcheck1"></td>
 <td><label class="resultchecklabel" for="resultcheck1">Text 1</label></td>
 </tr>

 <tr>
 <td><input type="checkbox" class="resultcheck" id="resultcheck2"></td>
 <td><label class="resultchecklabel" for="resultcheck2">Text 2</label></td>
 </tr>

</table>

Upvotes: 2

Related Questions