【问题标题】:Displaying hierarchical data with jQuery Datatable使用 jQuery Datatable 显示分层数据
【发布时间】:2015-05-28 11:49:30
【问题描述】:

我从 Server 得到的是一个父对象列表,每个对象由零个或多个子对象组成。有点像下面的

var data = [{
    "Id" : 1,
    "permissionValue" : 7,
    "child" : { //only one child object for simplicity
      "Id" :2,
      "permissionValue" : 7
    }
  }];

我想将此数据加载到 jQuery 数据表中。像这样实现一个 rowCallback 函数(添加一些 CSS 类):

tableOptions.rowCallBack = function(row,data,index){
    var api = this.api();
    api.rows.add(data.child).draw(); //not sure whether draw is necessary
  };
tableOptions.data = data;
that.dataTable = $("#dataTable").DataTable(tableOptions);

不出所料,只有父对象加载。我知道这不是数据应该传递的方式。尽管如此,还是很高兴知道这种分层数据是否可以通过努力显示出来。

【问题讨论】:

    标签: javascript jquery jquery-plugins datatables jquery-datatables


    【解决方案1】:

    有关潜在解决方案的演示,请参见下面的 sn-p。您需要对其进行调整以匹配您的数据结构,因为您在问题中对其进行了一定程度的简化。

    这段代码利用row().child方法首先检查一行是否已经显示,如果已经显示,则隐藏,否则显示。

    $(document).ready(function() {
    
       var dataInJson = [{
             "data": {
                "name": "b1",
                "street": "s1",
                "city": "c1",
                "departments": 10,
                "offices": 15
             },
             "kids": [{
                "data": {
                   "department": "HR",
                   "supervisor": "Isidor Bristol",
                   "floor": 1,
                   "employees": 15
                },
                "kids": [{
                      "data": {
                         "name": "Klement Nikodemos",
                         "phone": "+938462",
                         "hire_date": "January 1, 2010",
                         "id": 3456
                      },
                      "kids": []
                   }, {
                      "data": {
                         "name": "Madhava Helmuth",
                         "phone": "+348902",
                         "hire_date": "May 23, 2002",
                         "id": 1234
                      },
                      "kids": []
                   }, {
                      "data": {
                         "name": "Andria Jesse",
                         "phone": "456123",
                         "hire_date": "October 23, 2011",
                         "id": 9821
                      },
                      "kids": []
                   }
    
                ]
             }, {
                "data": {
                   "department": "development",
                   "supervisor": "Jim Linwood",
                   "floor": 2,
                   "employees": 18
                },
                "kids": [{
                      "data": {
                         "name": "Origenes Maxwell",
                         "phone": "345892",
                         "hire_date": "February 1, 2004",
                         "id": 6234
                      },
                      "kids": []
                   }
    
                ]
             }, {
                "data": {
                   "department": "testing",
                   "supervisor": "Zekeriya Seok",
                   "floor": 4,
                   "employees": 11
                },
                "kids": []
    
             }]
          }, {
             "data": {
                "name": "b2",
                "street": "s10",
                "city": "c2",
                "departments": 3,
                "offices": 10
             },
             "kids": [{
                "data": {
                   "department": "development",
                   "supervisor": "Gallagher Howie",
                   "floor": 8,
                   "employees": 24
                },
                "kids": [{
                      "data": {
                         "name": "Wat Dakota"
                      },
                      "kids": []
                   }
    
                ]
             }, {
                "data": {
                   "department": "testing",
                   "supervisor": "Shirley Gayle",
                   "floor": 4,
                   "employees": 11
                },
                "kids": []
    
             }]
    
          }, {
             "data": {
                "name": "b3",
                "street": "s3",
                "city": "c3",
                "departments": 2,
                "offices": 1
             },
             "kids": [{
                "data": {
                   "department": "development"
                },
                "kids": [{
                      "data": {
                         "name": "Wat Dakota"
                      },
                      "kids": []
                   }
    
                ]
             }, {
    
             }]
          },
    
          {
             "data": {
                "name": "b4",
                "city": "c4"
             },
             "kids": []
          }
    
       ];
    
    
       function buildTable(idOfTableParentElement, tableDataInJson) {
    
          var deepCopyOfData = JSON.parse(JSON.stringify(tableDataInJson));
    
          var countRowOccurence = (idOfTableParentElement.match(/row/g) || []).length;
          var table_id = 0;
          var tableIdString = "";
          if (countRowOccurence > 0) {
    
             var rowIds = new Array();
    
             var copyIdOfTableParentElement = idOfTableParentElement
             for (var i = countRowOccurence; i > 0; i--) {
                var firstIndexOfTabPosition = copyIdOfTableParentElement.indexOf("tab_") + "tab_".length;
                copyIdOfTableParentElement = copyIdOfTableParentElement.substring(firstIndexOfTabPosition, copyIdOfTableParentElement.length);
                var rowPosition = copyIdOfTableParentElement.indexOf("row_") + "row_".length;
                copyIdOfTableParentElement = copyIdOfTableParentElement.substring(rowPosition, copyIdOfTableParentElement.length);
                var rowId = "";
                if (copyIdOfTableParentElement.indexOf("tab_") != -1)
                   rowId = copyIdOfTableParentElement.substring(0, copyIdOfTableParentElement.indexOf("tab_"));
                else
                   rowId = copyIdOfTableParentElement.substring(0, copyIdOfTableParentElement.length);
    
                rowIds.push(parseInt(rowId));
             }
    
             rowIds.forEach(function(hierarchyPosition) {
                deepCopyOfData = JSON.parse(JSON.stringify(deepCopyOfData[hierarchyPosition].kids));
             });
    
             table_id = idOfTableParentElement;
             tableIdString = idOfTableParentElement + "_tab_" + countRowOccurence.toString();
          } else {
             tableIdString = "tab_" + countRowOccurence.toString();
          }
    
          var tableInHtml = "<table id=\"" + tableIdString + "\" class=\"stripe row-border order-column\">";
          tableInHtml += buildTableContent(tableIdString, deepCopyOfData);
          tableInHtml += "</table>";
    
          var a = $('#exampleTable tbody tr');
    
          return tableInHtml;
       }
    
       function buildTableContent(tableIdString, tableDataInJson) {
          // find data with max number of proerties
          var positionOfDataWithMaxProperties = 0;
          var maxNumberOfProperties = 0;
          for (var i = 0; i < tableDataInJson.length; i++) {
             if (typeof(tableDataInJson[i].data) !== 'undefined') {
                if (Object.keys(tableDataInJson[i].data).length > maxNumberOfProperties) {
                   maxNumberOfProperties = Object.keys(tableDataInJson[i].data).length;
                   positionOfDataWithMaxProperties = i;
                }
             }
          }
    
          // create array of properties
          var properties = new Array();
          Object.keys(tableDataInJson[positionOfDataWithMaxProperties].data).forEach(function(key) {
             properties.push(key);
          });
    
          // create header of table
          var TableMainHeader = "<thead><tr>";
          for (var i = 0; i < tableDataInJson.length; i++) {
             if (typeof(tableDataInJson[i].kids) !== 'undefined' && tableDataInJson[i].kids.length > 0) {
                TableMainHeader += "<th></th>";
                break;
             }
          }
          properties.forEach(function(property) {
             TableMainHeader += "<th>" + property + "</th>";
          });
          TableMainHeader += "</tr></thead>";
    
          // create body of table
          var TableMainBody = "<tbody>";
          for (var i = 0; i < tableDataInJson.length; i++) {
    
             if (typeof(tableDataInJson[i].data) !== 'undefined') {
    
                TableMainBody += "<tr id=\"" + tableIdString + "_row_" + parseInt(i) + "\" >";
    
                if (TableMainHeader.indexOf("<th></th>") != -1) {
                   if (tableDataInJson[i].kids.length > 0)
                      TableMainBody += "<td><img src=\"http://blog.picol.org/wp-content/themes/icon_blog/images/css_images/arrow_right_16.png\"></td>";
                   else
                      TableMainBody += "<td></td>";
                }
    
                properties.forEach(function(property) {
                   if (Object.keys(tableDataInJson[i].data).indexOf(property) === -1)
                      TableMainBody += "<td></td>";
                   else
                      TableMainBody += "<td>" + tableDataInJson[i].data[property] + "</td>";
                });
    
                TableMainBody += "</tr>";
             }
    
          };
          TableMainBody += "</tbody>";
    
          return TableMainHeader + TableMainBody;
       }
    
       //Run On HTML Build
       $(document).ready(function() {
    
          var divElement = $("#example").append(buildTable("example", dataInJson));
    
          var tables = new Array();
    
          //Initialse DataTables, with no sorting on the 'details' column
          var table = divElement.children().first().DataTable({
             "paginate": false,
             "lengthChange": false,
             "searching": false,
             "ordering": false,
             "info": false,
             "autoWidth": false
          });
    
          tables.push([divElement.children().first().children().first().attr("id"), table]);
    
          $(document).on('click', '#example tbody tr', function() {
             var $row = $(this);
             var parentTable = new Object();
             var parentTableId = $row.parent().parent().attr("id");
    
             for (var i = 0; i < tables.length; i++) {
                if (tables[i][0] === $row.parent().parent().attr("id")) {
                   parentTable = tables[i][1];
                   break;
                }
             }
    
             if (parentTable.row(this).child.isShown()) {
                /* This row is already open - close it */
                parentTable.row(this).child.hide();
    
             } else {
                if ($(this).children().first().children().first().is("img")) {
                   /* Open this row */
    
                   var tableInString = buildTable($row.attr("id"), dataInJson);
    
                   var tableAsJQueryNode = $('<div/>').html(tableInString).contents();
    
                   parentTable.row(this).child(tableAsJQueryNode, 'details').show();
                   var newtable = $('#' + tableAsJQueryNode.attr("id")).DataTable({
                      "paginate": false,
                      "lengthChange": false,
                      "searching": false,
                      "ordering": false,
                      "info": false,
                      "autoWidth": false
                   });
    
                   if (tables.some(function(a) {
                         return a[0] !== tableAsJQueryNode.attr("id")
                      })) {
                      tables.push([tableAsJQueryNode.attr("id"), newtable]);
                   }
                }
             }
          });
    
       });
    });
    <link href="http://cdn.datatables.net/1.10.7/css/jquery.dataTables.min.css" rel="stylesheet"/>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="http://cdn.datatables.net/1.10.7/js/jquery.dataTables.min.js"></script>
    
    <div id="example"></div>

    【讨论】:

    • 这在这个 sn-p 中运行良好,在我的项目中(使用数据表 1.10.7 和 jquery 2.1.4)我在单击展开箭头时遇到了 parentTable.row is not a function 异常。跨度>
    • @mtoloo 如果您使用dataTable() 初始化表parentTable,则可能是此错误的原因。请改用DataTable()
    • 我在 js fiddle 中尝试了你的代码 sn-p 得到错误 Uncaught TypeError: divElement.children(...).first(...).DataTable is not a function Fiddle link - @987654322 @
    猜你喜欢
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-12
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多