2011 年 6 月 19 日星期日

详见拆分行

更新:此博客帖子在发布 DataTables 1.10 和 jQuery 1.7 之前撰写。现在仍然保留此帖子,只是出于历史原因。此帖子的新版本现已可用。

表格是显示可轻松制成表格的汇总数据的完美解决方案。然而,你经常会想从你的网站/应用程序的最终用户那里获得深入浏览表格数据的权限并显示更详细的信息。这有助于整理界面,避免最终用户过于关心信息并让他们获得更好的控制。

DataTables 提供两种 API 方法,用来将明细行附加到 DataTables 中的父级;fnOpen显示额外的信息,而它的反函数fnClose删除它。由于fnOpen将接受 DOM 节点或 HTML 字符串,因此在明细行中显示的内容或多或少可由你决定。在这个示例中,我将展示如何使用打开和关闭时带有动画效果的内部表格。

此示例还展示了 DataTables 1.8 所包含的新mDataProp选项的工作原理。你可以通过很多不同的方法获取明细行的数据,包括 Ajax 或 DOM 数据源。在这个示例中,通过使用 mDataProp 和 DataTables 使用 JSON 对象来显示表格,我们可以使用赋给表格的原始对象,显示表格默认视图中没有的信息。

渲染引擎 浏览器 CSS 等级

表格

和往常一样,我会使用我的标准设置在表格中显示,但在这个示例中,默认情况下只显示五列中的三列 — 剩余信息将在明细显示中显示。还要注意,表格的开始处有一列备用列,供最终用户单击以显示/隐藏明细行。

<table cellpadding="0" cellspacing="0" border="0" class="display" id="example">
    <thead>
        <tr>
            <th></th>
            <th>Rendering engine</th>
            <th>Browser</th>
            <th>CSS grade</th>
        </tr>
    </thead>
    <tbody></tbody>
</table>

数据源如下所示

{ "aaData": [
    {
        "engine": "Trident",
        "browser": "Internet Explorer 4.0",
        "platform": "Win 95+",
        "version": "4",
        "grade": "X"
    },
    {
        "engine": "Trident",
        "browser": "Internet Explorer 5.0",
        "platform": "Win 95+",
        "version": "5",
        "grade": "C"
    },
    ...
] }

并且在使用mDataProp的情况下,DataTables 的初始化相当简单。请注意,第一列的mDataProp值为 null,并且已给定sDefaultContent使得 DataTables 呈现为静态字符串。

$(document).ready(function() {
  var anOpen = [];
    var sImageUrl = "/release-datatables/examples/examples_support/";

    var oTable = $('#example').dataTable( {
        "bProcessing": true,
        "sAjaxSource": "/release-datatables/examples/ajax/sources/objects.txt",
        "aoColumns": [
            { 
               "mDataProp": null, 
               "sClass": "control center", 
               "sDefaultContent": '<img src="'+sImageUrl+'details_open.png'+'">'
            },
            { "mDataProp": "engine" },
            { "mDataProp": "browser" },
            { "mDataProp": "grade" }
        ]
    } );
} );

查看控件

既然我们已经显示了该表格,现在需要向控制按钮添加事件处理程序,以根据需要调用fnOpenfnClose。在这里,我们将在数组 anOpen 中保存对我们“打开”的任何 TR 行的引用 — 以这种方式,我们可以使用$.inArray查看要打开该行还是已经打开该行,从而对其进行关闭。我们还更新控制图像以展示一个“关闭”按钮,以便向最终用户提供关于哪一项控件将执行单击操作的额外信息。

另请注意函数fnFormatDetails,它用于建立赋给fnOpen显示的字符串。我们使用fnGetData获取行的原始数据对象,以获取显示信息(如之前所述,你可以以任何想要的方式获取这些数据)。

$('#example td.control').live( 'click', function () {
   var nTr = this.parentNode;
   var i = $.inArray( nTr, anOpen );

   if ( i === -1 ) {
      $('img', this).attr( 'src', sImageUrl+"details_close.png" );
      oTable.fnOpen( nTr, fnFormatDetails(oTable, nTr), 'details' );
      anOpen.push( nTr );
    }
    else {
      $('img', this).attr( 'src', sImageUrl+"details_open.png" );
      oTable.fnClose( nTr );
      anOpen.splice( i, 1 );
    }
} );

function fnFormatDetails( oTable, nTr )
{
  var oData = oTable.fnGetData( nTr );
  var sOut = 
    '<div class="innerDetails">'+
      '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
        '<tr><td>Rendering engine:</td><td>'+oData.engine+'</td></tr>'+
        '<tr><td>Browser:</td><td>'+oData.browser+'</td></tr>'+
        '<tr><td>Platform:</td><td>'+oData.platform+'</td></tr>'+
        '<tr><td>Version:</td><td>'+oData.version+'</td></tr>'+
        '<tr><td>Grade:</td><td>'+oData.grade+'</td></tr>'+
      '</table>'+
    '</div>';
  return sOut;
}

动画

现在表格完全有效了 - 但我们添加一些动画,让它对最终用户更流畅。jQuery 函数 $().slideDown$().slideUp 用于动画。请注意,在 fnFormatDetails 中我放置了一个带有“innerDetails”类的包装器元素,这是我们将动画化的元素。fnOpen 返回一个引用 TR 节点,该节点附加到表格中以获取详细信息行,我们将其用作获取所需元素的选取器的一部分。

更新的控件代码如下所示

$('#example td.control').live( 'click', function () {
  var nTr = this.parentNode;
  var i = $.inArray( nTr, anOpen );

  if ( i === -1 ) {
    $('img', this).attr( 'src', sImageUrl+"details_close.png" );
    var nDetailsRow = oTable.fnOpen( nTr, fnFormatDetails(oTable, nTr), 'details' );
    $('div.innerDetails', nDetailsRow).slideDown();
    anOpen.push( nTr );
  }
  else {
    $('img', this).attr( 'src', sImageUrl+"details_open.png" );
    $('div.innerDetails', $(nTr).next()[0]).slideUp( function () {
      oTable.fnClose( nTr );
      anOpen.splice( i, 1 );
    } );
  }
} );

最后,为了让动画正常工作,我们需要默认隐藏信息包装器元素,并让 jQuery 处理其显示

div.innerDetails { display: none }

结论

使用 fnOpen 显示钻取数据可能是一种非常有用的表格交互,并且如本示例中所示,具有高度的可定制性。显示的触发、显示的内容以及信息的数据源都可以紧密集成到您的设置中。

与往常一样,论坛中有对此帖子的评论和讨论话题