jQuery Datatables 重绘后无法选择行

5
我正在使用jquery datatable插件在jquery UI对话框中显示表格。以下是我调用以绘制表格的函数。
function listPtCharges(filter){
var chgTable;
chgTable =
  $('#chargeTable').dataTable({
    "bJQueryUI": true,
    "bDestroy": true,    
    "sDom": 'tT',
    "bSort": false,
    "bAutoWidth": false,
    "sAjaxSource": "/ajax/ptchglist.php",
    "sAjaxDataProp": "Records",
    "fnServerData": function ( sSource, aoData, fnCallback ) {
      aoData.push( { "name": "acctno", "value": $("#curAcctno").val() } );
      aoData.push( { "name": "ins_id", "value": $("#ins_id").val() } );
      aoData.push( { "name": "filter", "value": filter } );
      $.ajax( {
        "dataType" : 'json',
        "type" : "POST",
        "url" : sSource,
        "data" : aoData,
        "success" : fnCallback
        } );
    } ,
    "aoColumns":
    [
     {"bVisible":false},
     {"sWidth": 55},
     {"sWidth": 30},
     {"sWidth": 40},
     {"sWidth": 125},
     {"sWidth": 50},
     {"sWidth": 50},
     {"sWidth": 20},                
     {"bVisible":false}  // allowed
    ],
    "oTableTools": {
      "sRowSelect": chgSelctionTyp,
      "sSwfPath": "/swf/copy_csv_xls_pdf.swf",
      "aButtons": []
    }
  });
}

在打开对话框后立即调用此函数。以下是打开对话框并加载表格的代码行。

var oTT = TableTools.fnGetInstance( 'chargeTable' );
      if(oTT)
        oTT.fnSelectNone();
      $( "#chargeList" ).dialog( "open" );
      listPtCharges();

在对话框中,我有另一个按钮,它具有事件处理程序来获取筛选器的值并调用相同的函数,使用新的筛选器。新加载的表总是从服务器带来更多的行。
除了一个奇怪的问题以外,一切都很好。每当绘制新的行数更多的表时,只有与先前表相等的行数可供选择。
我的意思是假设我加载了包含5行的表,按下按钮为表格带来新的数据集。表格被加载了8行。但现在我只能选择前5行。其余的都会导致Firebug中未知位置相关的错误。
非常感谢任何在这方面提供帮助的人。
编辑:以下是试图访问所选行的代码。
    var oTT = TableTools.fnGetInstance( 'chargeTable' );
    var aData = oTT.fnGetSelectedData();

这也是jQuery DataTables的一部分,可以在Firebug中显示错误信息。

"fnIsSelected": function ( n )
{
var pos = this.s.dt.oInstance.fnGetPosition( n );
return (this.s.dt.aoData[pos]._DTTT_selected===true) ? true : false;
}, 

在单击不可点击的行后,会显示以下错误。

类型错误:this.s.dt.aoData[pos] 未定义

我猜测aodata的长度仍然与之前加载的表相同。


看起来你使用了jQUery的bindclick而不是ondelegate,那个选择代码在哪里? - Daniel
我已在原问题下的“编辑”标题中添加了详细信息。 - bvnbhati
3个回答

4

不应该销毁并重建表格,而应该让datatable重新获取数据。

我认为调用fnDraw足以触发刷新 - 尽管没有测试过:

 $('#chargeTable').dataTable().fnDraw();

在您的fnServerData函数中,您可能需要更改加载filter参数的方式:
// keep this variable in some shared scope :
var filterPtr = {value: ''};

$('#chargeTable').dataTable({
    ....
    "fnServerData": function(...){
         ...
         aoData.push({ "name": "filter", "value": filterPtr.value });
         ...
     }
});

// if you need to update the filter :
filterPtr.value = 'newValue';
$('#chargeTable').dataTable().fnDraw();

2
我的意思是,假设我加载了5行表格,并按下按钮以获取新的数据集用于表格。 表格被加载了8行。 但是现在我只能选择前5行。 其余的都会导致firebug中与未识别位置相关的错误。
所以问题是,在单击此按钮后,它可能会带回更多行。 它看起来像这个“按钮”是一个“过滤器”,可能包含或不包含新行。
听起来您需要在修改后重新初始化datatable。 我曾经遇到过将新行注入datatable中后,该问题的解决方法就是这么做。
我知道这似乎有点大材小用,但这是我过去使用过的工作方法。 在这种情况下,调用redraw或设置bDestroy标志对我没有起作用。
在注入新行之前...
1.销毁表格 2.注入行 3.重新初始化datatable 再次强调,这可能适用于您,也可能不适用,但这是我过去必须做的事情。
$('#filterButton').click(function()
{
  //revert table to it's original state
  $('#chargeTable').dataTable().fnDestroy();

  //do some stuff, inject rows and get new filter value
  var filter = 'new filter value';

  //re-initialize the datatable
  listPtCharges(filter);
});

function listPtCharges(filter){
var chgTable;
chgTable =
  $('#chargeTable').dataTable({
    "bJQueryUI": true,
    "bDestroy": true,    
    "sDom": 'tT',
    "bSort": false,
    "bAutoWidth": false,
    "sAjaxSource": "/ajax/ptchglist.php",
    "sAjaxDataProp": "Records",
    "fnServerData": function ( sSource, aoData, fnCallback ) {
      aoData.push( { "name": "acctno", "value": $("#curAcctno").val() } );
      aoData.push( { "name": "ins_id", "value": $("#ins_id").val() } );
      aoData.push( { "name": "filter", "value": filter } );
      $.ajax( {
        "dataType" : 'json',
        "type" : "POST",
        "url" : sSource,
        "data" : aoData,
        "success" : fnCallback
        } );
    } ,
    "aoColumns":
    [
     {"bVisible":false},
     {"sWidth": 55},
     {"sWidth": 30},
     {"sWidth": 40},
     {"sWidth": 125},
     {"sWidth": 50},
     {"sWidth": 50},
     {"sWidth": 20},                
     {"bVisible":false}  // allowed
    ],
    "oTableTools": {
      "sRowSelect": chgSelctionTyp,
      "sSwfPath": "/swf/copy_csv_xls_pdf.swf",
      "aButtons": []
    }
  });
}

1

已测试并可用!

在线演示: http://jsfiddle.net/oscarj24/c9m3s/


我刚刚尝试通过创建一个datatable,然后使用buttonclick事件添加一些额外的硬编码数据来复制问题。起初,一切都正常,但是当添加额外的行时,之前的行仍然可以选择,但新的行不可能选择,而且浏览器的console中没有错误。然而,我建议你采取以下措施来“解决”这个问题: 1.-datatable初始化之后为“选择行”添加事件处理程序,因为行已经加载到DOM中。 2.-与其使用.click().on('click').live('click')来处理“选择行”事件,不如使用.delegate(),像这样:
$('#parent').delegate('children', 'click', function() { /* do something */ });

这样,您就能选择新添加的行了。

只是为了知道,.live()已经被弃用,但一些旧的插件如datatables仍在使用它,所以我将jQuery版本更改为1.7.2

此外,我使用fnAddData()代替fnDraw(),但这并不重要,它也引起了您遇到的同样问题,根据那个“解决方案”,我找到了一个(这就是我认为已经“测试和工作”的原因)


坦白地说,我无法详细解释这个问题为什么会发生(似乎是一个bug),但我有一个可能的“解决方案”,希望能帮到你。
请阅读代码中的注释,检查它(也许这可以给你另一种需要做什么的视角),在需要时还要检查你的浏览器控制台。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接