使用jQuery Datatable显示分层数据

时间:2015-05-28 11:49:30

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

我从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);

不出所料,只加载了父对象。我知道这不是数据传递的方式。不过,了解这种分层数据是否能够付出努力是很好的。

1 个答案:

答案 0 :(得分:4)

请参阅下面的代码段以演示可能的解决方案。您需要对其进行调整以匹配您的数据结构,因为您在问题中对其进行了一些简化。

此代码使用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>