How to make HTML table expand on click?

前端 未结 6 1854
渐次进展
渐次进展 2020-12-06 05:05

I am rendering HTML table with the help of JavaScript. I have made the table successfully, but now I have one requirement to show some new data in a row like on click expand

6条回答
  •  一整个雨季
    2020-12-06 05:48

    To achieve expected result, use below option of creating new table inside clicked td

    1. On Click of plus icon, get the brand name
    2. Filter items from data using brandname
    3. Creating table with items for that brand
    4. Hiding items row on selecting other row using class-itemsRow
    5. On Clicking already selecting , remove style display: none , instead of re-creating table

    function format(number, decimals = 2, locale = 'en-in') {
      const fixed = parseInt(number).toFixed(decimals);
      const [int, dec] = fixed.split('.')
      const intFormatted = (+int).toLocaleString(locale)
      return intFormatted + (dec ? '.' + dec : '');
    }
    var data = [{
        "outlet": "JAYANAGAR",
        "brandname": "Bakery FG",
        "itemname": "Khara Boondhi-L",
        "transactionType": "TransferIn",
        "netamount": 980
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Bakery FG",
        "itemname": "Samosa-L",
        "transactionType": "TransferIn",
        "netamount": 130
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Bakery FG",
        "itemname": "Corn Flakes Masala-L",
        "transactionType": "TransferIn",
        "netamount": 500
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Pastry & Cake FG",
        "itemname": "Plum Cake 250gm",
        "transactionType": "TransferIn",
        "netamount": 110
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Pastry & Cake FG",
        "itemname": "Butterscotch Cake",
        "transactionType": "TransferIn",
        "netamount": 720
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Pastry & Cake FG",
        "itemname": "Chocolate chips cake",
        "transactionType": "TransferIn",
        "netamount": 40000
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Pastry & Cake FG",
        "itemname": "Mango Delight Cake",
        "transactionType": "TransferIn",
        "netamount": 14000
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Pastry & Cake FG",
        "itemname": "Almond Honey Chocolate Cake",
        "transactionType": "TransferIn",
        "netamount": 500
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Pastry & Cake FG",
        "itemname": "Peach Cake",
        "transactionType": "TransferIn",
        "netamount": 5500
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Pastry & Cake FG",
        "itemname": "Black Forest Cake",
        "transactionType": "TransferIn",
        "netamount": 1000
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Ice Cream FG",
        "itemname": "Chocolate Crazy Boom",
        "transactionType": "TransferIn",
        "netamount": 2360
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Ice Cream FG",
        "itemname": "Hot Chocolate Fudge",
        "transactionType": "TransferIn",
        "netamount": 2340
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Ice Cream FG",
        "itemname": "Chocolate Sugar Free Ice-Cream",
        "transactionType": "TransferIn",
        "netamount": 1000
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Ice Cream FG",
        "itemname": "Kesar Badam Falooda",
        "transactionType": "TransferIn",
        "netamount": 4430
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Ice Cream FG",
        "itemname": "Strawberry Ice-cream",
        "transactionType": "TransferIn",
        "netamount": 1231
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Ice Cream FG",
        "itemname": "TOP- Chocochips",
        "transactionType": "TransferIn",
        "netamount": 2200
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Ice Cream FG",
        "itemname": "Cheese Cake Ice-Cream",
        "transactionType": "TransferIn",
        "netamount": 500
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Ice Cream FG",
        "itemname": "Sundae Large",
        "transactionType": "TransferIn",
        "netamount": 2350
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Ice Cream FG",
        "itemname": "Mango Ice-cream",
        "transactionType": "TransferIn",
        "netamount": 8000
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Ice Cream FG",
        "itemname": "TOP- Shooting Star",
        "transactionType": "TransferIn",
        "netamount": 2360
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Ice Cream FG",
        "itemname": "Ice Blue Sundae",
        "transactionType": "TransferIn",
        "netamount": 2340
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Ice Cream FG",
        "itemname": "Creamy Litchi Boom",
        "transactionType": "TransferIn",
        "netamount": 2200
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Ice Cream FG",
        "itemname": "Cookies Ice-cream",
        "transactionType": "TransferIn",
        "netamount": 7000
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Ice Cream FG",
        "itemname": "TOP- Wafer",
        "transactionType": "TransferIn",
        "netamount": 88000
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Ice Cream FG",
        "itemname": "Litchi cherry Sundae",
        "transactionType": "TransferIn",
        "netamount": 2440
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Ice Cream FG",
        "itemname": "Peach Malaba",
        "transactionType": "TransferIn",
        "netamount": 2230
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "Ice Cream FG",
        "itemname": "Cherry Mania Ice-Cream",
        "transactionType": "TransferIn",
        "netamount": 2700
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "North Indian FG",
        "itemname": "Fruit Mixture",
        "transactionType": "TransferIn",
        "netamount": 324
      },
      {
        "outlet": "JAYANAGAR",
        "brandname": "NA",
        "itemname": "NA",
        "transactionType": "Sales",
        "netamount": 476426
      },
      {
        "outlet": "KOLAR",
        "brandname": "NA",
        "itemname": "NA",
        "transactionType": "Sales",
        "netamount": 115313
      },
      {
        "outlet": "MALLESHWARAM",
        "brandname": "NA",
        "itemname": "NA",
        "transactionType": "Sales",
        "netamount": 92141
      }
    ]
    let formatData = function(data) {
      let brandnames = [];
      let itemnames = [];
      let outlets = [];
      data.forEach(element => {
        if (brandnames.indexOf(element.brandname) == -1 && (element.brandname) !== "NA") { //taking brandname which do not have bradname===NA
          brandnames.push(element.brandname);
        }
        if (itemnames.indexOf(element.itemname) == -1 && (element.itemname) !== "NA") { //taking itemname which do not have bradname===NA
          itemnames.push(element.itemname);
        }
        if (outlets.indexOf(element.outlet) == -1) {
          outlets.push(element.outlet);
        }
      });
      return {
        data: data,
        brandnames: brandnames,
        itemnames: itemnames,
        outlets: outlets,
      };
    };
    var totalSalesPercentage = '';
    var olWiseSalesPercentage = '';
    let renderTable = function(data) {
      brandnames = data.brandnames;
      itemnames = data.itemnames;
      outlets = data.outlets;
      data = data.data;
      let tbl = document.getElementById("ConsumptionTable");
      let table = document.createElement("table");
      let thead = document.createElement("thead");
      let headerRow = document.createElement("tr");
      let th = document.createElement("th");
    
      th = document.createElement("th");
      th.innerHTML = "Brand Name";
      th.classList.add("text-center");
      headerRow.appendChild(th);
    
      let grandTotal = 0;
      let grandNetAmount = 0;
      let outletWiseTotal = {};
      let outletWiseNetamount = {};
      th = document.createElement("th");
      th.colSpan = 2;
      th.innerHTML = "Total";
      th.classList.add("text-center");
      headerRow.appendChild(th);
    
      outlets.forEach(element => {
    
        th = document.createElement("th");
        th.colSpan = 2;
        th.innerHTML = element; // populating outlet 
        th.classList.add("text-center");
        headerRow.appendChild(th);
        outletWiseTotal[element] = 0;
        data.forEach(el => {
          if (el.outlet == element && el.brandname !== "NA") { //taking brandname which do not have bradname===NA
            outletWiseTotal[element] += parseInt(el.netamount); //here i am calculating the outletWiseTotal where transcationType==TransferIn
    
          }
          if (el.outlet == element && el.brandname == "NA" && el.transactionType == "Sales") { //taking brandname which do not have bradname===NA
            outletWiseNetamount[element] = parseInt(el.netamount) || 0
    
    
          }
    
        });
        console.log(outletWiseTotal)
        grandTotal += outletWiseTotal[element]; //then calculating grand total to populate it into  Total column at grn entery
    
        grandNetAmount += outletWiseNetamount[element] || 0
    
      });
    
      thead.appendChild(headerRow);
      headerRow = document.createElement("tr");
      th = document.createElement("th");
      th.innerHTML = "";
      headerRow.appendChild(th);
    
      for (i = 0; i < outlets.length + 1; i++) {
        th = document.createElement("th");
        th.innerHTML = "Sales";
        th.classList.add("text-center");
        headerRow.appendChild(th);
    
        th = document.createElement("th");
        th.innerHTML = "Grn Entery";
        th.classList.add("text-center");
        headerRow.appendChild(th);
      }
    
      headerRow.insertBefore(th, headerRow.children[1]);
      thead.appendChild(headerRow);
      table.appendChild(thead);
    
      headerRow = document.createElement("tr");
      td = document.createElement("th");
      td.innerHTML = "Total";
      td.classList.add("text-center");
      headerRow.appendChild(td);
      let el1 = 0;
      outlets.forEach(element => {
    
        td = document.createElement("th");
        td.innerHTML = outletWiseTotal[element].toLocaleString('en-IN');
        td.classList.add("text-right");
        headerRow.appendChild(td);
        if (element.outlet == element) {
          el1 = element.netAmount;
        }
        td = document.createElement("th");
        td.innerHTML = outletWiseNetamount[element].toLocaleString('en-IN') || 0;
        td.classList.add("text-right");
        headerRow.appendChild(td);
    
      });
      td = document.createElement("th");
      td.innerHTML = grandNetAmount.toLocaleString('en-IN');
      td.classList.add("text-right");
      headerRow.insertBefore(td, headerRow.children[1]);
    
      td = document.createElement("th");
      td.innerHTML = grandTotal.toLocaleString('en-IN');
      td.classList.add("text-right");
      headerRow.insertBefore(td, headerRow.children[1]);
      thead.appendChild(headerRow);
      table.appendChild(thead);
    
      let tbody = document.createElement("tbody");
      brandnames.forEach(element => {
        let row = document.createElement("tr");
    
        td = document.createElement("td");
        td.innerHTML = ' ' + " " + element; //creating plus font icon to make click happen
    
        row.appendChild(td);
        let total = 0;
        let totalBCount = 0;
        outlets.forEach(outlet => {
          let el = 0;
          let bc = 0;
          data.forEach(d => {
            if (d.brandname == element && d.outlet == outlet) {
              total += parseInt(d.netamount);
              el = d.netamount;
              console.log(el) //this one is populating ful data here
            }
          });
          console.log(el) //but here it is not taking cumulative sum of netamount it is only taking one amount of each brand 
          olWiseSalesPercentage = (el / outletWiseTotal[outlet]) * 100 || 0 //here doing some calculations
          td = document.createElement("td");
          td.innerHTML = el.toLocaleString('en-IN');
    
          td.classList.add("text-right");
          row.appendChild(td);
          td = document.createElement("td");
          td.innerHTML = olWiseSalesPercentage.toFixed(2) + "%";
    
          td.classList.add("text-right");
          row.appendChild(td);
        });
        totalSalesPercentage = (total / grandTotal) * 100 //here doing some calculations
        const totalSalesPercentageFix = totalSalesPercentage.toFixed(2) + "%"
        td = document.createElement("td");
        td.innerHTML = totalSalesPercentageFix;
        td.classList.add("text-right");
        row.insertBefore(td, row.children[1]);
    
        td = document.createElement("td");
        td.innerHTML = total.toLocaleString('en-IN');
        td.classList.add("text-right");
        row.insertBefore(td, row.children[1]);
        tbody.appendChild(row);
      });
      table.appendChild(tbody);
      tbl.innerHTML = "";
      tbl.appendChild(table);
      table.classList.add("table");
      table.classList.add("table-striped");
      table.classList.add("table-bordered");
      table.classList.add("table-hover");
    
    }
    let formatedData = formatData(data);
    renderTable(formatedData);
    
    function expand(e) {
      let itemsRow = document.querySelectorAll('.itemsRow');
      if(itemsRow){
        itemsRow.forEach(v => v.style.display = 'none')
      }
        let list = e.parentNode.children;
        for (v of list){
          if(v.nodeName === 'TABLE'){
          v.style.display = '';
          return
        }
        }
     
    
      let brand = e.parentNode.innerHTML.substr(e.parentNode.innerHTML.lastIndexOf('>')+1).trim()
      let table = document.createElement("table");
      table.classList.add("itemsRow");
      let tbody = document.createElement("tbody");
    
      let brandNames = data.filter(v => v.brandname === brand)
      
      brandNames.forEach(element => {
        let row = document.createElement("tr");
        for (let property in element) {
              td = document.createElement("td"); 
              td.classList.add("items");
              td.innerHTML = element[property];
             row.appendChild(td)
      }
    
        tbody.appendChild(row)
      });
      table.appendChild(tbody);
      e.parentNode.appendChild(table);
    }
    #test {
      color: green;
      cursor: pointer;
    }
    
    
    
    

    codepen - https://codepen.io/nagasai/pen/pBMgYv

提交回复
热议问题