3

I have a table that contains comma separated lists of numbers like this: <td>72,76,81</td>. I'm trying to select the table cells that don't contain a particular number. This selector worked:

$("td:not(:contains('76'))", $table)

The issue is that there may be rows that contain '576' or '761', etc.

To solve that issue, I decided to put a <span> around each number, so that it's now: <td><span>72</span>,<span>76</span>,<span>81</span></td>. My selector is now:

$("td:not(:contains('<span>76</span>'))", $table)

When I debug this selector in Firebug, it's is returning some span tag that doesn't actually exist in the HTML source, instead of the correct <td>s.

Basically, putting the '<span>' in the :contains() string is breaking the selector. Is there any selector similar to :contains() that will work properly when HTML is passed to it? Or is there some way I can select by the entire string inside the <span>?

BTW, this site is using jquery 1.3.2.

jessica
  • 3,051
  • 2
  • 30
  • 31

6 Answers6

5

If you want to stick with <span>s, this works, even with jQuery 1.3.2:

var $tds = $("table td").filter(function() {
    return !$(this).find('span').filter(function () {
        return $(this).text() === '76';
    }).length;
});

http://jsfiddle.net/mattball/PFk8H/


On the other hand, it's actually really easy if you want to go back to the old markup:

var $tds = $("table td").filter(function() {
    return !$(this).text().match(/\b76\b/);
});

http://jsfiddle.net/mattball/L6AFz/


To use a variable in the regex, use the new RegExp(string) constructor syntax:

var n = 76,
    re = new RegExp("\\b" + n + "\\b");

var $tds = $("table td").filter(function() {
    return !$(this).text().match(re);
});

http://jsfiddle.net/mattball/hKQH7/

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • 2
    please simplify regex like this `match(/\b76\b/)` meaning word boundary either side of 76 – Billy Moon Apr 06 '11 at 19:15
  • Option 2 here looks to me to be the best answer because it reduces the number of DOM elements. :) Problem, though, I am trying to pass a variable to the match() statement (obviously I'm not always looking for the number 76). `$(this).text().match('\b' + val + '\b')'` is returning undefined for me.. any ideas why? BTW I used this answer to put a variable in my regexp -- doesn't seem to be working http://stackoverflow.com/questions/1695633/how-to-pass-a-variable-into-regex-in-jquery-javascript/1695653#1695653 – jessica Apr 06 '11 at 19:49
2

try this:

$("td span:not(:contains('76'))", $table).parent()

$("td span", $table).filter(function(){return $(this).text() != '76';}).parent()
manji
  • 47,442
  • 5
  • 96
  • 103
1

You may not be able to use :contains for this. As you've stated :contains('76') will match '76', '576', '761', etc. You can try using .filter to get what you want.

$('td:has("span")').filter(function(){
    var x = true;
    $('span', this).each(function(){
        x = x && $(this).text() != '76';
    });
    return x;
});

Demo: http://jsfiddle.net/KvK3J/

gen_Eric
  • 223,194
  • 41
  • 299
  • 337
1

Tested with jQuery 1.2.6

http://jsfiddle.net/G27JF/4/


$("td>span").filter(function() { 
    return ($(this).text() != 76);
}).parent().css("text-decoration", "underline");

johnlemon
  • 20,761
  • 42
  • 119
  • 178
0

I would use a regular expression to match the insides of the table row. First iterate over all the elements then ignore the ones that match the regex

Here is a basic one that will match:

/^76$/g

check out RegExr to build more regex.

babsher
  • 1,016
  • 2
  • 8
  • 11
0

To avoid the 'Contains' issue, you would make them as classes:

<span class="76"></span>

And:

$("td:not(:has(span.76)"), $table)

This could be adjusted to have multiples in 1 object too as:

<span class="76 77 78"></span>

Or even put in the TD itself simplifying the selector even more

$("td:not(.76 .77, $table)
MacAnthony
  • 4,471
  • 2
  • 23
  • 26
  • This would still match '576' and '761'. – gen_Eric Apr 06 '11 at 18:47
  • Unfortunately I can't convert the values to classes, because all of the cells in the table are output by the same PHP loop, and some of the cells contain product names, which might be lengthy, contain quotes, etc. – jessica Apr 06 '11 at 18:55