views:

235

answers:

2

Hi all:

I'm just getting going with jQuery and am pretty excited about it.

My reason for posting is that I've written some jQuery that does it's required task, but I'm suspecting that it lacks a little in elegance...

I'm trying to grab all table rows that have: 1) a class of 'item' 2) a child text input box that has a value

The HTML:

<tr class="item">
    <td class="sku">[dynamic]</td>
    <td class="quantity">
        <input type="text" name="[dynamic]" maxlength="3" /></td>
</tr>

The jQuery

...
var selections=$(".item>.quantity>:text[value!='']").parent().parent();
...

The code I posted above works, but there are two things (at least?) that smell a little funny.

Code smell #1: I'm using '.parent().parent()' at the end to grab the whole row. Is there some way that I can just say, "give me all tr's with a class of 'item' where the child text input has a value" instead of backtraking up the heirarchy at the end?

Code smell #2: I can't figure out a way to 'trim' the text input's value during the selection to ensure that whitespace isnt interpreted as content. With my current method, I would have to 'trim' and check again during the .each loop, which seems redundant.

Let me know if you see a 'better way'?

Thanks, Richard

+4  A: 

#1

Use this instead (note the has selector):

var selections=$(".item:has(>.quantity>:text[value!=''])");

#2

Spaces are usually considered to be valid input, so if your application specifically needs otherwise, it's ok to filter in a loop using $.trim().

Seb
how about $("tr.item ..., just in case the OP is using the item class on other elements?
Russ Cam
Good thought - thanks.
rgeorge
Hi Seb:Thanks for the response. your suggestion works beautifully. I just kept overlooking the ':has' filter. I don't currently have enough reputation to vote for the answer, but you definitely nailed it - thanks again!Richard
rgeorge
@Richard: If his answer helped you, mark it as accepted by clicking on the checkmark to the left of the answer. Do remember to add 'input' before the ':text' selector though. :)
Paolo Bergantino
Voted for you :) You can mark as accepted to reward Seb
Russ Cam
@Richard: glad I could help :)Guys, thanks for your comments to mark as accepted :D
Seb
Thanks for the tips! Loving StackOverflow!
rgeorge
+2  A: 

I'm not sure if you are doing this intentionally, but you don't have to traverse down each child down to the input. Unless you have a reason for doing so, this is just as good:

var rows = $('tr.item:has(input:text[value!=''])');

Also note that the jQuery documentation suggests you preface :text with input as leaving it out is equal to *:text which is a very slow selector.

Paolo Bergantino
Awesome - great tips Paolo! Thanks.
rgeorge