why does parentNode replace all elements of td and not the ones specified?

156 Views Asked by At

Hi!

Can someone take a look at my code and tell me what's wrong? (No I do not have access to edit the HTML.)

Im trying to put id="goToThis" on the first parent that matches v(weekNumber) which is v2 in this case.

Problem: It sets it on every parent and not only those which match "goToweek".

I want it to only add "goToThis" on the first matching one.

Javascript(RESULT = "2019, 2"):

function setAttributes()
{ 

    var goToweek = "<td>v" + result[1] + "</td>"
        elementos = document.body.getElementsByTagName("td");

    for (var is = 0, length = elementos.length; is < length; is++)
    {   

        for (var cc in goToweek)
        {
            if (elementos[is].innerHTML.indexOf(goToweek[cc]) !== -1)
            {   

                parentOfTds2 = (elementos[is]).parentNode;
                parentOfTds2.setAttribute("id", "goToThis");
            }
        };
    };
}

Example HTML:

<tr>
  <td>2016</td>
  <td>v2</td>
</tr>
<tr>
  <td>2016</td>
  <td>v4</td>
</tr>
<tr>
  <td>2016</td>
  <td>v5</td>
</tr>
<tr>
  <td>2016</td>
  <td>v6</td>
</tr>
<tr>
  <td>2016</td>
  <td>v7</td>
</tr>
<tr>
  <td>2016</td>
  <td>v8</td>
</tr>
<tr>
  <td>2016</td>
  <td>v22</td>
</tr>........

After Code Execute::

<tr id="goToThis">
  <td>2016</td>
  <td>v2</td>
</tr>
<tr id="goToThis">
  <td>2016</td>
  <td>v4</td>
</tr>
<tr id="goToThis">
  <td>2016</td>
  <td>v5</td>
</tr>
<tr id="goToThis">
  <td>2016</td>
  <td>v6</td>
</tr>
<tr id="goToThis">
  <td>2016</td>
  <td>v7</td>
</tr>
<tr id="goToThis">
  <td>2016</td>
  <td>v8</td>
</tr>
<tr id="goToThis">
  <td>2016</td>
  <td>v22</td>
</tr>........

I want:

<tr id="goToThis">
  <td>2016</td>
  <td>v2</td>
</tr>
<tr>
  <td>2016</td>
  <td>v4</td>
</tr>
<tr>
  <td>2016</td>
  <td>v5</td>
</tr>
<tr>
  <td>2016</td>
  <td>v6</td>
</tr>
<tr>
  <td>2016</td>
  <td>v7</td>
</tr>
<tr>
  <td>2016</td>
  <td>v8</td>
</tr>
<tr>
  <td>2016</td>
  <td>v22</td>
</tr>........
2

There are 2 best solutions below

8
Bargros On BEST ANSWER

Here is a quick solution I whipped up.

function setAttributes() { 
   const elementos = document.getElementsByTagName("tr");
   for (let is = 0; is < elementos.length; is++) { 
      const innerElements = elementos[is].children;
      if (innerElements[0].innerHTML === (""+result[0]) && innerElements[1].innerHTML === ("v"+result[1])) {   
          elementos[is].id = "goToThis";
          break;
      }
   }
}

The problem I found from your example is that even if you compared the innerHTML of the element against goToWeek how would you be sure that the td for the year is the same as the year in you result array?

To avoid this instead of fetching all td I got all tr elements and checked that the year and week match and add the id to the corresponding tr parent and break out of the loop. This should attach goToThis to the first element matching the year and week.

4
Vadim Hulevich On

[].forEach.call(document.querySelectorAll("td"), function(el, ind, arr) { // in this string we give all td elements and iterate they
    if (el.textContent === "v2" && !arr._mutching) { // search match element and watch flag
        el.parentNode.id = "goToThis"; // set for paren id
        arr._mutching = true; set flag for break all cycle
    }else{
        return;
    }
});
    <table>
        <tr>
            <td>2016</td>
            <td>v2</td>
        </tr>
        <tr>
            <td>2016</td>
            <td>v4</td>
        </tr>
        <tr>
            <td>2016</td>
            <td>v5</td>
        </tr>
        <tr>
            <td>2016</td>
            <td>v2</td>  <!-- will not mutch -->
        </tr>
        <tr>
            <td>2016</td>
            <td>v7</td>
        </tr>
        <tr>
            <td>2016</td>
            <td>v8</td>
        </tr>
        <tr>
            <td>2016</td>
            <td>v22</td>
        </tr>
    </table>