2014-10-21 22 views
8

Ich lade Daten mit Ajax und generieren dynamisch Spaltennamen in meiner DataTable. Meine DataTable hat eine unterschiedliche Anzahl von Spalten, abhängig von der Auswahl durch den Benutzer. (Es gibt eine Dropdown-Liste).DataTables mit unterschiedlicher Anzahl von Spalten

Zum Beispiel gibt es zwei Optionen in Dropdown-Liste als Südprovinz und Northern Province. Südliche Provinz Tabelle hat 4 Spalten und Nordprovinz Tabelle hat 6 Spalten.

Szenario 1

Erste Benutzer wählen Südprovinz die 4 Spalten. Dann erzeugt es Tabelle ohne keine Fehler, aber danach, wenn Benutzer Nordprovinz auswählt, das 6 Spalten hat, erzeugt Tabelle nicht und js Konsolendruckfehler wie unten.

Uncaught TypeError: Cannot read property 'style' of undefined jquery.dataTables.js:3828

Szenario 2

Erste Benutzer wählen Northern Province die 6 Spalten. Dann erzeugt es Tabelle ohne keine Fehler, aber danach, wenn Benutzer Südprovinz auswählt, das 4 Spalten hat, Tabelle nicht erzeugen und js Konsolendruckfehler wie unten.

Uncaught TypeError: Cannot read property 'mData' of undefined jquery.dataTables.js:6122

Aber wenn beide Tabelle gleiche Anzahl von Spalten hat, erzeugen beide Tabellen ohne Fehler.

Wie kann ich das lösen? Hier

ist der JS-Code

jQuery(document) 
.ready(
function() { 
    $('#province-list').change(
      function() { 
       var prov = $(this).val(); 
       if (prov == "sp") { 
        make_SP(); 
       } else if (prov == "np") { 
        make_NP(); 
       } 
      }); 
    function make_SP() { 
    $("#dataTables-res_item") 
    .dataTable(
    { 
     "bDestroy" : true, 
     "bProcessing" : false, 
     "bServerSide" : true, 
     "sAjaxSource" : "/province_list_view?p_name=sp", 
     "aoColumns" : [ 
       { 
        "mData" : "result_date", 
        "sTitle" : "Result Date" 
       }, 
       { 
        "mData" : "result_day", 
        "sTitle" : "Result Day" 
       }, 
       { 
        "mData" : "draw_number", 
        "sTitle" : "Draw Number" 
       }, 
       { 
        "mData" : "draw_time", 
        "sTitle" : "Draw Time" 
       } ], 
     "order" : [ [ 0, "desc" ] ] 
     }); 
    };     
    function make_NP() { 
     $("#dataTables-res_item") 
     .dataTable(
     { 
      "bDestroy" : true, 
      "bProcessing" : false, 
      "bServerSide" : true, 
      "sAjaxSource" : "/province_list_view?p_name=np", 
      "aoColumns" : [ 
        { 
         "mData" : "result_date", 
         "sTitle" : "Result Date" 
        }, 
        { 
         "mData" : "result_day", 
         "sTitle" : "Result Day" 
        }, 
        { 
         "mData" : "draw_number", 
         "sTitle" : "Draw Number" 
        }, 
        { 
         "mData" : "draw_time", 
         "sTitle" : "Draw Time" 
        }, 
        { 
         "mData" : "draw_place", 
         "sTitle" : "Draw Place" 
        }, 
        { 
         "mData" : "draw_person", 
         "sTitle" : "Agent" 
        } ], 
      "order" : [ [ 0, "desc" ] ] 
     }); 
    }; 
}); 
+0

Make arbeiten Geige und lassen Sie uns wissen, dass dies einmal – Innodel

+0

Versuchen Sie, bevor make_SP Aufruf () Funktion zerstört die Datentabelle. – Gowri

+0

@Gowri Wie kann ich das tun? Ich habe "bDestroy" verwendet: "true". aber es hat nicht funktioniert. – Bishan

Antwort

10

Ich denke, der sicherste Weg, um die Tabelle vollständig zu entfernen ist, und dann wieder einsetzen, um das DOM vor Neuinitialisierung. Es scheint mir, dass dataTables nicht alle generierten Inhalte vollständig entfernt, weshalb der Fehler (aus verschiedenen Gründen) auftritt. In der Theorie sollte es mehr oder weniger wie oben funktionieren, tut es aber nicht. Betrachten Sie diese Lösung:

[vollständige Quelle in der Demo-Link unten]

var dataTable, 
    domTable, 
    htmlTable = '<table id="example"><tbody></tbody></table>'; 

function initDataTable(province) { 
    if ($.fn.DataTable.fnIsDataTable(domTable)) { 
     dataTable.fnDestroy(true); 
     $('body').append(htmlTable); 
    } 
    var data = (province=='sp') ? sp : np; 
    var columns = (province=='sp') ? spColumns : npColumns;  
    dataTable = $("#example").dataTable({ 
     aaData : data, 
     aoColumns : columns 
     /* other options here */ 
    });   
    domTable = document.getElementById('example'); 
} 

$('#province-list').change(function() { 
    var prov = $(this).val(); 
    initDataTable(prov); 
}); 

Dies funktioniert. Siehe Demo ->http://jsfiddle.net/gss4a17t/ Grundsätzlich ist es das gleiche wie in OP, aber anstatt verschiedene Funktionen für verschiedene Provinzen, habe ich verschiedene aoColumns für verschiedene Provinzen und so weiter gemacht. Und anstatt auf bDestroy angewiesen zu sein, entferne ich die gesamte <table> mit dataTable.fnDestroy(true) (sowohl DOM und und dataTables Injektionen) und fügt dann das <table> -Kelett vor der Reinitialisierung der DataTable wieder ein.

Ich weiß nicht, ob das an OPs anpassungsfähig ist, aber so würde ich es tun.Es ist flexibler für zukünftige Änderungen, und die aoColumns -Objekte können automatisch aus einem Skript generiert oder vom Server von AJAX erzeugt werden (wenn Sie zum Beispiel unterschiedliche Titel für verschiedene Sprachen haben möchten). "Gürtel und geschweifte Klammern" :)

+0

Danke für Ihre Antwort. Ich habe wenig Frage. Ich erhalte Daten durch Aufruf von URL. Wie kann ich es mit 'aaData' benutzen? – Bishan

+0

hey @Bishan, und danke für die Aufwertung! :) Ich denke, es sollte das gleiche sein, Sie erhalten Daten vom Server im gleichen JSON-Format wie in der Geige, denke ich? Dann erhalten Sie die Daten, fügen Sie das Ergebnis als 'aaData' ein. Rufen Sie "initDataTable" oder wie auch immer Sie es nennen, im Erfolgs-Handler Ihres AJAX auf. Ich kann das nicht in einer Geige wiedergeben, aber das sollte der Fall sein. – davidkonrad

+1

Danke @davidkonrad, ich habe 'sAjaxSource' anstelle von' aaData' verwendet. Jetzt geht es. :) – Bishan

12

Ich konfrontiert das gleiche Problem, wenn meine aktualisierte Daten andere Anzahl von Spalten als die vorherigen Daten hatte. Das Rezept ist wirklich einfach! In dem Szenario, wenn es eine Änderung der Anzahl der Spalten gibt, arbeitet Destroy function in Verbindung mit $("#datatable").empty();. Also, bevor Daten Code Nachladen würden folgende Zeilen enthalten:

if (dataTableObject) { // Check if DataTable has been previously created and therefore needs to be flushed 

    dataTableObject.fnDestroy(); // destroy the dataTableObject 
    // For new version use table.destroy(); 
    $('#' + DataTableDivID).empty(); // Empty the DOM element which contained DataTable 
    // The line above is needed if number of columns change in the Data 
    } 
// DataTable data loading/reloading codes comes here 

Also, insgesamt Ihr Code wie folgt aussehen:

if(dataTableObject) { // Check if table object exists and needs to be flushed 
    dataTableObject.fnDestroy(); // For new version use table.destroy(); 
    $('#myTable').empty(); // empty in case the columns change 
} 

var data = (province=='sp') ? sp : np; 
var columns = (province=='sp') ? spColumns : npColumns; 

dataTableObject = $('#myTable').DataTable({ 
     columns: columns, 
     data: data 
    }); 
+0

Ich habe Ihre Lösung als Kommentar zu https://datatables.net/manual/tech-notes/3#destroy gepostet. (Derzeit noch Moderation). –

Verwandte Themen