0

I am creating a website that generates a dynamic table on load from an array. The array is

let products = 
[
   ["product1", "Small Widget", "159753", 33, 22],
   ["product2", "Medium Widget", "258456", 55, 44],
   ["product3", "Large Widget", "753951", 77, 88],
   ["product4", "Not a Widget", "852654", 11, 2],
   ["product5", "Could be a Widget", "654456", 99, 6],
   ["product6", "Ultimate Widget", "321456", 111, 66],
   ["product7", "Jumbo Small Medium Widget", "987456", 88, 11]
   
]

The array goes: Product Name, Product Description, Product ID, Price and Inventory Amount. I need to make the table output these fields into the order of Name, ID, Description, Price and Inventory Amount, then I need to make the price field have a $ in front of the price and check the inventory amount if it is less than 20. If the inventory is less than 20 I need to change the background color of the cell. Can someone help me figure out how exactly I need to go about doing this? Here is my js file currently which only generates the table but none of the formatting I need.

let products = 
[
   ["product1", "Small Widget", "159753", 33, 22],
   ["product2", "Medium Widget", "258456", 55, 44],
   ["product3", "Large Widget", "753951", 77, 88],
   ["product4", "Not a Widget", "852654", 11, 2],
   ["product5", "Could be a Widget", "654456", 99, 6],
   ["product6", "Ultimate Widget", "321456", 111, 66],
   ["product7", "Jumbo Small Medium Widget", "987456", 88, 11]
   
]

//first create the table
function generateTableHead(table, data) {
    let thead = table.createTHead();
    let row = thead.insertRow();
    for (let key of data) {
        let th = document.createElement("th");
        let text = document.createTextNode();
        th.appendChild(text);
        row.appendChild(th);
    }
}

function generateTable(table, data) {
    for (let element of data) {
        let row = table.insertRow();
        for (key in element) {
            let cell = row.insertCell();
            let text = document.createTextNode(element[key]);
            cell.appendChild(text);
        }
    }
}
let table = document.querySelector("table");
let data = Object.keys(products[0]);
generateTable(table, products);
generateTableHead(table, data);
<!DOCTYPE html>
<html lang="en">
<head>
<title>The Sunglass Emporium </title>
   <meta charset="utf-8" />

    <link href="styles/styles.css" rel="stylesheet" type="text/css" />
    <link href="styles/reset.css" rel="stylesheet" type="text/css" />
    
    <link rel="icon" href="images/iconPic.png">
    
</head>

    <header>
    <a href="index.html"><img class="topImg" src="images/headerPic.png" alt="MUSC"/></a>
    <a href="index.html"><img class="topImg2" src="images/headerPic2.png" alt="MUSC"/></a>
    </header>
    <h1 class="titleH1"> The Sunglass Emporium </h1>
    <nav>
        <ul class="topnav1">
        <li><a class="topnav2" href="productList.html" >Product List</a></li>
        <li><a class="topnav2" href="productInfo.html" >Product Info</a></li>
        <li><a class="topnav2" href="productOrder.html" >Product Order</a></li>
        </ul>
    </nav>



<body>
    <table id="test">
    </table>
</body>



<footer>

</footer>

</html>

Can someone please help point me in the right direction? I have no idea what to change to make the table work correctly. I want to strictly use regular javascript.

2
  • 1
    Can you change the structure of your `products' or should everything be like this? Commented Sep 23, 2021 at 14:58
  • Then work with products will be easier. Just like this. let products = [ { name: "product1", description:"Small Widget", id: "159753", price: 33, amount: 22 }, {...} ] Commented Sep 23, 2021 at 15:00

2 Answers 2

1

Please find the correction that I added

  • Your table header is not bounded correctly. I created a dummy array with your required header labels and passed to your generateTableHead function
  • Inside your generateTable function, there should be some logic to differentiate "Price" and "Inventory Amount" data. I did it using the index of the array. Index 3 belongs to Price and 4 belongs to Inventory Amount.
  • So if the index is 3, append $ symbol, and if index is 4 add a background color to cell based on the value.

EDIT: If you want to have a different order, you could keep the order itself in a seperate array and process with that array as in this fiddle. Also to have the sum, select all the Inventory Amount fields from the individual array using Array.map and populate sum using some logic, I used Array.reuce for that.

Working Fiddle

// Array to keep the order of itration
const order = [0, 2, 1, 3, 4];

let products = [
  ["product1", "Small Widget", "159753", 33, 22],
  ["product2", "Medium Widget", "258456", 55, 44],
  ["product3", "Large Widget", "753951", 77, 88],
  ["product4", "Not a Widget", "852654", 11, 2],
  ["product5", "Could be a Widget", "654456", 99, 6],
  ["product6", "Ultimate Widget", "321456", 111, 66],
  ["product7", "Jumbo Small Medium Widget", "987456", 88, 11]
];

//first create the table
function generateTableHead(table, data) {
  let thead = table.createTHead();
  let row = thead.insertRow();
  for (let key of order) {
    let th = document.createElement("th");
    let text = document.createTextNode(data[key]);
    th.appendChild(text);
    row.appendChild(th);
  }
}

function generateTable(table, data) {
  for (let element of data) {
    let row = table.insertRow();
    for (key in element) {
      let cell = row.insertCell();
      const textContent = order[key] === 3 ? '$' + element[order[key]] : element[order[key]];
      let text = document.createTextNode(textContent);
      cell.appendChild(text);
      if (order[key] === 4 && element[order[key]] < 20) {
        cell.style.background = "grey";
      }
    }
  }
}

function generateTableFooter(table) {
  let row = table.insertRow();
  // My summation logic
  // Select the Inventory Amount from each array in products, which is the 5th element of array
  // `map` will generate an array with all Inventory Amount [22, 44, 88, 2, 6, 66, 11]
  // `reduce` will loop through this array and will find the sum
  const total = products.map((product) => product[4]).reduce((sum, curr) => {
    sum += curr;
    return sum;
  }, 0);
  for (let key of order) {
    let cell = row.insertCell();
    const textContent = order[key] === 4 ? total : '';
    let text = document.createTextNode(textContent);
    cell.appendChild(text);
  }
}

let table = document.querySelector("table");
const header = ["Product Name", "Product Description", "Product ID", "Price", "Inventory Amount"];
generateTable(table, products);
generateTableHead(table, header);
generateTableFooter(table);
<table id="test"></table>

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

6 Comments

how about the order of ( Name, ID, Description, Price , Inventory Amount) ?
Sonce the input is just array of arrays, the order is mandatory. If that was an object, the order was not strict
Is there a simple way to remove the $ from the Inventory amount field?
I have updated the answer. I thought you have to append $ for both price and inventory amount. Just check whether the index value is 3 for adding $ symbol
Is there a way to change this code to make the ID field the second column of the table instead of the third without changing the array itself? Also im trying to figure out how to make a total of all the Inventory amounts added together from the last field of the array. I cant find anything online about this
|
0

You have to update the Table generator function as below

function generateTable(table, data) {
    for (let element of data) {
        let row = table.insertRow();
        var cnt = 0;
        for (key in element) {
            let cell = row.insertCell();
            let text = document.createTextNode(element[key]);
            if(cnt == 3)
                text = document.createTextNode("$ "+element[key]);
            if(cnt == 4){
                if(element[key]<20)
                    cell.style.backgroundColor = "#ff0000";
            }
            cell.appendChild(text);
            cnt++;
        }
    }
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.