DataTable学习笔记---排序细则、列隐藏

转载出处:http://www.cnblogs.com/tonylp/archive/2013/03/07/2947585.html

 1.DataTable排序

             1.1 基础知识

               dataTable可以多列排序,在表格中,按住shirt,然后选择需要排序的列就可以了。下面是四个重要属性的区分:

              属性'bSort':初始化的时候定义整个table是否排序

$(document).ready( function () {
  $('#example').dataTable( {
    "bSort": false
  } );
} );

   属性'bSortable':初始化的时候定义具体哪一列是否可排序


$(document).ready( function() {
  $('#example').dataTable( {
    "aoColumns": [ 
      { "bSortable": false },
      null,
      null,
      null,
      null
    ] } );
} );
属性'aaSorting':初始化表格的时候,选择以怎样的规则排序


// Sort by 3rd column first, and then 4th column
$(document).ready( function() {
  $('#example').dataTable( {
    "aaSorting": [[2,'asc'], [3,'desc']]
  } );
} );

  属性'asSorting':设置具体哪一行的排序规则

// Using aoColumns
$(document).ready( function() {
  $('#example').dataTable( {
    "aoColumns": [
      null,
      { "asSorting": [ "asc" ] },
      { "asSorting": [ "desc", "asc", "asc" ] },
      { "asSorting": [ "desc" ] },
      null
    ]
  } );
} );


通过上面的介绍基本上应该清楚这四个属性的含义与不同了吧。接下来给介绍简单排序

             1.2 简单排序,单列排序

                  table初始化的时候使用属性'aaSorting',属性值是一个array。

$(document).ready(function() {
    $('#example').dataTable( {
        "aaSorting": [[ 4, "desc" ]]
    } );
} );

   1.3 多列排序

                 有了上面的单例排序,外加基础知识里的aaSorting的介绍,范例上面就有,这里就不写了。

             1.4 特殊排序规则

                 这里需要分清几个要点:

                 1. 首先是sSortDataType.定义数据源类型的排序(主要是input类型),dom-text,dom-select,dom-checkbox。突然发现以前有个做傻了,当初用checkbox的时候,就应该直接设置sSortDataType.

                 2.属性sType:定义这列数据类型,包括(string,numeric,date,html)。

                 3.不带类型检测的排序

                    老实说这个挺复杂的,怎么写排序规则,然后怎么实现,尽管dataTable有范例,但是没怎么看懂,下面我给出我改过的范例,如果有错误,如果大家发现好一点的范例,欢迎跟我分享,如果有时间我能理解它的范例,我也会及时更新这篇博文的。



function initTable(){
    tableTest = $('#tableTest').dataTable({
        "bJQueryUI": true,
        "sPaginationType": "full_numbers",
        "aaData": [
      ['101', 'aaa', '91,1', '2012-10-10', 'X'],
      ['102', 'bbb', '92,5', '2012-3-19', 'X'],
      ['103', 'ccc', '89,5', '2013-3-21', 'X'],
      ['105', 'eee', '95', '2011-11-11', 'C'],
      ['104', 'ddd', '91', '2013-2-22', 'X']
    ],
        'aaSorting':[ [1,'asc'],[2,'asc'] ],
        'aoColumns':[
        {'sTitle':'ID', 'sWidth':'20%','sClass':'center'},
        {'sTitle':'Name', 'sWidth':'20%','sClass':'center'},
        {'sTitle':'Score', 'sType': 'numeric-comma','sWidth':'20%','sClass':'center'},
        {'sTitle':'Date', 'sWidth':'20%','sClass':'center'},
        {'sTitle':'downLoad', 'sWidth':'20%','sClass':'center',
            "mRender": function ( data, type, full ) {
                return '<a href="'+data+'">Download</a>';
              }}
          ]
    });
}

jQuery.fn.dataTableExt.oSort['numeric-comma-asc']  = function(a,b) {
    var x = (a == "-") ? 0 : a.replace(",", "." );
    var y = (b == "-") ? 0 : b.replace( ",", "." );
    x = parseFloat( x );
    y = parseFloat( y );
    return ((x < y) ? -1 : ((x > y) ?  1 : 0));
};
 
jQuery.fn.dataTableExt.oSort['numeric-comma-desc'] = function(a,b) {
    var x = (a == "-") ? 0 : a.replace(",", "." );
    var y = (b == "-") ? 0 : b.replace( ",", "." );
    x = parseFloat( x );
    y = parseFloat( y );
    return ((x < y) ?  1 : ((x > y) ? -1 : 0));
};

    定义排序规则的时候肯定会定义两个,其实应该是三个,当>,<,=..一般定义的排序类型有数字,带小数的,string。

      下面是当表格中是一些input-type不是text类型的排序。那么首先应该先获取例如type=checkbox的值对吧

/* Create an array with the values of all the checkboxes in a column */
$.fn.dataTableExt.afnSortData['dom-checkbox'] = function  ( oSettings, iColumn )
{
    var aData = [];
    $( 'td:eq('+iColumn+') input', oSettings.oApi._fnGetTrNodes(oSettings) ).each( function () {
        aData.push( this.checked==true ? "1" : "0" );
    } );
    return aData;
}
 2.DataTable列隐藏


var tableTest;
function initTable(){
    tableTest = $('#tableTest').dataTable({
        "bJQueryUI": true,
        "sPaginationType": "full_numbers",
        "aaData": [
      ['101', 'aaa', '91,1', '2012-10-10', 'X'],
      ['102', 'bbb', '92,5', '2012-3-19', 'X'],
      ['103', 'ccc', '89,5', '2013-3-21', 'X'],
      ['105', 'eee', '95', '2011-11-11', 'C'],
      ['104', 'ddd', '91', '2013-2-22', 'X']
    ],
        'aaSorting':[ [1,'asc'],[2,'asc'] ],
        'aoColumns':[
        {'sTitle':'ID', 'sWidth':'20%','sClass':'center'},
        {'sTitle':'Name', 'sWidth':'20%','sClass':'center'},
        {'sTitle':'Score','sWidth':'20%','sClass':'center'},
        {'sTitle':'Date', 'sWidth':'20%','sClass':'center'},
        {'sTitle':'downLoad', 'sWidth':'20%',"bVisible": false,"bSearchable": false, 'sClass':'center',
            "mRender": function ( data, type, full ) {
                return '<input type="text" class="userName" value="'+data+'"/>';
              }}
          ]
    });
    
    $('#tableTest').find('.userName').each(function(){
        console.log($(this).val());
    });
}

 有两个bVisible和bSearchable,如果设置bVisible:false,那么这列数据是不可访问的,bSearchAble:false是可以访问的,我感觉这边做的不是很好哎,就比方说我们一般都喜欢对表添加一列隐藏列,里面记录每行的id,方便数据访问,但是貌似这招这样不行。我想能不能用mReader来做,就比方上面代码,设置type='hidden',试验发现不行,看来我是明显天真了。但是想到mReader:function(data,type,full)其中的full就是这一列的所有信息,试验了一下,的却访问隐藏的那一列,那么通过这种变相的方法就可以访问隐藏的数据了。

      总结一下,可以通过mReader:function(data,type,full)中的full参数获取一行所有信息(包括隐藏列),获取到的是一列字符串,然后通过spilt转换位数组,然后选取第几个。

//代码不全,就是那么个意思
{'sTitle':'ID', 'sWidth':'20%','sClass':'center'},
        {'sTitle':'Name', 'sWidth':'20%','sClass':'center'},
        {'sTitle':'Score','sWidth':'20%','sClass':'center'},
        {'sTitle':'Date', 'sWidth':'20%','bVisible':false,'sClass':'center'},
        {'sTitle':'downLoad', 'sWidth':'20%',"bSearchable": false, 'sClass':'center',
            "mRender": function ( data, type, full ) {
                return '<input type="text" class="userName" value="'+full+'"/>';
              }}
          ]
    });
    var s;
    var data;
    $('#tableTest').find('.userName').each(function(){
        var data = $(this).val();
        var s = data.split(",");
        console.log(s[3]);
    });
//输出
//2012-10-10 
//2012-3-19 
2013-3-21
2013-2-22 
2011-11-11

 通过点击按钮确定该列是否可见或是隐藏---自带了范例

  通过oTable.fnSetColumnVis(iCol,1/0);前一个参数是第几列。下面的代码应该挺好看懂的吧。

$(document).ready(function() {
    $('#example').dataTable( {
        "sScrollY": "200px",
        "bPaginate": false
    } );
} );
 
function fnShowHide( iCol )
{
    /* Get the DataTables object again - this is not a recreation, just a get of the object */
    var oTable = $('#example').dataTable();
     
    var bVis = oTable.fnSettings().aoColumns[iCol].bVisible;
    oTable.fnSetColumnVis( iCol, bVis ? false : true );
}

通过点击按钮确定是否显示该列详细信息---自带范例


/* Formating function for row details */
function fnFormatDetails ( oTable, nTr )
{
    var aData = oTable.fnGetData( nTr );
    var sOut = '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">';
    sOut += '<tr><td>Rendering engine:</td><td>'+aData[1]+' '+aData[4]+'</td></tr>';
    sOut += '<tr><td>Link to source:</td><td>Could provide a link here</td></tr>';
    sOut += '<tr><td>Extra info:</td><td>And any further details here (images etc)</td></tr>';
    sOut += '</table>';
     
    return sOut;
}
 
$(document).ready(function() {
    /*
     * Insert a 'details' column to the table
     */
    var nCloneTh = document.createElement( 'th' );
    var nCloneTd = document.createElement( 'td' );
    nCloneTd.innerHTML = '<img src="../examples_support/details_open.png">';
    nCloneTd.className = "center";
     
    $('#example thead tr').each( function () {
        this.insertBefore( nCloneTh, this.childNodes[0] );
    } );
     
    $('#example tbody tr').each( function () {
        this.insertBefore(  nCloneTd.cloneNode( true ), this.childNodes[0] );
    } );
     
    /*
     * Initialse DataTables, with no sorting on the 'details' column
     */
    var oTable = $('#example').dataTable( {
        "aoColumnDefs": [
            { "bSortable": false, "aTargets": [ 0 ] }
        ],
        "aaSorting": [[1, 'asc']]
    });
     
    /* Add event listener for opening and closing details
     * Note that the indicator for showing which row is open is not controlled by DataTables,
     * rather it is done here
     */
    $('#example tbody td img').live('click', function () {
        var nTr = $(this).parents('tr')[0];
        if ( oTable.fnIsOpen(nTr) )
        {
            /* This row is already open - close it */
            this.src = "../examples_support/details_open.png";
            oTable.fnClose( nTr );
        }
        else
        {
            /* Open this row */
            this.src = "../examples_support/details_close.png";
            oTable.fnOpen( nTr, fnFormatDetails(oTable, nTr), 'details' );
        }
    } );
} );


效果截图:


    Keep on fighting!!

以后会继续更新的。

<think>嗯,用户的问题是关于在C#的DataTable中如何对包含特殊格式字符串如"A12-23"和"B1-12"的进行自定义排序。我需要先理解这些字符串的结构,然后确定排序的规则。 首先,这些字符串看起来像是包含字母前缀,后面跟着数字范围,比如A12-23,可能表示从A12到A23。不过用户可能需要按照特定的顺序排序,比如先按字母部分,再按起始数字,再按结束数字排序。例如,A12-23应该排在B1-12之前,因为A在字母顺序上先于B;而在同一字母下,比如A10-20和A5-15,可能需要比较起始数字,A5-15排在前面,因为5比10小。 接下来,我需要考虑如何在C#中实现这样的排序DataTable本身支持通过DataView的Sort属性进行排序,但默认的排序可能无法处理这种复杂格式。因此,可能需要使用自定义的排序逻辑,比如实现IComparer接口,然后在DataView中使用这个比较器。 然后,我需要分析字符串的结构。字符串可能分为字母部分、起始数字和结束数字。例如,分解"A12-23"可以得到前缀"A",起始数字12,结束数字23。可以使用正则表达式来提取这些部分,比如正则表达式^([A-Za-z]+)(\d+)-(\d+)$,这样可以分组捕获前缀、起始和结束数字。 接下来,实现IComparer接口中的Compare方法。在比较两个字符串时,首先比较前缀的字母顺序,如果相同,再比较起始数字,如果还相同,最后比较结束数字。需要处理可能的格式错误,比如无效的字符串,这时候可能需要抛出异常或者返回默认值。 然后,如何在DataView中应用这个自定义的比较器。由于DataView的Sort属性默认不支持传入IComparer,可能需要将DataTable转换为Enumerable,使用OrderBy方法并传入自定义的比较器,或者通过添加计算排序键提取出来,然后根据这些键进行排序。 另外,用户提到参考的链接是关于VSTO和Excel的C#代码,可能需要考虑与Excel的交互,但用户当前的问题集中在DataTable的自定义排序,所以重点应放在DataTable的处理上,而不是Excel部分。 可能的实现步骤包括: 1. 编写正则表达式分解字符串。 2. 创建自定义的IComparer实现。 3. 将DataTable转换为DataView,并应用自定义排序,或者使用LINQ进行排序。 4. 处理可能的异常情况,如无效的字符串格式。 需要考虑的细节问题包括:正则表达式是否能正确捕获所有情况,比较器中的转换是否正确处理数字,以及性能问题,如果数据量大的话,可能需要优化比较器的效率。 最后,用户可能需要具体的代码示例,所以需要提供一个完整的例子,包括正则表达式的使用、比较器的实现,以及在DataTable中的应用方法。同时,需要提醒用户注意异常处理,比如无效格式的字符串如何处理。</think>以下是在C#中实现DataTable特殊格式字符串(如"A12-23"、"B1-12")自定义排序的具体方法: ### 一、核心排序逻辑实现 1. **正则表达式分解**:使用正则表达式`^([A-Za-z]+)(\d+)-(\d+)$`解析字符串 2. **三元组比较规则**: - 第一优先级:字母部分(ASCII顺序) - 第二优先级:起始数字(数值大小) - 第三优先级:结束数字(数值大小) ```csharp public class SpecialFormatComparer : IComparer<string> { public int Compare(string x, string y) { var pattern = new Regex(@"^([A-Za-z]+)(\d+)-(\d+)$"); var matchX = pattern.Match(x); var matchY = pattern.Match(y); if (!matchX.Success || !matchY.Success) throw new FormatException("Invalid string format"); // 比较字母部分 int letterCompare = string.Compare( matchX.Groups[1].Value, matchY.Groups[1].Value, StringComparison.Ordinal); if (letterCompare != 0) return letterCompare; // 比较起始数字 int startX = int.Parse(matchX.Groups[2].Value); int startY = int.Parse(matchY.Groups[2].Value); if (startX != startY) return startX.CompareTo(startY); // 比较结束数字 int endX = int.Parse(matchX.Groups[3].Value); int endY = int.Parse(matchY.Groups[3].Value); return endX.CompareTo(endY); } } ``` ### 二、DataTable应用方法 ```csharp DataTable CustomSort(DataTable dt, string columnName) { // 转换为可枚举对象 var rows = dt.AsEnumerable().ToList(); // 执行自定义排序 var sortedRows = rows.OrderBy( r => r.Field<string>(columnName), new SpecialFormatComparer()).ToList(); // 重建DataTable return sortedRows.CopyToDataTable(); } // 使用示例 var sortedTable = CustomSort(yourDataTable, "YourColumnName"); ``` ### 三、异常处理建议 1. **格式验证**:在数据加载阶段添加格式验证 ```csharp bool ValidateFormat(string input) { return Regex.IsMatch(input, @"^[A-Za-z]+\d+-\d+$"); } ``` 2. **容错处理**:在比较器中添加默认返回值 ```csharp // 修改Compare方法开头 if (!matchX.Success || !matchY.Success) return string.Compare(x, y, StringComparison.Ordinal); // 默认字符串比较 ``` ### 四、性能优化方案 1. **预解析数据**:添加计算存储解析结果 ```csharp dt.Columns.Add("SortKey", typeof(Tuple<string, int, int>)); foreach (DataRow row in dt.Rows) { var match = pattern.Match(row["YourColumn"].ToString()); row["SortKey"] = Tuple.Create( match.Groups[1].Value, int.Parse(match.Groups[2].Value), int.Parse(match.Groups[3].Value)); } // 排序时直接使用计算 dt.DefaultView.Sort = "SortKey"; ``` 2. **缓存机制**:对已解析的结果进行缓存
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值