2

Image i have table like this :

<table>
    <tr>
        <td>Adresse IP</td>
        <td class='tdSoap'>10.2.3.4</td>
    </tr>
    <tr>
        <td>Zobi</td>
        <td class='tdSoap'>blabla</td>
    </tr>
    <tr>
        <td>Adresse</td>
        <td class='tdSoap'>NYC</td>
    </tr>
</table>

I want get the "NYC" value, by selecting the TR what has a TD with "Adresse", but NOT with "Adresse IP".

I already do what I want with this code :

$("table tr:has(td:contains('Adresse'))").not(":contains(Adresse\u00a0IP)").find("td.tdSoap").text();

But, I tried a lot with this kind of code, and never succeed :

$("table tr:has(td:contains('Adresse'):not(':contains(Adresse\u00a0IP)')) td.tdSoap").text();

PS : "\u00a" is becaused of that http://bugs.jquery.com/ticket/3450

Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100
Gates
  • 23
  • 1
  • 4

2 Answers2

3

perhaps this:

$("table tr td:contains('Adresse')").not(':contains(Adresse\u00a0IP)').next('.tdSoap').text();

why does this not work:(what you have)

$("table tr:has(td:contains('Adresse'):not(':contains(Adresse\u00a0IP)')) td.tdSoap").text();

jQuery uses a right to left in a selector, so think this:

  1. find all td.tdSoap
  2. now find those that have not any 'Adresse\u00a0IP' - well none do inside the td.tdSoap
  3. now find those that do have 'Adresse' - well none do inside the td.tdSoap
  4. now has, combine those - still none INSIDE that td.tdSoap so nothing is selected.

Now, this also works taking out the "has" and added a next:

$("table tr td:contains('Adresse'):not(':contains(Adresse\u00a0IP)')").next("td.tdSoap").addClass('myfirst');

However, run some performance metrics and see which of these is faster:

$('table').find('tr').find('td:contains("Adresse")').not(':contains("Adresse\u00a0IP")').next('.tdSoap').text();
$('table').find('.tdSoap').prev(':contains(Adresse)').not(':contains(Adresse\u00a0IP)').next().text();
$("table tr td:contains('Adresse'):not(':contains(Adresse\u00a0IP)')").next('td.tdSoap').text();
$("table tr:has(td:contains('Adresse'))").not(":contains(Adresse\u00a0IP)").find("td.tdSoap").text();
$("table tr td:contains('Adresse')").not(':contains(Adresse\u00a0IP)').next('.tdSoap').text();

NOTE: those get the text of all of them if you have more "groups" of these, not sure you want all of them, but that is what you have.

EDIT: this works with or without the &nbsp

$('table').find('tr').find('td:contains("Adresse")').not(':contains("Adresse\u00a0IP")').not(':contains("Adresse IP")').next('.tdSoap').text();
Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100
  • FYI, I make the assumption you DO have &nbsp in the ip name thing - if you have some with, and some without that `&nbsp`, you will need to rework. I tested these using 1.9.1 jQuery and 1.6.4 – Mark Schultheiss Feb 14 '13 at 14:15
  • Thx Mark, for this answer. Makes more sense for me. But still dont understand why it works on Goram example : http://jsfiddle.net/GoranMottram/2ycvN/ – Gates Feb 14 '13 at 14:48
  • BTW, I tried with $("table tr td:contains('Adresse'):not(':contains(Adresse\u00a0IP)') + td.tdSoap") that is the same that next() (if i'm right), and it works too. – Gates Feb 14 '13 at 14:52
  • $("table tr:has(td:contains('Adresse'): td.tdSoap").text(); – Gates Feb 14 '13 at 15:00
  • It IS weird to do, but putting in .next, .find etc is often faster than a large combined selector - seems counter intuitive, but the selector code works that way - run performance tests, try to limit as fast as possible the dom traversal. That fiddle does not have the &nbsp in it - why I included an additional which filtered both. – Mark Schultheiss Feb 14 '13 at 15:03
  • Indeed, that's weird :) Thx Mark. I'll do some test to find the best way. – Gates Feb 14 '13 at 15:13
  • you are on the right track, test for performance, I used to a lot of combined selectors like that, but stopped when I had a performance issue and found the difference using .find(), .next() etc. to traverse a large complicate structure. For example "#myid div.myclass" is slower than `$("#myid").find(".myclass")` making the assumption that only the div has that class. and sometimes $(".myclass") is faster still using those assumptions - when it would seem using and id is "always use" it is NOT always faster in all cases. – Mark Schultheiss Feb 14 '13 at 15:27
0

If you can't modify the HTML, then this should do the trick:

$('table tr:has(td:contains("Adresse"):not(:contains("Adresse IP"))) td.tdSoap').text()

Otherwise I'd advise trying what Mahmood says in the comments and giving it something specific to select on.

Goran Mottram
  • 6,244
  • 26
  • 41