2015-05-19 2 views
1

Я использую плагин jQuery для создания вложенных независимых таблиц. В сообщении this я нашел способ создания вложенной таблицы. Когда я хочу, чтобы создать вложенную таблицу в вложенной таблицы я получаю ошибку в строке 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 с той же проблемой, но решения нет.

Если щелкнуть на строке вложенной таблицы, вы получите ошибку:

enter image description here

ответ

2

Существует ошибка в коде, строка # 316 должна быть:

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

См this JSFiddle для демонстрации.

ПРИМЕЧАНИЕ. Ваш код также нуждается в некоторой оптимизации, но это не имеет отношения к вашему вопросу.

+0

Не могли бы вы также дать рекомендации о том, какие оптимизации? – Matt

+0

@Matt, просто [мелкие вещи] (http://jsfiddle.net/qtynfu5a/2/). –