黑色幽默 2012-10-17
关于Jquery的DataTables里TableTools的应用
分类:javaScript2011-06-2417:45880人阅读评论(0)收藏举报
最近在产品中使用了TableTools这个工具,主要用来实现导出和复制功能。
但是在实际的运用中出现了以下相关问题
当结合jquery的tabs工具,tableTools只能在初始化的页面运行正常,一旦切换到其他Tabs里就不能正常运行了;
另外就是同一个页面里,不能在不同的div下创建一个tableTools工具;
还有就是几个datatables在一个页面里,但是每次都只显示其中一个,导致TableTools工具不能正常使用。
而且datatables在多次切换后,还会出现有时也会报__flash__addCallback相关的错误,function__flash__addCallback(instance,name)方法里的instance为null。
另外同时初始化多个datatables组件,当前页面只显示一个,另外一个需要通过切换的方式进行显示(tabs),但表头会缩进。
TableTools默认都是前台导出哦复制,如何实现后台导出(并支持后台过滤)。
1、datatables表头缩短问题,首先是这个div必须显示出来,不能让此div在一个display:none的状态下,如果这样,datatables更新数据后显示就会出现表头缩短。
2、多个tables在同一页面下,必须在一个大的容器里面(简单的说就是在一个div下面),不然tableTools导出不能使用。
3、关于tablesTools后台分页处理,这里给出源码(实际情况需要调试):
1.增加aButton项
"ext-xls":{"sAction":"flash_save",
"sCharSet":"utf16le",
"bBomInc":true,
"sFileName":"*.csv",
"sFieldBoundary":"",
"sFieldSeperator":"\t",
"sNewLine":"auto",
"sTitle":"",
"sToolTip":"",
"sButtonClass":"DTTT_button_xls",
"sButtonClassHover":"DTTT_button_xls_hover",
"sButtonText":"Excel",
"sAjaxUrl":"/xhr.php",
"sParameters":"",
"sKeys":"",
"mColumns":"all",
"bHeader":true,
"bFooter":true,
"bSelectedOnly":false,
"fnMouseover":null,
"fnMouseout":null,
"fnClick":function(nButton,oConfig,flash){
varsData=this.fnGetExtXlsData(oConfig,"header");
varvkeys=oConfig.sKeys;
$.ajax({
"url":oConfig.sAjaxUrl,
"data":oConfig.sParameters,
"async":false,
"success":function(data){
$.each(data.jsondata,function(k,n){
sData+=(k+1)+"\t";
for(j=0;j<vkeys.length;j++){
sData+=""+eval("n[\""+vkeys[j]+"\"]")+"\t";
}
sData+="\r\n";
});
},
"dataType":"json",
"type":"POST"
});
sData+=this.fnGetExtXlsData(oConfig,"footer");
this.fnSetText(flash,sData);
},
"fnSelect":null,
"fnComplete":null,
"fnInit":null,
"fnAjaxComplete":null
},
此处是通过分析tabletools导出数据格式后进行修改的,只是加上了ajax后返回数据的填充,其他导出的header、footer都是于页面上保持一致。
@@另外java端设置json的名字应该为jsondata(必须一致)
fnGetExtXlsData方法
/**@methodfnGetExtXlsData
*@paramoConfig
*@returns
*/
"fnGetExtXlsData":function(oConfig,flag)
{
/*InfuturethiscouldbeusedtogetdatafromaplainHTMLsourceaswellasDataTables*/
if(this.s.dt)
{
returnthis._fnGetExtXlsData(oConfig,flag);
}
},
_fnGetExtXlsData方法
/**
*@paramoConfig
*@paramdata
*@returns{String}
*/
"_fnGetExtXlsData":function(oConfig,flag)
{
vari,iLen,j,jLen;
varsData='',sLoopData='';
vardt=this.s.dt;
varregex=newRegExp(oConfig.sFieldBoundary,"g");/*Doithereforspeed*/
varaColumnsInc=this._fnColumnTargets(oConfig.mColumns);
varsNewline=this._fnNewline(oConfig);
/*
*Header
*/
if(oConfig.bHeader&&flag=="header")
{
for(i=0,iLen=dt.aoColumns.length;i<iLen;i++)
{
if(aColumnsInc[i])
{
sLoopData=dt.aoColumns[i].sTitle.replace(/\n/g,"").replace(/<.*?>/g,"");
sLoopData=this._fnHtmlDecode(sLoopData);
sData+=this._fnBoundData(sLoopData,oConfig.sFieldBoundary,regex)+
oConfig.sFieldSeperator;
}
}
sData=sData.slice(0,oConfig.sFieldSeperator.length*-1);
sData+=sNewline;
}
/*
*Footer
*/
if(oConfig.bFooter&&flag=="footer")
{
for(i=0,iLen=dt.aoColumns.length;i<iLen;i++)
{
if(aColumnsInc[i]&&dt.aoColumns[i].nTf!==null)
{
sLoopData=dt.aoColumns[i].nTf.innerHTML.replace(/\n/g,"").replace(/<.*?>/g,"");
sLoopData=this._fnHtmlDecode(sLoopData);
sData+=this._fnBoundData(sLoopData,oConfig.sFieldBoundary,regex)+
oConfig.sFieldSeperator;
}
}
sData=sData.slice(0,oConfig.sFieldSeperator.length*-1);
}
/*Nopointershere-thisisastringcopy*/
//_sLastData=sData;
returnsData;
},
以上该方法只是借用插件原先实现的方式设置header与footer。
到此处应该说tabletools的源码改造部分完成,下面该是前端如何应用了,请继续往瞎看(硬着头皮也要继续(*^__^*)嘻嘻……)
【页面应用实例】
functionfillData2Tables(arr){
if(dateTable!=null){dateTable.fnClearTable();}
varqueryType=getQuertTypeValue();
varparameters={"queryType":queryType,
"startDate":$("#startDate").val(),
"endDate":$("#endDate").val(),
"singleDate":$("#singleDate").val(),
"userid":$("#userid").val(),
"userlevel":$("#userlevel").val()};
varvKeys=["nick","logintimes","userid","usertype","userlevel","shopid","shoptitle","shopcname","ddate"];
dateTable=$('#loginUser').dataTable({
"sDom":'T<"clear">lfrtip',
"oTableTools":{
"sSwfPath":"../3rd/datatables/media/TableTools/media/swf/copy_cvs_xls_pdf.swf",
"aButtons":[
{
"sExtends":"copy",
"sButtonText":"复制"
},
{
"sExtends":"xls",
"sButtonText":"导出Excel"
},
{
"sExtends":"ext-xls",
"sAjaxUrl":"yx/loginUser!ext.action",
"sParameters":parameters,
"sKeys":vKeys,
"sButtonText":"导出文件"
}
]
},
'sScrollX':'100%',
'sScrollXInner':'180%',
"sPaginationType":"full_numbers",
'bScrollCollapse':true,
'fnDrawCallback':function(oSettings){
if(oSettings.bSorted||oSettings.bFiltered){
for(vari=0,iLen=oSettings.aiDisplay.length;i<iLen;i++){
$('td:eq(0)',oSettings.aoData[oSettings.aiDisplay[i]].nTr).html(i+1);
}
}
},
'aoColumnDefs':[
{'bSortable':false,'sClass':'index','aTargets':[0]}
],
'aaSorting':[[1,'desc']]
});
dateTable.fnAddData(arr);
}
java端实现:
publicStringext()throwsException{
QueryConditionqc=wrapQueryCondition();
qc.setIsDownload(AppCons.ISDOWNLOAD);
List<DayLogin>dayLogins=fxbReportService.getDayLoginsByCondition(qc);
Map<String,Object>map=newHashMap<String,Object>();
map.put("jsondata",dayLogins);
Struts2Utils.renderJson(JSONObject.fromObject(map).toString());
returnnull;
}
以上红色部分,需要说明的是:
sAjaxUrl:请求的url地址
sParameters:请求的参数
sKeys:对应的json数据的key值,必须与页面table列一致(数量)
sExtends:此处是扩展tabletools的一个aButton项
4、在使用datatable结合tableTools时,最好该对象能够重用,而不是每次都创建新的,这样可以避免出现flash崩溃的情况,另一种方式就是多次创建也可以,不过要进行清除处理,也能避免flash崩溃情况。清理代码如下:
if($('#ZeroClipboardMovie_'+count)!=null){
$('#ZeroClipboardMovie_'+count).remove();
}
count++;
count是每次创建时,都会自动加1,这样才能匹配找到对应的对象。
5、当使用tabs结合datatable时,必须有一个主框架,简单说就是tabs里有四个选项,每个选项对应一个页面。总共就需要5个页面,其中一个页面就是用来包含其他4个页面,包括加载其他的js、css等(也许说的不是很明白,表达不够准确吧,呵呵)。
过段时间会整理关于fusioncharts的使用方式,其类似的问题也在datatable里出现过。