多个嵌套表中的详细信息行不起作用

Detail row in multiple nested tables doesn't work

我使用 DataTables jQuery plugin to create nested independent tables. In this post 我发现了如何创建嵌套 table。当我想在嵌套 table 中创建嵌套 table 时,我在行 parentTable.fnOpen(this, tableAsJQueryNode, 'details');

中遇到错误
Uncaught TypeError: Cannot read property '0' of undefined

jsfiddle

html

<body><div id="example"></div><body>

javascript 带有示例数据的代码

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 + "\">";
  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({
            "bPaginate": false,
            "bLengthChange": false,
            "bFilter": false,
            "bSort": false,
            "bInfo": false,
            "bAutoWidth": false,
        });

        tables.push([divElement.children().first().children().first().attr("id"), table]);

        $(document).on('click', '#example tbody tr' , function() {

            var parentTable = new Object();

            var parentTableId = $(this).parent().parent().attr("id");

            if (tables.some(function(a){return a[0] === parentTableId})){
              for (var i = 0; i < tables.length; i++){
                  if (tables[i][0] === $(this).parent().parent().attr("id")){
                    parentTable = tables[i][4];
                    break;
                  }
              }; 
            }

            if (parentTable.fnIsOpen($(this))) {
                /* This row is already open - close it */
                parentTable.fnClose($(this));
            }
            else {
              if ($(this).children().first().children().first().is("img")){
                /* Open this row */

                var tableInString = buildTable($(this).attr("id"), dataInJson);

                var tableAsJQueryNode = $('<div/>').html(tableInString).contents();

                parentTable.fnOpen(this, tableAsJQueryNode, 'details');
                var newtable = $(tableAsJQueryNode.attr("id")).dataTable({
                    "bPaginate": false,
                    "bLengthChange": false,
                    "bFilter": false,
                    "bSort": false,
                    "bInfo": false,
                    "bAutoWidth": false
                });

                if (tables.some(function(a){return a[0] !== tableAsJQueryNode.attr("id")})){
                    tables.push([tableAsJQueryNode.attr("id"), newtable]);
                }
              }
            }
        });

});

我找到一个thread有同样的问题,但是没有解决方法。

如果单击嵌套 table 中的行,您会收到错误消息:

你的代码有错误,第 316 行应该是:

var newtable = $('#' + tableAsJQueryNode.attr("id")).dataTable({

请参阅 this JSFiddle 进行演示。

注意:您的代码也需要一些优化,但这与您的问题无关。