How to Create the Updatable Table with Vanilla JS
Tags: javascript, codenewbie, beginners
Published: 2021-03-16 12:10:01

This is how I created the updatable table with Vanilla JavaScript.  I also share the issue that I encountered.

# What I created
I created the "Menu Management System" app, which enables a cafe or a restaurant to easily update its menu. (It could be great if the print function is added)
![Demo Capture](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tht7r6atun3ojq19eqel.png)You can see [the demo movie](https://youtu.be/VFDAhXn6_lU) and [the code](https://github.com/shiv-chan/Projects/tree/main/%238).

# How It Works
First, set an empty table in HTML and create the default array in JavaScript.
```javascript
let food = [
	{
		name: 'French Toast',
		price: 7.99,
		popularity: '★★',
	},
	{
		name: 'Hawaiian Pancake',
		price: 9.99,
		popularity: '★★★',
	},
	{
		name: 'Omelet',
		price: 5.99,
		popularity: '★★',
	}
];
```
Then, when the page is loaded the following function executes to show the default version of the table.
```javascript
const tBody = document.querySelector('tbody');

function updateTable() {
	const tableData = food
		.map((item) => {
			return `
    <tr>
    <td>${item.name}</td>
    <td>$${item.price}</td>
    <td>${item.popularity}</td>
    <td><i class="fas fa-times-circle"></i></td>
    </tr>
    `;
		})
		.join('');

  tBody.innerHTML = tableData;
}
```
When a new item is added by clicking the "Add Item" button, push the new item to `food` array. Then, update the whole table. The function is below.
```javascript
const addBtn = document.querySelector('.btn-outline-primary');

function addItem() {
	const name = document.querySelector('#name');
	const price = document.querySelector('#price');
	const popularity = document.querySelector('#popularity');
    const obj = {};
  if(name.value !== '' && price.value !== '' && popularity.value !== ''){
    obj.name = name.value;
    obj.price = price.value;
    obj.popularity = popularity.value;
    food.push(obj);
    updateTable(); //update the table once again here.
    name.value = '';
    price.value = '';
    popularity.value = 'Select Popularity';
  }
}

addBtn.addEventListener('click', addItem);
```
To delete all items, I first came up with creating the loop function that goes through(loops over) all `<tr>` nested in `<tBody>` and remove all.

...and this is where I got stuck!

# Issue!!!
For the "Clear All" button, I simply created the following loop function.
```javascript
const tBody = document.querySelector('tbody');
const tableRows = tBody.getElementsByTagName('tr');

function clearAllItem() {
  for(let i = 0; i < tableRows.length; i++){
    tableRows[i].remove();
  }
  food = [];
}
```
However, it deletes some of the rows; **not all of them**.
It looked like this.
![Error Table](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7dzr4bpecebd7qa1kj70.png)This has to do with the way for-loop iteration behaves.

With the code above, the function `clearAllItem` runs the following ways.

**1. First-time run**
 - Table at the moment

| CHOICE       | PRICE | POPULARITY |
|--------------|-------|------------|
| French Toast | $7.99 | ★★         |
| Hawaiian Pancake    | $9.99 | ★★★        |
| Omelet   | $5.55 | ★★         |

- `i` = 0
- `tableRows.length` = 3
- `i` is less than `tableRows.length`

The function executes `tableRows[0].remove();`, then "French Toast" row and its data is gone.

**2. Second-time run**
 - Table at the moment

| CHOICE       | PRICE | POPULARITY |
|--------------|-------|------------|
| Hawaiian Pancake    | $9.99 | ★★★        |
| Omelet   | $5.55 | ★★         |

- `i` = 1
- `tableRows.length` = 2
- `i` is less than `tableRows.length`

The function executes `tableRows[1].remove();`, then "Omelet" row and its data is gone.

**3. Third-time run**
 - Table at the moment

| CHOICE       | PRICE | POPULARITY |
|--------------|-------|------------|
| Hawaiian Pancake    | $9.99 | ★★★        |

- `i` = 3
- `tableRows.length` = 1
- `i` is greater than `tableRows.length` ❌

The function won't execute any and the loop stops here.

The "Hawaiian Pancake" row still remains.

# Solution

To avoid the problem, I set the for-loop backward.

```javascript
function clearAllItem() {
  for(let i = tableRows.length - 1; i >= 0; i--){
    tableRows[i].remove();
  }
  food = [];
}
```

Let's break this down.

**1. First-time run**
 - Table at the moment

| CHOICE       | PRICE | POPULARITY |
|--------------|-------|------------|
| French Toast | $7.99 | ★★         |
| Hawaiian Pancake    | $9.99 | ★★★        |
| Omelet   | $5.55 | ★★         |

- `tableRows.length` = 3
- `i` = `tableRows.length` - 1 = 2
- `i` is greater than 0

The function executes `tableRows[2].remove();`, then "Omelet" row and its data is gone.

**2. Second-time run**
 - Table at the moment

| CHOICE       | PRICE | POPULARITY |
|--------------|-------|------------|
| French Toast | $7.99 | ★★         |
| Hawaiian Pancake    | $9.99 | ★★★        |

- `tableRows.length` = 2
- `i` = `tableRows.length` - 1 = 1
- `i` is greater than 0

The function executes `tableRows[1].remove();`, then "Hawaiian Pancake" row and its data is gone.

**2. Third-time run**
 - Table at the moment

| CHOICE       | PRICE | POPULARITY |
|--------------|-------|------------|
| French Toast | $7.99 | ★★         |

- `tableRows.length` = 1
- `i` = `tableRows.length` - 1 = 0
- `i` is equal to 0

The function executes `tableRows[0].remove();`, then "French Toast" row and its data is gone.

Now, all items are gone🎉🎉

This would be a good solution when dealing with elements of a live HTML collection.

---

This one is a very simple app, but storing data to local storage or database makes this app more functioning for use in practice!