Why does jQuery's :contains count unexpected in my code?

92 Views Asked by At

I have a function that takes two parameters: The first is a string to count, the second the id of an HTML element in which the function is supposed to count occurrances of that string.

function countString(searchString, elementToSearchIn) {
    return $("#"+elementToSearchIn+" *:contains("+searchString+")").length;
    // In this example, call will be $("#searchElement *:contains('Apple')").length;
}

<table id="searchElement" border="1">
  <tr>
    <th>Apple</th>
    <th>Apple</th>
    <th>Banana</th>
  </tr>
  <tr>
    <td>Apple</td>
    <td>Orange</td>
    <td>Banana</td>
  </tr>
</table>

I have setup a small fiddle demonstrating the problem: For example I have three times "Apple" in my table, but countString returns 6.

Why is my function not returning the correct count?

https://jsfiddle.net/v10swbff/

2

There are 2 best solutions below

2
On BEST ANSWER

The problem is *:contains is matching TD, TH AND TR. So it counts 6 (one for each TR and then the expected TH and TD counts). To fix it, you could check the TH and TD separately like so:

function countString(searchString, elementToSearchIn) {
    var thCount = $("#"+elementToSearchIn+" th:contains("+searchString+")").length;
    var tdCount = $("#"+elementToSearchIn+" td:contains("+searchString+")").length;
    return thCount + tdCount;
}

Updated JSFiddle: https://jsfiddle.net/v10swbff/1/

1
On

As Cymen said, is matching tr elements in the search. I propose another function that you can use:

function countString(searchString, elementToSearchIn) {
    return $("#"+elementToSearchIn+" tr>*:contains("+searchString+")").length;
}

By just adding the 'tr>' you'll find only the th and td. :)