Vitaliy Povestev
Vitaliy Povestev

Reputation: 3

Why i keep getting the same value for every iteration

I have a table which contains some text values. The main problem is that I have to first get them and then turn them into an array, so I've made a loop, checking for values in the table and when i try to get their content, it returns the same number. Here's some code example

HTML

<table id="my-table">
  <tr id="default-row">
    <td class = "cell" contenteditable="true">3</td>
    <td class = "cell" contenteditable="true">10</td>
    <td class = "cell" contenteditable="true">56</td>
    <td class = "cell" contenteditable="true">3</td>
  </tr>
  <tr>
    <td class = "cell" contenteditable="true">3</td>
    <td class = "cell" contenteditable="true">5</td>
    <td class = "cell" contenteditable="true">3</td>
    <td class = "cell" contenteditable="true">4</td>
  </tr>
  <tr>
    <td class = "cell" contenteditable="true">5</td>
    <td class = "cell" contenteditable="true">6</td>
    <td class = "cell" contenteditable="true">7</td>
    <td class = "cell" contenteditable="true">8</td>
  </tr>
  <tr>
    <td class = "cell" contenteditable="true">12</td>
    <td class = "cell" contenteditable="true">6</td>
    <td class = "cell" contenteditable="true">7</td>
    <td class = "cell" contenteditable="true">3</td>
  </tr>
</table>

JS

const cellValues = []

var table = document.getElementById("my-table");
//iterate trough rows
for(var i = 0, row; row = table.rows[i]; i++) {
  //iterate trough columns
  for(var j = 0, col; col = row.cells[j]; j++) {
    cellValues.push(document.querySelector(".cell").textContent)
    //get text value of the cell
  }
}
console.log(cellValues)

Upvotes: 0

Views: 266

Answers (3)

Ro Milton
Ro Milton

Reputation: 2526

As mentioned by other answers, the issue is document.querySelector() is selecting the first cell every time.

Another approach is to use .reduce() and .map()

const table = document.getElementById("my-table");
const cells = [...table.rows].reduce((acc, row) => [
  ...acc,
  ...[...row.cells].map(cell => cell.textContent)
],[]);
console.log(cells)
<table id="my-table">
  <tr id="default-row">
    <td class = "cell" contenteditable="true">3</td>
    <td class = "cell" contenteditable="true">10</td>
    <td class = "cell" contenteditable="true">56</td>
    <td class = "cell" contenteditable="true">3</td>
  </tr>
  <tr>
    <td class = "cell" contenteditable="true">3</td>
    <td class = "cell" contenteditable="true">5</td>
    <td class = "cell" contenteditable="true">3</td>
    <td class = "cell" contenteditable="true">4</td>
  </tr>
  <tr>
    <td class = "cell" contenteditable="true">5</td>
    <td class = "cell" contenteditable="true">6</td>
    <td class = "cell" contenteditable="true">7</td>
    <td class = "cell" contenteditable="true">8</td>
  </tr>
  <tr>
    <td class = "cell" contenteditable="true">12</td>
    <td class = "cell" contenteditable="true">6</td>
    <td class = "cell" contenteditable="true">7</td>
    <td class = "cell" contenteditable="true">3</td>
  </tr>
</table>

Upvotes: 0

Anuga
Anuga

Reputation: 2828

Keep it simple and clean. Just reuse the previous const's. This way, you can add check up's if needed, and know what row your on.

const cellValues = []

const table = document.getElementById("my-table");
//iterate trough rows
for (let i = 0; i <= table.rows.length - 1; i++) {
  // iterate trough columns
  for (let j = 0; j <= table.rows[i].cells.length - 1; j++) {
    // get text value of the cell
    cellValues.push(table.rows[i].cells[j].textContent)
  }
}
console.log(cellValues)
<table id="my-table">
  <tr id="default-row">
    <td class="cell" contenteditable="true">3</td>
    <td class="cell" contenteditable="true">10</td>
    <td class="cell" contenteditable="true">56</td>
    <td class="cell" contenteditable="true">3</td>
  </tr>
  <tr>
    <td class="cell" contenteditable="true">3</td>
    <td class="cell" contenteditable="true">5</td>
    <td class="cell" contenteditable="true">3</td>
    <td class="cell" contenteditable="true">4</td>
  </tr>
  <tr>
    <td class="cell" contenteditable="true">5</td>
    <td class="cell" contenteditable="true">6</td>
    <td class="cell" contenteditable="true">7</td>
    <td class="cell" contenteditable="true">8</td>
  </tr>
  <tr>
    <td class="cell" contenteditable="true">12</td>
    <td class="cell" contenteditable="true">6</td>
    <td class="cell" contenteditable="true">7</td>
    <td class="cell" contenteditable="true">3</td>
  </tr>
</table>

Upvotes: 0

CherryDT
CherryDT

Reputation: 29011

You are not using i and j inside of your loops at all, you always just query the first .cell.

You could do something like table.querySelector('tr')[0].querySelector('.cell')[j] but it's probably easier to use the col variable that you already have - which is exactly the element you are looking for!

var table = document.getElementById("my-table");
//iterate trough rows
for (var i = 0, row; row = table.rows[i]; i++) {
  //iterate trough columns
  for (var j = 0, col; col = row.cells[j]; j++) {
    cellValues.push(col.textContent)
    //get text value of the cell
  }
}
console.log(cellValues)

Alternatively, if you aren't interested in i, j or row much, you could just iterate over all the .cells:

const cellValues = [...document.querySelectorAll('.cell')]
  .map(cell => cell.textContent)

Upvotes: 2

Related Questions