【背景描述】
制作一个排行榜,想要突出显示前123名,并依次标识【冠军】、【亚军】、【季军】。
有以下几种方式实现:
#1-> 调用每行的回调函数 fnCreatedRow: function (nRow, aData, iDataIndex)
#2-> 调用每个单元格的回调函数 createdCell: function(nTd, sData, oData, iRow, iCol)
#3-> 排序、搜索等触发表格重新渲染 + 实现单个单元格的格式渲染
#4-> 使用datatable API row()实现
DataTable API:http://www.datatables.club/reference/api/
【具体说明】
#1-> 回调函数 fnCreatedRow: function (nRow, aData, iDataIndex)
--> nRow: 当前已经被创建的tr元素对象,即DOM
--> aData: 当前行的对象,类似一个array,通过aData.keyValue 可以取到对应的字段值
--> iDataIndex: 当前行数,内部存储索引值
参考资料:http://datatables.club/reference/option/createdRow.html
$("#example").DataTable({
//每行回调函数,给123行设置特殊标识
"fnCreatedRow": function (nRow, aData, iDataIndex) {
//当前第1行,下标从0开始计数
if(iDataIndex == 0){
$(nRow).css("background-color", "#e46262"); //设置背景色
$(nRow).css("font-weight","bold"); //设置字体加粗
$(nRow).css("color","#ffffff"); //设置字体颜色
//取第0列当前行的单元格,设置一个图标加文字
$('td:eq(0)',nRow).html(" 冠军");
}
else if(iDataIndex == 1){
$(nRow).css("background-color", "#ffb456");
$(nRow).css("font-weight","bold");
$(nRow).css("color","#ffffcc");
$('td:eq(0)',nRow).html(" 亚军");
}
else if(iDataIndex == 2){
$(nRow).css("background-color", "#FFFF00");
$(nRow).css("font-weight","bold");
$(nRow).css("color","#8d9ab9");
$('td:eq(0)',nRow).html(" 季军");
}
//其他行正常显示
else
$('td:eq(0)',nRow).html(iDataIndex+1);
}
});
实现效果:左图依照第4列进行排序结果,排序后每行记录会进行移动,包括第1列的排名序号。
适用于不需要动态排序的场景。
tips:最开始写成了 $('td:eq(0)',nRow).innerText = iDataIndex+1;
程序无法识别这段代码,换成innerHtml也一样,关于它们之间的区别可以参考:
https://www.cnblogs.com/fozero/p/5916878.html
#2-> 调用回调函数 createdCell: function(nTd, sData, oData, iRow, iCol)
顾名思义,这个函数是在创建单元格的时候回调的,参数设置如下:
--> nTd : 当前单元格DOM对象
-->sData : 当前单元格的具体数值
-->oData : 当前整行的数据对象
--> iRow : 行下标
--> iCol : 列下标
tips : 只能单个单元格进行渲染,一般都是取用的$(nTd)对象进行相应的操作。
oData.key 等价于 sData,即对第一列“排名”来说,oData.排名 = sData
$("#example").DataTable({
"data": dataArray.BodyData,
"columns":[
{
"data": "排名",
//单元格渲染格式
createdCell: function (nTd, sData, oData, iRow, iCol) {
if(iRow == 0)
{
$(nTd).css("background-color", "#e46262");
$(nTd).css("font-weight","bold");
$(nTd).css("color","#ffffff");
$(nTd).html(" 冠军");
}
else if(iRow == 1){
$(nTd).css("background-color", "#ffb456");
$(nTd).css("font-weight","bold");
$(nTd).css("color","#ffffcc");
$(nTd).html(" 亚军");
}
else if(iRow == 2){
$(nTd).css("background-color", "#FFFF00");
$(nTd).css("font-weight","bold");
$(nTd).css("color","#8d9ab9");
$(nTd).html(" 季军");
}
else{
$(nTd).html(iRow+1) ;
}
}
},
{
"data": "姓名",
createdCell: function (nTd, sData, oData, iRow, iCol) {
if(iRow == 0)
{
$(nTd).css("background-color", "#e46262");
}
else if(iRow == 1){
$(nTd).css("background-color", "#ffb456");
}
else if(iRow == 2){
$(nTd).css("background-color", "#FFFF00");
}
}
},
{
"data": "地区",
//单元格渲染
createdCell: function (nTd, sData, oData, iRow, iCol) {
if(iRow == 0)
{
$(nTd).css("background-color", "#e46262");
}
else if(iRow == 1){
$(nTd).css("background-color", "#ffb456");
}
else if(iRow == 2){
$(nTd).css("background-color", "#FFFF00");
}
}
},
{
"data": "排序数",
createdCell: function (nTd, sData, oData, iRow, iCol) {
if(iRow == 0)
{
$(nTd).css("background-color", "#e46262");
}
else if(iRow == 1){
$(nTd).css("background-color", "#ffb456");
}
else if(iRow == 2){
$(nTd).css("background-color", "#FFFF00");
}
}
}
]
});
实现效果同上。
datatable的各种回调函数:https://www.cnblogs.com/lxny/p/6203661.html
-----------------------#小结#-----------------------
fnCreatedRow 和 createdCell 的用法类似,一个是针对整行的,一个是针对单个单元格的,在fnCreatedRow调用过程中,如果需要取单个单元格可以用 $('td:eq(0)',nRow) ,其中0代表第0列,另外样式设置采用.css(),文本设置采用.html()。
#3-> 排序、搜索等触发表格重新渲染 + 实现单个单元格的格式渲染
1. 要求按某一列排序的时候,前三行固定不变,即每次排序时会重新渲染单元格格式,而不会导致记录跟着一起移动。
2. 可以自定义渲染每个单元格的格式,包括背景、字体大小、颜色、加粗等属性,起强调突显作用。
适用场景:需要依据不同的列条件(column)取前几位,并突出显示。
var t = $("#example").DataTable();
t.on('order.dt search.dt',function () {
//-------第1列--------
t.column(0, {search: 'applied', order: 'applied'}).nodes().each(function (cell, i) {
//保存默认单元格格式风格
var cellStyle = cell.style;
if(i==0){
cell.innerHTML = " 冠军";
cell.style.backgroundColor = "#e46262";
cell.style.color = "#FFFFFF";
cell.style.fontWeight = "bold";
}
else if(i==1){
cell.innerHTML = " 亚军";
cell.style.backgroundColor = "#ffb456";
cell.style.color = "#FFFFFF";
cell.style.fontWeight = "bold";
}
else if(i==2){
cell.innerHTML = " 季军";
cell.style.backgroundColor = "#FFFF00";
cell.style.color = "#FFFFFF";
cell.style.fontWeight = "bold";
}
else {
cell.innerHTML = i + 1;
//设置单元格为默认的风格
cell.style = cellStyle;
}
});
//-------第2列--------
t.column(1,{search: 'applied', order: 'applied'}).nodes().each(function (cell, i) {
//保存默认单元格格式风格
var cellStyle = cell.style;
if(i==0){
cell.style.backgroundColor = "#ff6262";
cell.style.color = "#FFFFFF";
cell.style.fontWeight = "bold";
}
else if(i==1){
cell.style.backgroundColor = "#ffb49a";
cell.style.color = "#ffffcc";
cell.style.fontWeight = "bold";
}
else if(i==2){
cell.style.backgroundColor = "#FFFFa9";
cell.style.color = "#8d9ab9";
cell.style.fontWeight = "bold";
}
else{
//设置单元格为默认的风格
cell.style = cellStyle;
}
});
//-------第3列--------
t.column(2, {search: 'applied', order: 'applied'}).nodes().each(function (cell, i) {
//保存默认单元格格式风格
var cellStyle = cell.style;
if(i==0){
cell.style.backgroundColor = "#e1ed99";
cell.style.color = "#FFFFFF";
cell.style.fontWeight = "bold";
}
else if(i==1){
cell.style.backgroundColor = "#dd5579";
cell.style.color = "#FFFFFF";
cell.style.fontWeight = "bolder";
}
else if(i==2){
cell.style.backgroundColor = "#abbb37";
cell.style.color = "#FFFFFF";
cell.style.fontWeight = "bolder";
}
else{
//设置单元格为默认的风格
cell.style = cellStyle;
}
});
}).draw();
输出效果:左图是依据第4列的数值从高到低排列,右图是从低到高排列后的结果。
tips:重新渲染的时候记得先保存默认单元格的风格,重绘的时候记得设置成默认风格,不然会出现以下情况。
代码放在ajax-complete function(){} 里面,即当数据加载完成的时候调用重绘函数。
#4-> 使用datatable API row() 实现
4.1 点击单行,打印输出当前JSONObject
var table = $("#example").DataTable();
$('#examplet body').on('click','tr',function () {
console.log(table.row(this).data());
});
4.2 点击单个单元格,打印输出当前单元格信息
var table = $("#example").DataTable();
$('#example tbody').on('click','td',function () {
console.log(table.cell(this).data());
});
4.3 设置特定一行的样式
官方例子:https://datatables.net/reference/api/row().data()
参考:https://zhidao.baidu.com/question/198931344022248125.html
初始想法:借用row.id()判定是否需要特殊渲染某一行,结果输出的是undefined,正常情况下会返回当前rowid,原因是没有设置id值,所以应该使用的是 row.index() 来返回当前的rowindex。
ex. 点击当前行,返回rowindex
var table = $('#example').DataTable();
$('#example').on( 'click', 'tr', function () {
var index = table.row( this ).index();
alert( 'Clicked row index '+index );
});
ex. 根据index,分别点击前3行,改变该行的背景色,任意一行点击后,第一列单元格的值会变成“updated”。
var table = $('#example').DataTable();
$('#example').on('click', 'tr', function () {
var index = table.row( this ).index();
table.cell(index, 0).data('updated').draw();
if(index == 0){
$(this).css("background-color", "#e46262");
}
if(index == 1){
$(this).css("background-color", "#ffb456");
}
if(index == 2){
$(this).css("background-color", "#FFFF00");
}
});
回到最开始的问题,前三行特殊渲染背景+字体加粗,第一列加图标突显主题。
下面两种写法完全等价,方式其实和第一种方式很相似,都是取到需要的那一行,然后对行进行操作,之后通过$('td: eq(0)', this) 取这一行的某一列进行单独渲染。
tips: 代码段放置在 ajax complete: function () { } 里面。
var tr = $('#example tr');
tr.each(function () {
var index = $(this).index();
if(index == 0){
$(this).css("background-color", "#e46262");
$(this).css("font-weight","bold");
$(this).css("color","#ffffff");
$('td:eq(0)',this).html(" 冠军");
console.log(this);
}
else if(index == 1){
$(this).css("background-color", "#ffb456");
$(this).css("font-weight","bold");
$(this).css("color","#ffffcc");
$('td:eq(0)',this).html(" 亚军");
console.log(this);
}
else if(index == 2){
$(this).css("background-color", "#FFFF00");
$(this).css("font-weight","bold");
$(this).css("color","#8d9ab9");
$('td:eq(0)',this).html(" 季军");
console.log(this);
}
else{
$('td:eq(0)',this).html(index + 1);
}
});
//等价写法
var tr = $('#example tr');
tr.each(function () {
var row = $(this);
var index = row.index();
if(index == 0){
row.css("background-color", "#e46262");
row.css("font-weight","bold");
row.css("color","#ffffff");
$('td:eq(0)',row).html(" 冠军");
console.log(this);
}
else if(index == 1){
row.css("background-color", "#ffb456");
row.css("font-weight","bold");
row.css("color","#ffffcc");
$('td:eq(0)',row).html(" 亚军");
console.log(this);
}
else if(index == 2){
row.css("background-color", "#FFFF00");
row.css("font-weight","bold");
row.css("color","#8d9ab9");
$('td:eq(0)',row).html(" 季军");
console.log(this);
}
else{
$('td:eq(0)',this).html(index + 1);
}
});
实现效果: