【问题标题】:Expand and Collapse HTML Table Data Rows展开和折叠 HTML 表数据行
【发布时间】:2020-11-21 10:50:53
【问题描述】:

我一遍又一遍地遇到问题。我有一个非常可靠的 HTML 表格功能,但是因为它会包含很多数据行,所以我也想要一种简化功能的方法。我想对具有相同“程序字段”的数据行进行分组,并创建一个展开/折叠函数,该函数将隐藏/显示具有相同程序字段的所有行。

这是我的表格输出的示例。例如,有两个程序以 X 作为值我想创建一个写有“x”的行并能够单击它,它会下拉所有具有“x”值的行,如果我再次单击它将折叠他们。

这个 YouTube 视频几乎正是我想要完成的,但是很难理解,因为这个人的所有数据都是硬编码/静态的,因为我的数据是通过请求提取的。

YouTube Video of Example

这是我的代码:


<script src="/jquery-3.3.1.min.js"></script>
<script>

var webAppUrl = _spPageContextInfo.webAbsoluteUrl;

function loadData(source, url) {
  return fetch(url, { headers: { accept: "application/json; odata=verbose" } }) // make request
    .then((r) => {
      if (!r.ok) throw new Error("Failed: " + url);  // Check for errors
      return r.json();  // parse JSON
    })
    .then((data) => data.d.results) // unwrap to get results array
    .then((results) => {
      results.forEach((r) => (r.source = source)); // add source to each item
      return results;
    });
}

window.addEventListener("load", function () {
  Promise.all([
    loadData("xDeliverables", "_api/web/lists/getbytitle('xDeliverables')/items?$select=Program,To,Date,Approved,Notes,Deliverable"),
    loadData("yDeliverables", "_api/web/lists/getbytitle('yDeliverables')/items?$select=Program,To,Date,Approved,Notes,Deliverable"),
    loadData("zDeliverables", "_api/web/lists/getbytitle('zDeliverables')/items?$select=Program,To,Date,Approved,Notes,Deliverable"),
  ])
    .then(([r1, r2, r3]) => {
      const objItems = r1.concat(r2,r3);
      var tableContent =
        '<table id="deliverablesTable" style="width:100%" border="1 px"><thead><tr><td><strong>Program</strong></td>' +
        "<td><strong>To</strong></td>" +
        "<td><strong>Date Submitted</strong></td>" +
        "<td><strong>Approved</strong></td>" +
        "<td><strong>Notes</strong></td>" +
        "<td><strong>Deliverable</strong></td>" +
        "</tr></thead><tbody>";

      for (var i = 0; i < objItems.length; i++) {
        tableContent += "<tr>";
        tableContent += "<td>" + objItems[i].Program + "</td>";
        tableContent += "<td>" + objItems[i].To + "</td>";
        tableContent += "<td>" + objItems[i].Date + "</td>";
        tableContent += "<td>" + objItems[i].Approved + "</td>";
        tableContent += "<td>" + objItems[i].Notes + "</td>";
        tableContent += "<td>" + objItems[i].Deliverable + "</td>";
        tableContent += "</tr>";
      }
      $("#deliverables").append(tableContent);
    })
    .catch((err) => {
      alert("Error: " + err);
      console.error(err);
    });
});
function searchTable() {
  var input, filter, table, tr, td, i, txtValue;
  input = document.getElementById("myInput");
  filter = input.value.toUpperCase();
  table = document.getElementById("deliverablesTable");
  tr = table.getElementsByTagName("tr");
  for (i = 0; i < tr.length; i++) {
    td = tr[i].getElementsByTagName("td")[0];
    if (td) {
      txtValue = td.textContent || td.innerText;
      if (txtValue.toUpperCase().indexOf(filter) > -1) {
        tr[i].style.display = "";
      } else {
        tr[i].style.display = "none";
      }
    }       
  }
}
</script>

<style>
#myInput {
  background-image: url('https://cdn1.iconfinder.com/data/icons/hawcons/32/698627-icon-111-search-256.png');
  background-position: left center;
  background-repeat: no-repeat;
  background-size: 30px;
  width: 100%;
  font-size: 16px;
  padding: 12px 20px 12px 40px;
  border: 1px solid #ddd;
  margin-bottom: 12px;
}

#deliverablesTable {
  border-collapse: collapse;
  width: 100%;
  border: 1px solid #ddd;
  font-size: 18px;
}

#deliverablesTable th, #deliverablesTable td {
  text-align: center;
  padding: 12px;
}

#deliverablesTable tr {
  border-bottom: 1px solid #ddd;
}
#deliverablesTable tr:nth-child(even) {
  background-color: #dddddd;
}

#deliverablesTable tr.header, #deliverablesTable tr:hover {
  background-color: #f1f1f1;
}
</style>
<div id="EmployeePanel">
   <table id='deliverablesTable' style="width: 100%;" border="1 px">
     <tr>
       <td>
          <div id="deliverables" style="width: 100%"></div>
      </td>
    </tr>
 </table>
</div>

 

【问题讨论】:

    标签: javascript html jquery ajax sharepoint


    【解决方案1】:

    在每个 Program 第一次出现后创建一行,并在单击该行时分配 searchTable() 函数:

    window.addEventListener("load", function () {
    //Create a empty array
      var programs = new Array();
      Promise.all([
        loadData("xDeliverables", "_api/web/lists/getbytitle('xDeliverables')/items?$select=Program,To,Date,Approved,Notes,Deliverable"),
        loadData("yDeliverables", "_api/web/lists/getbytitle('yDeliverables')/items?$select=Program,To,Date,Approved,Notes,Deliverable"),
        loadData("zDeliverables", "_api/web/lists/getbytitle('zDeliverables')/items?$select=Program,To,Date,Approved,Notes,Deliverable"),
      ])
        .then(([r1, r2, r3]) => {
          const objItems = r1.concat(r2,r3);
          var tableContent =
            '<table id="deliverablesTable" style="width:100%" border="1 px"><thead><tr><td><strong>Program</strong></td>' +
            "<td><strong>To</strong></td>" +
            "<td><strong>Date Submitted</strong></td>" +
            "<td><strong>Approved</strong></td>" +
            "<td><strong>Notes</strong></td>" +
            "<td><strong>Deliverable</strong></td>" +
            "</tr></thead><tbody>";
    
          for (var i = 0; i < objItems.length; i++) {
            if (programs.indexOf(objItems[i].Program)==-1){
              //first occurrence of this Program
              programs.push(objItems[i].Program);
              tableContent += '<tr><td colspan="*" class="searchRow">'+objItems[i].Program+ '</td><tr>';
            }
            tableContent += "<tr>";
            tableContent += "<td>" + objItems[i].Program + "</td>";
            tableContent += "<td>" + objItems[i].To + "</td>";
            tableContent += "<td>" + objItems[i].Date + "</td>";
            tableContent += "<td>" + objItems[i].Approved + "</td>";
            tableContent += "<td>" + objItems[i].Notes + "</td>";
            tableContent += "<td>" + objItems[i].Deliverable + "</td>";
            tableContent += "</tr>";
          }
          $(tableContent).find('.searchRow').click(function(){
             searchTable($(this).text());
          })
          $("#deliverables").append(tableContent);
        })
        .catch((err) => {
          alert("Error: " + err);
          console.error(err);
        });
    });
    

    更改 searchTable 使其可以接受参数。如果参数不为空,则赋值给搜索输入框。

    function searchTable(srch) {
      if(srch!=== undefined){
        $('#myInput').val(srch)
      var input, filter, table, tr, td, i, txtValue;
      input = document.getElementById("myInput");
      filter = input.value.toUpperCase();
      table = document.getElementById("deliverablesTable");
      tr = table.getElementsByTagName("tr");
      for (i = 0; i < tr.length; i++) {
        td = tr[i].getElementsByTagName("td")[0];
        if (td) {
          txtValue = td.textContent || td.innerText;
          if (txtValue.toUpperCase().indexOf(filter) > -1) {
            tr[i].style.display = "";
          } else {
            tr[i].style.display = "none";
          }
        }       
      }
    
    

    您可以以不同的方式处理参数/输入框,具体取决于您是否希望用户输入覆盖行点击,反之亦然。

    【讨论】:

    • 我知道我没有将所有代码都粘贴到 sn-p 中。我有一个工作得很好,这不是我要解决的问题。
    • 不确定是什么问题,但插入此代码后表格没有出现,只是搜索框。
    • 已编辑 - 我无法对其进行测试,因此您可能需要在调试器中单步执行才能找到问题。
    • 刚刚检查过,我唯一能找到的是一个 CORS 问题,这很奇怪,因为我之前从同一个站点拉动,所以我没有遇到过任何这些问题。
    • 我修复了我犯的一个错误,但您仍可能需要在调试器中逐步完成。 CORS 问题可能是一个红鲱鱼。
    猜你喜欢
    • 2019-03-12
    • 2016-04-18
    • 2019-12-24
    • 2018-03-06
    • 1970-01-01
    • 1970-01-01
    • 2016-08-25
    • 2020-02-22
    • 1970-01-01
    相关资源
    最近更新 更多