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.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
pv619
  • 409
  • 11
  • 29
  • 3
    Your table HTML is broken as you can see from the formatting of the snippet - you're missing the `` – Rory McCrossan Dec 14 '18 at 13:43
  • 2
    … and `` has to be replaced by ``. – Takit Isy Dec 14 '18 at 13:45
  • 1
    Possible duplicate of [How do I select a span containing a specific text value, using jquery?](https://stackoverflow.com/questions/9424417/how-do-i-select-a-span-containing-a-specific-text-value-using-jquery) – Heretic Monkey Dec 14 '18 at 13:55
  • 1
    @RoryMcCrossan HTML allows for omitting the end tag on `` elements, even when naive tidy tools don't know that :). See https://stackoverflow.com/q/4020374/215552 – Heretic Monkey Dec 14 '18 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 `` where the `` should have been. – Rory McCrossan Dec 14 '18 at 13:59
  • 1
    Although I suspect @pv619 has made an error in the html (`` is obviously an error), having closing tags for tr and td are not required in html5. – Luke Dec 14 '18 at 13:59
  • Thank you @RoryMcCrossan and Takit for spotting it out :) Sorry Heretic if was similar and Luke thanks you for the information, i was aware of it :) – pv619 Dec 14 '18 at 14:12

3 Answers3

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>
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
  • 2
    Closing tags are optional for `` and `` 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." https://www.w3.org/TR/html5/syntax.html – Luke Dec 14 '18 at 13:56
  • 1
    @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 `` where the `` should have been. – Rory McCrossan Dec 14 '18 at 13:58
  • 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 Dec 14 '18 at 14:10
  • 1
    @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 – Rory McCrossan Dec 14 '18 at 14:18
  • It was me, because I am trying to get the values from the URL parameter and tried to match it with the element. Thank you once again for your help :) – pv619 Dec 14 '18 at 14:33
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.

MightyMike
  • 64
  • 4
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
Luke
  • 18,811
  • 16
  • 99
  • 115