1

I am trying to find array values inside an element and then add a css class to it. Is my technique wrong? Can someone please help me.

var numbers = [1, 2, 3, 7, 8, 9, 10, 16, 17, 18, 19, 20];
for (numbers < 1; numbers <= 20; numbers++) {
  $('td').find(numbers).addClass('active');
}
td.active {
  color: #f00;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tr>
    <td>1
      <td>
        <td>2
          <td>
            <td>3
              <td>
                <td>4
                  <td>
                    <td>5
                      <td>
                        <td>6
                          <td>
                            <td>7
                              <td>
                                <td>8
                                  <td>
                                    <td>9
                                      <td>
                                        <td>10
                                          <td>
                                            <tr/>
                                            <tr>
                                              <td>11
                                                <td>
                                                  <td>12
                                                    <td>
                                                      <td>13
                                                        <td>
                                                          <td>14
                                                            <td>
                                                              <td>15
                                                                <td>
                                                                  <td>16
                                                                    <td>
                                                                      <td>17
                                                                        <td>
                                                                          <td>18
                                                                            <td>
                                                                              <td>19
                                                                                <td>
                                                                                  <td>20
                                                                                    <td>
                                                                                      <tr/>
</table>

Thanks in advance.

7
  • 3
    Your table HTML is broken as you can see from the formatting of the snippet - you're missing the </td> Commented Dec 14, 2018 at 13:43
  • 2
    … and <tr/> has to be replaced by </tr>. Commented Dec 14, 2018 at 13:45
  • 1
    Possible duplicate of How do I select a span containing a specific text value, using jquery? Commented Dec 14, 2018 at 13:55
  • 1
    @RoryMcCrossan HTML allows for omitting the end tag on <td> elements, even when naive tidy tools don't know that :). See stackoverflow.com/q/4020374/215552 Commented Dec 14, 2018 at 13:58
  • 2
    @HereticMonkey thanks, was not aware of that. I would argue it's terrible practice to write code in that way, though. The OP's code was incorrect either way, as they had extra unnecessary <td> where the </td> should have been. Commented Dec 14, 2018 at 13:59

3 Answers 3

4

There's several issues here. Firstly your HTML is broken. The td elements needs to be closed properly with </td>. Then the <tr /> need to be </tr>.

Secondly your for loop syntax is incorrect. numbers is a reference to the array, so using it as the iterator is going to cause odd behaviour. You instead need to define an integer and increment that. Then you can use that integer to retrieve values from numbers by index within the for loop.

Finally, find() is expecting a selector to search for child elements within the td. Instead you need to use filter() to match the text of each cell. The filter function needs to take the text of the cell and use indexOf() to determine if that value is within the array contents. Also note that when using this method you no longer need the for loop at all. Try this:

var numbers = [1, 2, 3, 7, 8, 9, 10, 16, 17, 18, 19, 20];
$('td').filter(function() {
  return numbers.indexOf(parseInt($(this).text(), 10)) != -1;
}).addClass('active');
td.active {
  color: #f00;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
  <tr>
    <td>1</td>
    <td>2</td>
    <td>3</td>
    <td>4</td>
    <td>5</td>
    <td>6</td>
    <td>7</td>
    <td>8</td>
    <td>9</td>
    <td>10</td>
  </tr>
  <tr>
    <td>11</td>
    <td>12</td>
    <td>13</td>
    <td>14</td>
    <td>15</td>
    <td>16</td>
    <td>17</td>
    <td>18</td>
    <td>19</td>
    <td>20</td>
  </tr>
</table>

Sign up to request clarification or add additional context in comments.

5 Comments

Closing tags are optional for <tr> and <td> in html5 -- "A td element’s end tag may be omitted if the td element is immediately followed by a td or th element, or if there is no more content in the parent element." w3.org/TR/html5/syntax.html
@Luke thanks was not aware of that. However, that's a terrible idea to write code without the closing tags, IMO. The OP's code was incorrect either way, as they had extra unnecessary <td> where the </td> should have been.
Wow!!!! thank you soo much Rory for the detailed explanation and with a solution. It works great. Only one issue i face with this is that, when numbers have [10, 20, 30] it also highlights [1, 2, 3]. Can you give a suggestion on that please? Apart from that it works like a charm thank you once again :)
@pv619 I can't replicate that behaviour - the snippet above will only highlight exact value matches, so 10 will not match 100 or 1000, for example
It was me, because I am trying to get the values from the URL parameter and tried to match it with the <td> element. Thank you once again for your help :)
1

As Rory said, make sure you close all elements correctly.

Try out this code. It filters out all elements with the specified numbers as inner html and sets the css class.

var numbers = [1, 2, 3, 7, 8, 9, 10, 16, 17, 18, 19, 20];
for (var i = 0; i < numbers.length; i++) {
  $('td').filter(function() { 
    return $(this).html() == numbers[i];
  }).addClass('active');
}

As you can see, you must iterate the array to get the specified values.

1 Comment

It works :) thank you Mike for your help really appreciate it.
1

If you like tiny, reusable functions like I do, here's how I would do it:

const activeNumbers = [1, 2, 3, 7, 8, 9, 10, 16, 17, 18, 19, 20];

function getNumberText($elt) {
    return parseInt($elt.text(), 10);
}

function isActiveNumber(n) {
    return activeNumbers.includes(n);
}

function updateActiveClass(elt) {
    const $elt = $(elt);
    const n = getNumberText($elt);
    $elt.toggleClass('active', isActiveNumber(n));
}

function highlightActiveCells(selector) {
    $(selector).find('td').each(function () { updateActiveClass(this); });
}

highlightActiveCells('table'); // or a better selector, like a class or id

1 Comment

Thanks Luke, for your help and really appreciate it :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.