2014-10-21 34 views
8

DataTable'ımda dinamik olarak ajax kullanarak ve sütun adları üreterek veri yüklüyorum. DataTable'ım, kullanıcı seçimine bağlı olarak farklı sayıda sütuna sahiptir. (Bir açılır liste vardır).Farklı sayıda sütun içeren DataTable'lar

Örneğin, Güney Eyaleti ve Kuzey Eyaleti olarak açılan listeden 2 seçenek vardır. Güney İli tablo 4 sütun ve Kuzey il tablosunun 6 sütun vardır.

Senaryo 1

İlk kullanıcı 4 sütun var Güney İli seçin. Sonra hata olmadan tablo oluşturur, Ama sonra kullanıcı 6 sütun içeren Kuzey Eyaleti seçerseniz, tablo aşağıdaki gibi üretilemiyor ve js konsol baskı hatası.

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

Senaryo 2

İlk kullanıcı 6 sütun bulunmaktadır Kuzey İli seçin. Sonra hata olmadan tablo üretir, Ama sonra kullanıcı 4 sütun içeren Güney Eyaleti seçerseniz, tablo aşağıdaki gibi üretilemez ve js konsol baskı hatası. Her iki tablo aynı kolon sayısını varsa

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

Fakat her iki tablo hatasız üretir.

Bunu nasıl çözebiliriz? İşte

Ben güvenli yolu tamamen tabloyu kaldırmak ve sonra reinitialising önce DOM tekrar takın olduğunu düşünüyorum JS Kod

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

Yap çalışma kemençe ve (bize make_SP çağırmadan önce, bir kez bu deneyin – Innodel

+0

bildirmek) işlevi datatable yok. – Gowri

+0

@Gowri Bunu nasıl yapabilirim? Ben "bDestroy" kullandım: true'. ama işe yaramadı. – Bishan

cevap

10

olduğunu. VeriTabloları üretilen tüm içeriği tamamen kaldırmaz, bu yüzden hata (lar) ın neden (farklı nedenlerden dolayı) oluştuğunu görür. Teoride, yukarıdaki gibi çalışmalı, az ya da çok, ama değil. [Aşağıdaki demo linkte tam kaynağını]

Bu işleri

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); 
}); 

: Bu çözümü düşünün. Bkz. Demo ->http://jsfiddle.net/gss4a17t/ Temelde OP'deki ile aynıdır, ancak farklı iller için farklı işlevler yerine farklı iller için farklı aoColumns yaptım. Ve bDestroy belgesine güvenmek yerine, <table>'un tamamını dataTable.fnDestroy(true) (her ikisi de DOM ve ve dataTables enjeksiyonları) ile kaldırırım ve daha sonra dataTable'ı yeniden başlatmadan önce <table> -keleton'u yeniden yerleştiririm.

Bu, OP'nin gereksinimine uyarlanabilir mi bilmiyorum, ancak böyle yaparım.Gelecekteki değişiklikler için daha esnektir ve aoColumns -object'ler bir komut dosyasından otomatik olarak oluşturulabilir veya sunucudan AJAX tarafından elde edilebilir (örneğin farklı diller için farklı başlıklar varsa). "Kemer ve parantez" :)

+0

Cevabınız için teşekkür ederiz. Benim biraz sorum var. URL'yi arayarak veri alıyorum. AaData ile nasıl kullanabilirim? – Bishan

+0

hey @Bishan, ve teşekkür için teşekkürler! :) Bence aynı olması gerektiğini düşünüyorum, sunucudan verileri aynı JSON formatında aldığım kemandaki gibi mi? Sonra verileri alırsınız, sonucu "aaData" olarak eklersiniz. Yani AJAX'inizin başarı işleyicisinde "initDataTable" ya da adınız ne olursa olsun. Bunu bir kemanda yeniden üretemiyorum, ama durum böyle olmalı. – davidkonrad

+1

Teşekkürler @davidkonrad, 'aaData' yerine' sAjaxSource' kullandı. Şimdi çalışıyor. :) – Bishan

12

Güncel bilgilerim, önceki verilere göre farklı sütun sayısı olduğunda, aynı sorunu yaşadım. Tarif gerçekten basit! numaralı sütunların sayısında değişiklik olduğunda, Destroy function, $("#datatable").empty(); ile birlikte çalışır. Bu yüzden veri kodunuzu tekrar yüklemeden önce aşağıdaki satırları içerecektir: Yani genel

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 

, bu gibi görünebilir kodunuzu:

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

Çözümünüzü https://datatables.net/manual/tech-notes/3#destroy adresine bir yorum olarak gönderdim. (Şu anda hala beklemede). –

İlgili konular