尝试制作HTML表并使用相同的JSON数据填充select标签

时间:2019-01-23 17:54:13

标签: javascript jquery html json

我有一个JSON数据,我试图从中创建一个HTML表以及一个下拉列表,但是面临呈现表和下拉列表的问题。

我的JSON:

[
  {
    "Category name": "juce",
    "Category Data": [
      {
        "Item Code": "1234",
        "Item Name": "juce1",
        "Quantity": "0"
      }
    ]
  },
  {
    "Category name": "juce",
    "Category Data": [
      {
        "Item Code": "1234",
        "Item Name": "juce2",
        "Quantity": "0"
      }
    ]
  },
  {
    "Category name": "rice",
    "Category Data": [
      {
        "Item Code": "1234",
        "Item Name": "rice1",
        "Quantity": "0"
      }
    ]
  },
  {
    "Category name": "rice",
    "Category Data": [
      {
        "Item Code": "1234",
        "Item Name": "juce2",
        "Quantity": "0"
      }
    ]
  },
  {
    "Category name": "roti",
    "Category Data": [
      {
        "Item Code": "1234",
        "Item Name": "roti1",
        "Quantity": "0"
      }
    ]
  },
  {
    "Category name": "roti",
    "Category Data": [
      {
        "Item Code": "1234",
        "Item Name": "juce2",
        "Quantity": "0"
      }
    ]
  }
]

我正在尝试制作一个HTML表格,该表格外部有下拉菜单,名为Category Name。

就像我的JSON一样,我在下拉列表中有想要的类别名称,以及其他数据(如HTML表格中的数据)。

当用户单击下拉列表中的任何类别时,HTML表将仅根据该类别名称进行填充。

“数量”此字段是可编辑的,将由用户

输入

我正在尝试的代码段:

function addTable(tableData) {
  var col = Object.keys(tableData[0]);
  var countNum = col.filter(i => !isNaN(i)).length;
  var num = col.splice(0, countNum);
  col = col.concat(num);
  var table = document.createElement("table");
  var tr = table.insertRow(-1); // TABLE ROW.
  var colNum = col.length; //to improve the speed
  for (var i = 0; i < colNum + 1; i++) {
    var th = document.createElement("th"); // TABLE HEADER.
    if (i >= colNum) {
      th.innerHTML = "Quantity";
      tr.appendChild(th);
      tr.classList.add("text-center");
      tr.classList.add("head")
    } else {
      th.innerHTML = col[i];
      tr.appendChild(th);
      tr.classList.add("text-center");
      tr.classList.add("head")
    }
  }
  for (var i = 0; i < tableData.length; i++) {
    tr = table.insertRow(-1);
    for (var j = 0; j < col.length + 1; j++) {
      let tabCell = tr.insertCell(-1);
      var hiddenField = document.createElement("input");
      hiddenField.style.display = "none";
      var tabledata = tableData[i][col[j]];
      if (i > -1 && j >= colNum) {
        var quantityField = document.createElement("input");
        quantityField.style.border = "none";
        quantityField.style["text-align"] = "center";
        quantityField.setAttribute('name', 'Quantity');
        quantityField.setAttribute('autocomplete', 'on');
        quantityField.setAttribute('value', '0');
        quantityField.setAttribute('type', 'number');
        quantityField.setAttribute('required', 'required');
        quantityField.classList.add("dataReset");
        tabCell.appendChild(quantityField);
      } else {
        if (tableData[i]['Item Code'] === tableData[i][col[j]]) {
          tabCell.innerHTML = tabledata;
          hiddenField.setAttribute('name', 'Item_Code');
          hiddenField.setAttribute('value', tabledata);
          tabCell.appendChild(hiddenField);
        }
        if (tableData[i]['Item Name'] === tableData[i][col[j]]) {
          tabCell.innerHTML = tabledata;
          hiddenField.setAttribute('name', 'Item_Name');
          hiddenField.setAttribute('value', tabledata);
          tabCell.appendChild(hiddenField);
        }
        if (j > 1)
          tabCell.classList.add("text-right");
      }
    }
  }
  var divContainer = document.getElementById("HourlysalesSummary");
  divContainer.innerHTML = "";
  divContainer.appendChild(table);
  table.classList.add("table");
  table.classList.add("table-striped");
  table.classList.add("table-bordered");
  table.classList.add("table-hover");
}
addTable(tableData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="www.google.com" id="form1">
  <div class="row position-relative">
    <div class="col-lg-4">
      <h5 id="commonHeader">Category</h5>
      <select class="test" id="CategoryName" name="categoryCode">
        <option>All</option> <!-- this also i want to populate with the JSON DATA not statically,except All -->
        <option>juce</option>
        <option>rice</option>
        <option>roti</option>
      </select>
    </div>
  </div>
  <hr style="border: 1px solid black">
  <div class="table-responsive">
    <table class="w-100" id=HourlysalesSummary></table>
  </div>
  <div>
    <button type="submit" id="save">
      <i class="fas fa-save"></i> Save
    </button>
  </div>
</form>

但是我没有得到结果。

我只有一个JSON,我想做所有事情来填充下拉列表,并且当用户选择“类别”来填充表时也要进行过滤。

2 个答案:

答案 0 :(得分:0)

明智的选择一个实用程序库(例如Underscore或Lodash),以使数组操作更容易一些。在此示例中,我使用了Lodash。

var data = []/ //enter your array of data here instead of empty array
var dataArray = []; //this will hold a collection of Category Names
for (datum of data) {
   console.log(datum);
   dataArray.push(datum["Category name"]);
}
uniqueArrayForDropdown = _.sortedUniq(dataArray); //only save unique category names

现在,当有人选择类别名称时,您可以使用以下函数过滤data对象(此处将rice设置为静态,但您可以将其更改为所选的值从下拉列表中):

//this is the simple example with static data
data.filter(function(item) {return item["Category name"] === "rice";})

您可以通过设置创建类似于以下内容的函数并设置更改事件以执行filterSelection()来应用它:

// this is a dynamic function that reads the selected value from the
// DOM and applies the filter accordingly
function filterSelection() {
   var e = document.getElementById("CategoryName");
   var selectedCategory = e.options[e.selectedIndex].value;
   var filteredData = data.filter(function(item) {return item["Category name"] === selectedCategory;})

   drawTable(filteredData); //you need to write the drawTable method
}

只要表逻辑正确,就可以绘制filteredData数组; filteredData包含与过滤条件匹配的data个对象的子集。

答案 1 :(得分:0)

对于该项目,最好分步骤进行。我看到一些步骤:

  • 通过数据键创建表头
  • 从数据创建表主体
  • 从类别名称(唯一)更新过滤器选项

请考虑以下代码。

var tData = [{
    "Category name": "juce",
    "Category Data": [{
      "Item Code": "1234",
      "Item Name": "juce1",
      "Quantity": "0"
    }]
  },
  {
    "Category name": "juce",
    "Category Data": [{
      "Item Code": "1234",
      "Item Name": "juce2",
      "Quantity": "0"
    }]
  },
  {
    "Category name": "rice",
    "Category Data": [{
      "Item Code": "1234",
      "Item Name": "rice1",
      "Quantity": "0"
    }]
  },
  {
    "Category name": "rice",
    "Category Data": [{
      "Item Code": "1234",
      "Item Name": "juce2",
      "Quantity": "0"
    }]
  },
  {
    "Category name": "roti",
    "Category Data": [{
      "Item Code": "1234",
      "Item Name": "roti1",
      "Quantity": "0"
    }]
  },
  {
    "Category name": "roti",
    "Category Data": [{
      "Item Code": "1234",
      "Item Name": "juce2",
      "Quantity": "0"
    }]
  }
];

$(function() {
  function getCatNames(arr) {
    var names = [];
    $.each(arr, function(key, obj) {
      names.push(obj['Category name']);
    });
    var unique = names.filter((v, i, a) => a.indexOf(v) === i);
    return unique;
  }

  function updateFilter(obj, d) {
    var catOpts = getCatNames(d);
    obj.html("");
    obj.append("<option>All</option>");
    $.each(catOpts, function(k, v) {
      $("<option>").html(v).appendTo(obj);
    });
  }

  function filterSelection(obj) {
    var s = $("#CategoryName option:selected").val();
    if (s == "All") {
      $("tbody tr", obj).show();
      return;
    }
    $("tbody tr", obj).each(function(ind, el) {
      var cat = $("td:eq(0)", el).text().trim();
      if (cat != s) {
        $(el).hide();
      } else {
        $(el).show();
      }
    });
  }

  function makeTableHead(obj, data) {
    if (obj.find("thead").length === 0) {
      $("<thead>").prependTo(obj);
    }
    var row = $("<tr>").appendTo($("thead", obj));
    $.each(data[0], function(k, v) {
      console.log(k, v);
      if (k == "Category name") {
        $("<th>", {
          class: "text-center head"
        }).html(k).appendTo(row);
      } else {
        $.each(v[0], function(j, x) {
          $("<th>", {
            class: "text-center head"
          }).html(j).appendTo(row);
        });
      }
    });
  }

  function makeTableBody(obj, data, qnty) {
    if (qnty == undefined) {
      qnty = true;
    }
    if (obj.find("tbody").length === 0) {
      $("<tbody>").appendTo(obj);
    }
    $.each(data, function(k, v) {
      var row = $("<tr>", {
        class: "item-" + k
      }).appendTo($("tbody", obj));
      var n = $("<td>", {
        class: "text-center cat-name"
      }).html(v['Category name']).appendTo(row);
      $("<input>", {
        type: "hidden",
        name: "cat-name[]",
        value: v['Category name']
      }).appendTo(n);
      var itc = $("<td>", {
        class: "text-center item-code"
      }).appendTo(row);
      itc.html(v['Category Data'][0]['Item Code']);
      $("<input>", {
        type: "hidden",
        name: "item_code",
        value: v['Category Data'][0]['Item Code']
      }).appendTo(itc);
      var itn = $("<td>", {
        class: "text-center item-name"
      }).appendTo(row);
      itn.html(v['Category Data'][0]['Item Name']);
      $("<input>", {
        type: "hidden",
        name: "item_name",
        value: v['Category Data'][0]['Item Name']
      }).appendTo(itn);
      if (qnty) {
        var q = $("<td>", {
          class: "cat-qnty"
        }).appendTo(row);
        $("<input>", {
          name: "Quantity",
          autocomplete: "on",
          value: v['Category Data'][0].Quantity,
          type: "number",
          class: "dataReset"
        }).css({
          border: "none",
          "text-align": "center",
          width: "4em"
        }).appendTo(q);
      }
    });
  }

  function addTable(tableData, tbl) {
    if (tbl == undefined) {
      tbl = $("<table>", {
        id: "HourlysalesSummary"
      });
    }
    //var col = Object.keys(tableData[0]);
    //var countNum = col.length;
    makeTableHead(tbl, tableData);
    makeTableBody(tbl, tableData);
    var divContainer = $("#HourlysalesSummary").parent();
    divContainer.html(tbl);
    tbl.addClass("table table-striped table-bordered table-hover");
  }

  updateFilter($("#CategoryName"), tData);
  addTable(tData, $("#HourlysalesSummary"));

  $("#CategoryName").change(function() {
    filterSelection($("#HourlysalesSummary"));
  });
});
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="www.google.com" id="form1">
  <div class="row position-relative">
    <div class="col-lg-4">
      <h5 id="commonHeader">Category</h5>
      <select class="test" id="CategoryName" name="categoryCode">
        <option>All</option>
        <option>juce</option>
        <option>rice</option>
        <option>roti</option>
      </select>
    </div>
  </div>
  <hr style="border: 1px solid black">
  <div class="table-responsive">
    <table class="w-100" id="HourlysalesSummary">
      <thead></thead>
      <tbody></tbody>
    </table>
  </div>
  <div>
    <button type="submit" id="save"><i class="fas fa-save"></i> Save</button>
  </div>
</form>

如您所见,我创建了以下功能:

  • addTable( data )
    • makeTableHead( object, data, quantity )
    • makeTableBody( object, data, quantity )
  • updateFilter( object, data )
    • getCatNames( data )
    • filterSelection( object )

使用<thead><tbody>可以在您具有更多动态表主体内容时有所帮助。如果您进行更改或加载新数据,则可能只需要对新数据运行makeTableBody($("#HourlysalesSummary"), tData);

我将很多代码切换到了jQuery。如果可能的话,我不喜欢混合。这也使我们可以更多地使用$.each(),这对数组和对象数据确实很有帮助。

希望这会有所帮助。