Avmeade
Avmeade

Reputation: 11

Generate table with array

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.

Upvotes: 0

Views: 347

Answers (2)

Nitheesh
Nitheesh

Reputation: 19986

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>

Upvotes: 1

Subhashis Pandey
Subhashis Pandey

Reputation: 1538

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++;
        }
    }
}

Upvotes: 0

Related Questions