jquery 具有不同列数的数据表

bweufnob  于 12个月前  发布在  jQuery
关注(0)|答案(5)|浏览(126)

我正在使用apache加载数据,并在DataTable中动态生成列名。根据用户的选择,我的数据表有不同的列数。(有一个下拉列表)。
例如,下拉列表中有两个选项,南部省北部省南部省表有4列,北部省表有6列。

情景1

第一个用户选择南部省,有4列。然后它生成表没有错误,但在此之后,如果用户选择北部省,其中有6列,表不生成和js控制台打印错误如下。
Uncaught TypeError: Cannot read property 'style' of undefined jquery.dataTables.js:3828

情景2

第一个用户选择北部省,有6列。然后它生成表没有任何错误,但在此之后,如果用户选择南部省,其中有4列,表不生成和js控制台打印错误如下。
Uncaught TypeError: Cannot read property 'mData' of undefined jquery.dataTables.js:6122
但如果两个表具有相同的列数,则两个表都不会生成错误。
我该如何解决这个问题?

这里是JS代码

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" ] ]
        });
    };
});
t98cgbkg

t98cgbkg1#

当我更新的数据与以前的数据有不同的列数时,我也遇到了同样的问题。食谱真的很简单!列数变化**的场景下,Destroy function$("#datatable").empty();配合使用。因此,在重新加载数据之前,您的代码将包含以下行:

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

因此,总体而言,您的代码可能看起来像这样:

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

46scxncf2#

我认为最安全的方法是完全删除表,然后在重新初始化之前将其重新插入到DOM中。在我看来,dataTables并没有完全删除所有生成的内容,这就是为什么会发生错误(出于不同的原因)。从理论上讲,它应该像上面一样工作,或多或少,但它没有。考虑这个解决方案:
[full源代码在下面的演示链接]

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

这是可行的。参见demo ->**http://jsfiddle.net/gss4a17t/**基本上它和OP中的一样,但是我没有为不同的省份提供不同的功能,而是为不同的省份制作了不同的aoColumns等等。我没有依赖bDestroy,而是用dataTable.fnDestroy(true)(DOM * 和 * 以及dataTables注入)删除了整个<table>,然后在重新初始化dataTable之前重新插入<table>-skeleton。
我不知道这是否适合OP的需要,但这就是我会怎么做。它对于未来的更改更加灵活,aoColumns-对象可以从脚本自动生成,或者通过AJAX从服务器实现(例如,如果您希望为不同的语言提供不同的标题)。“腰带和背带”:)

btxsgosb

btxsgosb3#

有很好的解决办法,但在遇到这个问题后,活力仍然在我脑海中响起。我想分享这一点,而不是在js的出口。所以请评论。

function genericAjaxCall(url, tableId, _header, _dataMapping, isData,
    isEditDelete) {
if (!isData) {
    $.ajax({
        url : url,
        method : "GET",
        dataType : "JSON",
        success : function(data) {
            var editDeletUrl = url.split("/");
            var dataArray = createArray(_header, data, _dataMapping, url,
                    isEditDelete)
            createListHeading(tableId, dataArray, false);
            initDT(tableId, dataArray);
        },
        error : function(xhr) {
            console.log(xhr);
            openErrorModal("Guru", xhr.responseText);
        }
    });
} else {
    var dataArray = createArray(_header, url, _dataMapping);
    console.log(dataArray);
    var finalData = dataArray + objName;
    console.log(finalData);
    createListHeading(tableId, dataArray, false);
    initDT(tableId, dataArray);
 }
}

function createArrayWithDelete(_header, data, _dataMapping, url) {
var posts = {};
posts.postDT = []
for (var i = 0; i < data.length; i++) {
    var jsonData = {};

    for (var j = 0; j < _header.length; j++) {
        if (_dataMapping[j].indexOf('.') !== -1) {
            var parts = _dataMapping[j].split(".");
            if (String(data[i][parts[0]][parts[1]]).indexOf('*') !== -1) {
                jsonData[_header[j]] = data[i][parts[0]][parts[1]].bold()
                        .replace("*", "");
            } else {
                jsonData[_header[j]] = data[i][parts[0]][parts[1]];
            }

        } else {

            if (String(data[i][_dataMapping[j]]).indexOf('*') !== -1) {
                jsonData[_header[j]] = data[i][_dataMapping[j]].bold()
                        .replace("*", "");
            } else {
                jsonData[_header[j]] = data[i][_dataMapping[j]];
            }
        }
    }

    if (_header[_header.length - 1]) {
        jsonData["Action"] = deleteOnly(url,
                data[i][_dataMapping[_dataMapping.length - 1]]);
    }

    posts.postDT.push(jsonData);
   }
   return posts.postDT;
  }

function createListHeading(tableId, data, isAction) {
var posts = {
    post : []
};
$.each(data[0], function(key, value) {
    posts.post.push({
        "mDataProp" : key,
        "sTitle" : key
        /* "sType" : "string" */
    });
   });
  cols = posts.post

 }

function initDT(tableId, results) {
// Construct the measurement table
data_table = $('#' + tableId).DataTable({
    "iDisplayLength" : 10,
    scrollCollapse : true,
    "aaSorting" : [],
    "aaData" : results,
    "aoColumns" : cols
});
$('#' + tableId).DataTable().columns.adjust();
}

这就是我打电话的方式

$(function() {
    var header = [ "H1", "H2", "H3", "H4" ];
    var dataMapping = [ "d1", "d2", "d3", "d3" ];

    genericAjaxCall("ajaxurlWhichreturnJSON", "tableId", header, dataMapping,
            false, true);
});

这里是d1,d2...是你的回应的关键。现在我们不需要担心用户选择哪个值。注:这不是直接解决这个问题,但它是比喻

hk8txs48

hk8txs484#

我知道这是一个老问题,但由于我花了几个小时试图用DataTables 1.10.18解决它,我希望它能帮助别人。我使用JavaScript数组作为数据源,并使用jQuery 1.12.4。这是基于@davidkonrad的回答。
超文本标记语言:

select province
<select id="province-list">
  <option value="sp">sp</option>
  <option value="np">np</option>    
</select>    
<br><br>

<div id="table-container">
    <table id="example" class="display"></table>
</div>

JS:

var sp = [
  [ 'col1', 'col2'] ,
  [ 'col11', 'col22']    
];

var np = [
  [ 'col1', 'col2', 'col3', 'col4' ],
  [ 'col11', 'col22', 'col33', 'col44' ]
];

var spColumns = [
  { title : "column1" },
  { title : "column2" }
];

var npColumns = [
  { title : "column1" },
  { title : "column2" },
  { title : "column3" },
  { title : "column4" }      
];

var dataTable,
  htmlTable = '<table id="example" class="display"></table>';

function initDataTable(province) {
  if ($.fn.DataTable.isDataTable('#example')) {
    dataTable = $('#example').DataTable();
    dataTable.destroy(true);
    $('#table-container').empty();
    $('#table-container').append(htmlTable);
  } 
  var data = (province=='sp') ? sp : np;
  var columns = (province=='sp') ? spColumns : npColumns;  

  dataTable = $('#example').DataTable( {
    "data": data,
    "columns": columns
  } );
}

$(document).ready(function() {
  initDataTable('sp');

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

});
bd1hkmkf

bd1hkmkf5#

if(table) {
                table.destroy(); //destroy tableData object
                $('#dttable').empty(); //clear table
            }
   table = $('#dttable').DataTable({
                columns: cols, //set  new columns array
                data:    data1 //set new data
            });

相关问题