原生javascript实现简单的datagrid数据表格
简单的datagrid
1.排序自定义排序方式
2.编辑
3.拖拽
4.分页
5.单选多选(ctrl)线性选(shift)
6.文字render 就是给文字着色 比如大于0红色 小于0绿色
7.对列的显示隐藏
8.分组
只是一个示例 没有什么与后台的借口
其实可以写几个回调就行了 里面有loading条可以在没返回结果前一直显示
<!DOCTYPEhtml>
<htmlxmlns="http://www.w3.org/1999/xhtml">
<head>
<metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/>
<title>table</title>
<styletype="text/css">
*{margin:0;padding:0;}
.h{line-height:20px;}
.c{zoom:1;}
.c:after{content:".";display:block;height:0;clear:both;visibility:hidden;}
.l{float:left;}
.r{float:right;}
ul{list-style:none;}
.demo{width:832px;height:400px;font-size:12px;margin:20pxauto;position:relative}
.demo.m_a{margin-right:8px;}
.demo.nobreak{white-space:keep-all;*white-space:normal;text-overflow:ellipsis;overflow:hidden;height:22px;width:100%;}
.demo.container{
border:1pxsolid#99bbe8;
height:auto;
}
.demo.i_a{border:1pxsolid#ccc;margin-top:2px;}
.demo.t_a{border-left:1pxsolid#99bbe8;border-bottom:1pxsolid#99bbe8;}
.demo.t_atd{background-color:#fff;border-right:1pxsolid#ccc;border-top:1pxsolid#ccc;}
.demotabletd{
line-height:22px;
height:20px;
}
.demotablethead.theadfocus{
background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png)repeat-x0-163px;
}
.demotabletheadtd{
overflow:hidden;
}
.demo.t_atbodytd{padding-left:8px;}
.demo.title{height:24px;line-height:22px;font-weight:bold;padding-left:20px;color:#666666;background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png)repeat-x0-300px; }
.demo.bar{_display:inline-block;line-height:20px;height:20px;border-top:1pxsolid#99bbe8;background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png)repeat-x0-350px;padding:2px02px20px;}
.demo.f_a{color:#3b526e;font-weight:bold;}
.demo.first_div,.demo.prev_div,.demo.next_div,.demo.last_div,.demo.first_div_no,.demo.prev_div_no,.demo.next_div_no,.demo.last_div_no{float:left;width:18px;height:16px;margin-top:3px;cursor:pointer;display:block;margin-right:5px;background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png)no-repeat}
.demo.first_div{background-position:-12px-58px;}
.demo.first_div_no{background-position:4px-58px;cursor:normal}
.demo.prev_div{background-position:-11px-78px;}
.demo.prev_div_no{background-position:5px-78px;cursor:normal}
.demo.next_div{background-position:-65px-78px;}
.demo.next_div_no{background-position:-49px-78px;cursor:normal}
.demo.last_div{background-position:-67px-58px;}
.demo.last_div_no{background-position:-51px-58px;cursor:normal}
.demo.rowfocustd{background-color:#ebf2fb}
.demo.delbtn,.demo.delbtn:hover{background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png)no-repeat;width:45px;text-align:center;height:20px;color:#333;display:block;text-decoration:none;float:left;}
.demo.delbtn{background-position:-55px0;}
.demo.delbtn:hover{background-position:-55px-30px;color:#666}
.demotable{
font-size:12px;
table-layout:fixed;
-moz-user-select:-moz-none;
-webkit-user-select:none;
-khtml-user-select:none;
}
.demo.tabcontainer{
width:99%;
overflow:auto;
padding:2px002px;
background-color:#FFFBF7;
position:relative;
}
.demotabletheadtd{background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png)repeat-x0-100px;}
.demotabletheada{
z-index:1000;
background-color:#C3DAF9;
background-image:url("http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png");
display:none;
width:12px;
height:22px;
background-position:0-234px;
position:absolute;
top:0;
right:0;
}
.demotabletheaddiv{position:relative;z-index:1;}
.demotabletheadp{
width:1px;
height:22px;
background-color:#99BBE8;
float:left;
display:block;
cursor:e-resize;
margin-right:2px;
}
.demotabletr.trfocustd{
background-color:#ebf2fb
}
.demodivtable,.demodivtabletr,.demodivtabletrtd{
-moz-user-select:-moz-none;
-webkit-user-select:none;
}
.demotabletrtd{background-color:#fff;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.demo.loading{position:absolute;z-index:9999;left:0;top:0;background:#e5e5e5;filter:Alpha(opacity=50);opacity:0.5;-moz-opacity:0.5;-khtml-opacity:0.5;}
.demo.loaddiv{position:absolute;z-index:99999;width:98px;height:28px;border:1pxsolid#6593cf;background:#fffurl(http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png)repeat-x0-300px;padding:2px;}
.demo.loadgif{background:#fffurl(images/loading_small.gif)no-repeat4px5px;padding:5px0027px;width:68px;height:21px;border:1pxsolid#6593cf;}
.demo.loadtext{color:#000;}
.demo.edittable{border:1pxsolid#c4c4c4;}
.demo.edittabletd{background:#ebf2fb;height:24px;}
.demo.editbtn{padding:5px;width:100px;margin:0auto;background:#ebf2fb;border:1pxsolid#c4c4c4;border-top:none;}
.demo.delbtn,.ajaxTable.delbtn:hover{background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png)no-repeat;width:45px;text-align:center;height:20px;color:#333;display:block;text-decoration:none;float:left;}
.demo.delbtn{background-position:-55px0;}
.demo.delbtn:hover{background-position:-55px-30px;color:#666}
.demo.btn_a,.ajaxTable.btn_a:hover{cursor:pointer;background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png)no-repeat;text-align:center;padding-top:5px;width:45px;height:17px;display:block;float:left;cursor:pointer;text-decoration:none;}
.demo.btn_a{background-position:00;color:#333;}
.demo.btn_a:hover{background-position:0-30px;color:#666;}
.sort-asc.head_span{
height:12px;width:24px;
display:block;
float:left;
padding-right:18px;
background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png)no-repeatright-423px;
}
.head_span{float:left;line-height:22px;display:block;}
.sort-desc.head_span{
height:12px;width:24px;
display:block;
float:left;
padding-right:18px;
background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png)no-repeatright-391px;
}
.x-menu{
position:absolute;
background:url(menu.gif)repeat-y#f0f0f0;
border:1pxsolid#718bb7;
width:134px;
display:none;
}
.x-menu.disableda{
color:#999;
}
.x-menu-list{padding:2px;overflow:hidden;margin:0;}
.x-menu-listli{padding:1px;white-space:nowrap;height:20px;}
.x-menu-listli.focus{backround:#09F;}
a.x-menu-item{
display:block;
cursor:pointer;
line-height:18px;
height:20px;
outline-color:-moz-use-text-color;
outline-style:none;
outline-width:0;
width:100px;
padding-left:27px;
position:relative;
text-decoration:none;
white-space:nowrap;
font-size:12px;
color:#222;
}
a.x-m_a{padding-left:8px;width:120px;}
a.x-menu-iteminput{margin-right:8px}
a.x-menu-item:hover{background-color:#d9e8fb}
.asc{background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png)no-repeat-53px-218px;}
.desc{background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png)no-repeat-53px-243px;}
.columns{background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png)no-repeat-53px-268px;}
.submenu{
position:absolute;
z-index:1500;
background:#f0f0f0;
border:1pxsolid#718bb7;
width:134px;
display:none;
}
.x-menu-list.child-menu{background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png)no-repeatright-444px;}
a.x-m_a{padding-left:8px;width:120px;}
a.x-menu-iteminput{margin-right:8px}
a.x-menu-item:hover{background-color:#d9e8fb}
.line{
width:1px;background-color:#cccccc;position:absolute;display:none;z-index:100;
}
.red{
color:#FF0000;
}
.greed{
color:#33FF00;
}
</style>
</head>
<body>
1.排序自定义排序方式
<br>
2.编辑
<br>
3.拖拽
<br>
4.分页
<br>
5.单选多选(ctrl)线性选(shift)
<br>
6.文字render 就是给文字着色 比如大于0红色 小于0绿色
<br>
7.对列的显示隐藏
<br>
8.分组
<br>
<divid='demo'class='demo'></div>
<br><br>下面是分组的 且有一个自定义排序方式 很好一般很差<br><br>
<divid='demo1'class='demo'></div>
<scripttype="text/javascript">
(function(doc,undefined){
varwin=this;
win.Sys=function(ua){
varb={
ie:/msie/.test(ua)&&!/opera/.test(ua),
opera:/opera/.test(ua),
safari:/webkit/.test(ua)&&!/chrome/.test(ua),
firefox:/firefox/.test(ua),
chrome:/chrome/.test(ua)
},vMark="";
for(variinb){
if(b[i]){vMark="safari"==i?"version":i;break;}
}
b.version=vMark&&RegExp("(?:"+vMark+")[\\/:]([\\d.]+)").test(ua)?RegExp.$1:"0";
b.ie6=b.ie&&parseInt(b.version,10)==6;
b.ie7=b.ie&&parseInt(b.version,10)==7;
b.ie8=b.ie&&parseInt(b.version,10)==8;
returnb;
}(win.navigator.userAgent.toLowerCase());
win.Sys.ie6&&doc.execCommand("BackgroundImageCache",false,true);
win.$$=function(id){
returntypeofid==='string'
?doc.getElementById(id)
:id;
};
win.$q=function(name,parent){
returnparent.getElementsByTagName(name);
}
win.$c=function(name,parent){
varelem=typeofname==='object'?name:doc.createElement(name);
parent&&parent.appendChild(elem);
returnelem;
};
win.addListener=function(element,e,fn){
!element.events&&(element.events={});
element.events[e]&&(element.events[e][addListener.guid++]=fn)||(element.events[e]={'0':fn});
element.addEventListener?element.addEventListener(e,fn,false):element.attachEvent("on"+e,fn);
};
win.addListener.guid=1;
win.removeListener=function(element,e,fn){
varhandlers=element.events[e],type;
if(fn){
for(typeinhandlers)
if(handlers[type]===fn){
element.removeEventListener?element.removeEventListener(e,fn,false):element.detachEvent("on"+e,fn);
deletehandlers[type];
}
}else{
for(typeinhandlers){
element.removeEventListener?element.removeEventListener(e,handlers[type],false):element.detachEvent("on"+e,handlers[type]);
deletehandlers[type];
}
}
};
win.fireEvent=function(element,eventName){
if(element[eventName]){
element[eventName]();
}elseif(element.fireEvent){
element.fireEvent('on'+eventName);
}elseif(doc.createEvent){
varevt=doc.createEvent("MouseEvents");
evt.initEvent(eventName,true,true);
element.dispatchEvent(evt);
}
};
win.setStyle=function(elems,style,value){
if(!elems.length)elems=[elems];
if(typeofstyle=="string"){
style=value===undefined?{cssText:style}:(function(o){
return(o[style]=value,o);
})({});
};
each(elems,function(i,elem,style){
varvalue,name,ie=Sys.ie;
for(nameinstyle){
value=style[name];
if(name==="opacity"&&ie){
elem.style.filter=(elem.currentStyle.filter||"").replace(/alpha\([^)]*\)/,"")+"alpha(opacity="+value*100+")";
}elseif(name==="float"){
elem.style[ie?"styleFloat":"cssFloat"]=value;
}else{
name=name.replace(/-([a-z])/ig,function(all,letter){
returnletter.toUpperCase();
});
elem.style[name]=value;
}
}
},style);
};
win.setAttr=function(dom,attr){
if(typeofattr!=='object')
return;
for(varnameinattr)
dom.setAttribute(name,attr[name]);
}
varslice=Array.prototype.slice;
win.bind=function(object,fun){
varargs=slice.call(arguments).slice(2);
returnfunction(){
returnfun.apply(object,args);
};
};
win.bindAsEventListener=function(object,fun,args){
varargs=slice.call(arguments).slice(2);
returnfunction(event){
returnfun.apply(object,[event||win.event].concat(args));
}
};
win.extend=function(){
vartarget=arguments[0]||{},i=1,length=arguments.length,deep=true,options;
if(typeoftarget==="boolean"){
deep=target;
target=arguments[1]||{};
i=2;
}
if(typeoftarget!=="object"&&Object.prototype.toString.call(target)!="[objectFunction]")
target={};
for(;i<length;i++){
if((options=arguments[i])!=null)
for(varnameinoptions){
varsrc=target[name],copy=options[name];
if(target===copy)
continue;
if(deep&©&&typeofcopy==="object"&&!copy.nodeType){
target[name]=arguments.callee(deep,src||(copy.length!=null?[]:{}),copy);
}
elseif(copy!==undefined)
target[name]=copy;
}
}
returntarget;
};
win.Class=function(properties){
var_class=function(){
return(arguments[0]!==null&&this.initialize&&typeof(this.initialize)=='function')
?this.initialize.apply(this,arguments)
:this;
};
_class.prototype=properties;
return_class;
};
win.each= function(object,callback,args){
varname,i=0,length=object.length;
if(args){
args=Array.prototype.slice.call(arguments).slice(2);
if(length===undefined){
for(nameinobject)
if(callback.apply(object[name],[name,object[name]].concat(args))===false)
break;
}else
for(;i<length;i++)
if(callback.apply(object[i],[i,object[i]].concat(args))===false) //
break;
}else{
if(length===undefined){
for(nameinobject)
if(callback.call(object[name],name,object[name])===false)
break;
}else
for(varvalue=object[0];
i<length&&callback.call(value,i,value)!==false;value=object[++i]){}
}
returnobject;
};
win.currentStyle=function(element){
returnelement.currentStyle||doc.defaultView.getComputedStyle(element,null);
};
win.objPos=function(elem){
varleft=0,top=0,right=0,bottom=0,doc=elem?elem.ownerDocument:doc;
if(!elem.getBoundingClientRect||win.Sys.ie8){
varn=elem;
while(n){left+=n.offsetLeft,top+=n.offsetTop;n=n.offsetParent;};
right=left+elem.offsetWidth;bottom=top+elem.offsetHeight;
}else{
varrect=elem.getBoundingClientRect();
left=right=doc.documentElement.scrollLeft||doc.body.scrollLeft;
top=bottom=doc.documentElement.scrollLeft||doc.body.scrollLeft;
left+=rect.left;right+=rect.right;
top+=rect.top;bottom+=rect.bottom;
}
return{"left":left,"top":top,"right":right,"bottom":bottom};
};
win.contains=function(k,j){
returndocument.compareDocumentPosition
?k.compareDocumentPosition(j)&16
:k!==j&&k.contains(j);
};
win.hasClass=function(element,className){
returnelement.className.match(newRegExp('(\\s|^)'+className+'(\\s|$)'));
};
win.addClass=function(element,className){
if(!win.hasClass(element,className))
element.className.replace(/\s/g,'')===''
?element.className=className
:element.className+=""+className;
};
win.removeClass=function(element,className){
win.hasClass(element,className)&&(element.className=element.className.replace(newRegExp('(\\s*|^)'+className+'(\\s*|$)'),''));
}
})(document);
(function(doc,undefined){
varwin =this,
uuid =-1;
/*
检查字符串中是否有key
如果有且key后面是- 返回-后面的东西否则返回true
检测不到返回false
*/
functioncheckReg(str,key){
varreg=newRegExp('(?:^|\\s)'+key+'\\b-?(.*?)(?:\\s|$)','i');
if(reg.exec(str)!=null){
returnRegExp.$1===''?true:RegExp.$1;
}else{
returnfalse;
}
};
/*
修改字符串中key对应的value
*/
functionmodify(str,key,value){
varreg=newRegExp('(^|\\s)('+key+'\\b-).*?(\\s|$)','i');
returnstr.replace(reg,'$1$2'+value+'$3');
};
win.easyGrid=newClass({
options :{
perPage :10,
currPage :0,
totalPage :0,
count :10,
page :0,
isEdit :false,
widthConfig :{
td :null,
prevTd :null,
x :0,
tdWidth :0,
prevWidth:0
},
cellMinWidth:50,
sortType:{
int :function(v){returnparseInt(v)},
float :function(v){returnparseFloat(v)},
date :function(v){returnv.toString()},
string:function(v){returnv.toString()}
},
title :'标题'
},
initialize:function(options){
varop =extend(true,{},this.options),
options =this.defaults=extend(op,options),
container =this.container=$c('div',options.container),
dataConfig=options.dataConfig,
title =$c('div',container);
container.className='container';
title.innerHTML=options.title;
title.className='title';
this.primaryKey=options.primaryKey;
this.top=$c('div',container);
this.top.className='bar';
this.top.innerHTML='<divclass="c"><a href="javascript:;"class="first_div_no"page="start"></a><ahref="javascript:;"class="prev_div_no"page="next"></a><divclass="br"></div><divclass="lm_a"><inputtype="text"style="width:40px"class="i_a"/></div><divclass="br"></div><ahref="javascript:;"class="next_div"page="pre"></a><ahref="javascript:;"class="last_div"page="end"></a><divclass="br"></div><ahref="javascript:;"class="delbtnm_a"go="go">跳转</a><ahref="javascript:;"class="delbtn"del="del">删除</a><divclass="rm_a">当前第<spanclass="f_a"></span>页总共<spanclass="f_a"></span>页一页<spanclass="f_a"></span>条数据共<spanclass="f_a"></span>条数据</div></div>';
vartabContainer=this.tabContainer =$c('div',container);
this.bottom=$c(this.top.cloneNode(true),container);
tabContainer.className='tabcontainer';
tabContainer.style.height= ~~options.container.offsetHeight-83+'px';
vartable=this.table=$c('table',tabContainer);
table.className='t_a';
setAttr(table,{cellpadding:"0",cellspacing:"0",border:"0"});
this.thead=$c('thead',table);
this.tbody=$c('tbody',table);
this.tbody.style.display='none';
//loading条
this.loading_bg=$c('div',container);
this.loading_bg.className='loading';
setStyle(this.loading_bg,{
width :container.offsetWidth+2+'px',
height:container.offsetHeight+2+'px'
});
this.loading=$c('div',container);
this.loading.className='loaddiv'
setStyle(this.loading,{
left:(container.offsetWidth/2-45)+'px',
top:(container.offsetHeight/2-14)+'px'
});
this.loading.innerHTML='<divclass="loadgif">Loading...</div>';
//表格有多少列
this.colCount=options.fields.length;
//数据源形式是 [[],[],[],[],[],[]]
this.data =[];
//当前请求到的数据源中 所有的分组头形式是[trdom1,trdom2]
this.grouphead =[];
//记录已经插入table的分组的tr [tr1,tr2,tr3]
this.insertTrs=[];
//列索引
//形式[[td11,td12,td13,td14],[td21,td22,td23,td24]]
this.columns=[];
//true表示正序false表示反序
this.ascSort=true;
//保存哪一列正在排序中的表头td
this.sortColumn='';
//所有tr行 如果没有分组形式是[tr1,tr2,tr3,tr4]
//如果有分组 [[tr1,tr2,tr3,tr4],[tr5,tr6,tr7,tr8]]
this.rows=[];
//一级菜单
this.popMenu=$c('div',doc.body);
this.popMenu.className='x-menu';
this.popMenu.innerHTML='<ulclass="x-menu-list"><li><ahref="javascript:;"class="x-menu-itemasc"menuType="asc">升序</a></li><li><ahref="javascript:;"class="x-menu-itemdesc"menuType="desc">降序</a></li><li><ahref="javascript:;"class="x-menu-itemcolumns"menuType="columns">所有列</a></li></ul>';
//创建子菜单
this.subPopMenu=$c('div',doc.body);
this.subPopMenu.className='submenu';
//表头的第一级弹出层是否打开如果打开 保存该td
this.isMenuOpen=false;
//保存列所有列中某一列是否显示或隐藏num为计数器看有多少列是现实中的
//格式 clos:[true,false,true,true]1,3,4列显示 第2列隐藏
this.isShowTrs={
num:0,
clos:[]
};
//创建拖动时显示的基准线
this.line=$c('div',doc.body);
this.line.className='line';
//保存行
//属性为uuid的递增量如{1:dom,2:dom}
this.selectedRows={};
//保存最后选中的行
this.lastSelectRow={dom:null,index:null};
this.currentEditRow={index:0,dom:null};
this.editData=[];
this.editForm=$c('div',tabContainer);;
setStyle(this.editForm,{
position:'absolute',
display :'none',
'z-index':'120'
});
this.editTable=$c('table',this.editForm);
setAttr(this.editTable,{
cellspacing:'0',
cellpadding:'0',
border:'0'
});
varbtnC=$c('div',this.editForm);
btnC.className='editbtn';
btnC.style.textAlign='center';
btnC.innerHTML='<divclass="c"><aclass="btn_am_a"do="submit"href="javascript:;">提交</a><aclass="btn_a"do="cancel"href="javascript:;">取消</a></div>';
this.editTable.className='edittable';
varetr=$c('tr',$c('tbody',this.editTable));
//创建一个tr的副本 因为后面生成tr的时候可以直接复制节点
this.copyTr =$c('tr');
this.groupTr=$c('tr');
this.groupTr.setAttribute('g','y');
varctd=$c('td',this.groupTr)
ctd.setAttribute('colSpan',options.fields.length);
vartheadTr=$c('tr',this.thead),
tWidth =0,
self =this,
ul =$c('ul',this.subPopMenu),
li;
each(options.fields,function(i,o){
vartd=$c('td',theadTr),
width=o.width?o.width:'80',
div=i===0?'<divclass="cnobreak">':'<divclass="cnobreak"><p></p>';
td.innerHTML=[div,'<spanclass="head_span">',o.name,'</span><ahref="javascript:;"></a></div>'].join('');
setAttr(td,{clos:i,width:width,unselectable:'on','class':o.type===undefined?'':'type-'+o.type});
self.createInput(i,o,etr);
tWidth=tWidth+(~~width);
li=$c('li',ul);
li.innerHTML=[
'<ahref="javascript:;"class="x-menu-itemx-m_a"><inputtype="checkbox"checked="true" cols="',
i,
'"/>',
o.name,
'</a>'
].join('');
//生成列索引的 每列的第一项
self.columns[i]=[td];
$c('td',self.copyTr).setAttribute('unselectable','on');
//计算出所显示的列索引和一共多少列num
self.isShowTrs.num++;
self.isShowTrs.clos[i]=true;
});
setAttr(this.table,{width:tWidth+options.fields.length+1})
//生成tbody里面的tr只是生成tr根据perPage生成它是显示当前一共有多少条数据的配置项
vari=0,
trsLen=options.perPage,
frag =doc.createDocumentFragment(),
arr =newArray(options.fields.length),
tr,
tds;
for(;i<trsLen;i++){
tr =this.copyTr.cloneNode(true);
tds=$q('td',tr);
each(arr,function(i){
//生成列索引的所有项
self.columns[i].push(tds[i]);
});
$c(tr,frag);
}
this.tbody.appendChild(frag);
if(typeofdataConfig==='object'){
setTimeout(function(){self.getDataCallBack(dataConfig);},5);
}else{
}
/*
表格拖拽
表格排序
等一些操作
*/
addListener(this.thead,'click',bindAsEventListener(this,this.sortTable));
addListener(this.thead,'mouseover',bindAsEventListener(this,this.theadOver));
addListener(this.thead,'mouseout',bindAsEventListener(this,this.theadOut));
addListener(this.thead,'mousedown',bindAsEventListener(this,this.dragWidth));
/*
绑定弹出层click事件 进行排序
第2级菜单绑定 进行对列隐藏显示
*/
addListener(this.popMenu,'click',bindAsEventListener(this,this.menuClick));
addListener(this.popMenu,'mouseover',bindAsEventListener(this,this.menuOver));
addListener(this.subPopMenu,'click',bindAsEventListener(this,this.subMenuClick));
/*
放上去表格行的内容变粗
*/
addListener(this.tbody,'mousemove',bindAsEventListener(this,this.rowHighlight,true));
addListener(this.tbody,'mouseout',bindAsEventListener(this,this.rowHighlight,false));
addListener(this.tbody,'mousedown',bindAsEventListener(this,this.selectRow,false));
addListener(this.tbody,'dblclick',bindAsEventListener(this,this.editRow,false));
addListener(btnC,'click',bindAsEventListener(this,this.modifyTr));
addListener(this.top,'click',bindAsEventListener(this,this.pageBarClick));
addListener(this.bottom,'click',bindAsEventListener(this,this.pageBarClick));
},
getDataCallBack:function(data){
varoptions=this.defaults,
self =this,
totla =0;
this.data.length=0;
if(data.data){
if(data.data[0].groupName){
vargrouphead=this.grouphead;
grouphead.length=0;
each(data.data,function(i,o){
vargtr=self.groupTr.cloneNode(true);
$q('td',gtr)[0].innerHTML=o.groupName;
grouphead.push(gtr);
each(o.rows,function(j,d){
//this.data中数据的最后一项是索引
d.push(i);
self.data.push(d);
});
});
this.showGroup=true;
}else{
each(data.data,function(i,o){
self.data.push(o);
});
this.showGroup=false;
}
}else{
return;
}
total=data.total
?data.total>=this.data.length
?data.total
:this.data.length
:this.data.length;
this.writeMessage(total);
this.buildTbody(options.currPage);
},
buildTbody:function(pageNum){
if(this.data.length===0){
this.tbody.style.display='none';
return;
}
vari =0,
j =0,
self =this,
data =this.data,
options=this.defaults,
trsLen =options.perPage,
tdsLen =options.fields.length,
tbody =this.tbody,
trs =tbody.getElementsByTagName('tr'),
start =pageNum*options.perPage,
tr;
this.rows.length=0;
if(this.showGroup){
vargroup={},
index,
arr=[],
insertTrs=this.insertTrs;
//清除掉之前插入的分组tr
insertTrs.length!=0&&each(insertTrs,function(i,o){
self.tbody.removeChild(o);
});
insertTrs.length=0;
//遍历填充数据 给this.rows赋值
varnum=-1;
for(;i<trsLen;i++){
tr =trs[i];
//如果没有数据了 就开始隐藏剩下的行
if(!data[i+start]){
tr.style.display='none';
continue;
}
//做标记tr里面的内容对应data中哪条数据
tr.setAttribute('dataIndex',i+start);
tr.style.display='block';
tds=tr.getElementsByTagName('td');
//x为分组的不同组的标识
varx=data[i+start][data[i+start].length-1];
//用来判断后来的数据和之前的数据是不是同一个组的
//如果是同一个组的选this.rows的最后一列添加
//不是同一个组的创建一列添加
num==x
?this.rows[this.rows.length-1].push(tr)
:(this.rows[this.rows.length]=[tr],num=x);
//用数组arr记住每个分组的的第一个tr的位置因为后面要插入tr头 i为位置num为分组的序号
!(numingroup)&&(group[num]=i+start,arr.push([num,i]));
for(j=0;j<tdsLen;j++){
td=tds[j];
vartxt =data[i+start][j]===''?' ':data[i+start][j];
render=options.fields[j].render;
td.innerHTML=render
?render(txt)
:txt;
}
tr.style.display='';
}
each(arr.reverse(),function(i,o){
insertTrs.push(self.grouphead[o[0]]);
self.tbody.insertBefore(self.grouphead[o[0]],trs[o[1]]);
});
}else{
for(;i<trsLen;i++){
tr =trs[i];
//做标记tr里面的内容对应data中哪条数据
tr.setAttribute('dataIndex',i+start);
this.rows.push(tr);
//没有数据的tr隐藏掉
if(!data[i+start]){
tr.style.display='none';
continue;
}
tr.style.display='';
tds=$q('td',tr);
for(j=0;j<tdsLen;j++){
vartxt =data[i+start][j]===''?' ':data[i+start][j];
render=options.fields[j].render;
tds[j].innerHTML=render
?render(txt)
:txt;
}
}
}
options.currPage=pageNum;
this.top.getElementsByTagName('span')[0].innerHTML=this.bottom.getElementsByTagName('span')[0].innerHTML=~~pageNum+1;
vartopAs=this.top.getElementsByTagName('a'),
bottomAs=this.bottom.getElementsByTagName('a');
if(options.totalPage===1){
bottomAs[0].className=topAs[0].className='first_div_no';
bottomAs[1].className=topAs[1].className='prev_div_no';
bottomAs[2].className=topAs[2].className='next_div_no';
bottomAs[3].className=topAs[3].className='last_div_no';
}elseif(options.currPage===0){
bottomAs[0].className=topAs[0].className='first_div_no';
bottomAs[1].className=topAs[1].className='prev_div_no';
bottomAs[2].className=topAs[2].className='next_div';
bottomAs[3].className=topAs[3].className='last_div';
}elseif(options.currPage+1===options.totalPage){
bottomAs[0].className=topAs[0].className='first_div';
bottomAs[1].className=topAs[1].className='prev_div';
bottomAs[2].className=topAs[2].className='next_div_no';
bottomAs[3].className=topAs[3].className='last_div_no';
}else{
bottomAs[0].className=topAs[0].className='first_div';
bottomAs[1].className=topAs[1].className='prev_div';
bottomAs[2].className=topAs[2].className='next_div';
bottomAs[3].className=topAs[3].className='last_div';
}
this.tbody.style.display='';
this.loading_bg.style.display='none';
this.loading.style.display='none';
},
writeMessage:function(total){
varoptions =this.defaults,
base =total/options.perPage,
topSpans =this.top.getElementsByTagName('span'),
bottomSpans=this.bottom.getElementsByTagName('span');
options.totalPage=base>parseInt(base)
?parseInt(base)+1
:base;
bottomSpans[0].innerHTML=topSpans[0].innerHTML=~~options.currPage+1;
bottomSpans[1].innerHTML=topSpans[1].innerHTML=options.totalPage;
bottomSpans[2].innerHTML=topSpans[2].innerHTML=options.perPage;
bottomSpans[3].innerHTML=topSpans[3].innerHTML=total;
},
sortTable:function(e){
varelem=e.target||e.srcElement,
self=this,
options =this.defaults,
elemName =elem.nodeName.toLowerCase(),
showGroup=this.showGroup,
tdElem =elem,
name =elemName;
//拖拽的时候可能会触发一次click原因是ie下全部绑定在this.table上代码见拖拽
if($q('td',elem).length>1)
return;
if(name!=='td'){
while(name!=='td'){
tdElem=tdElem.parentNode;
name=tdElem.nodeName.toLowerCase();
}
}
varissort=checkReg(tdElem.className,'sort'),
type =checkReg(tdElem.className,'type')
//进行排序
if(elemName!=='a'&&type){
varfrag=doc.createDocumentFragment();
if(this.sortColumn!==tdElem&&this.sortColumn!==''){
removeClass(this.sortColumn,'sort-asc');
removeClass(this.sortColumn,'sort-desc');
}
if(issort){
//有分组,每组单独取反序 不分组,直接取反序
showGroup
?each(this.rows,function(i,o){o.reverse();})
:this.rows.reverse();
tdElem.className=modify(tdElem.className,'sort',issort==='asc'?'desc':'asc');
}else{
showGroup
?each(this.rows,function(i,o){
o.sort(self.compare(tdElem.getAttribute('clos'),type));
})
:this.rows.sort(this.compare(tdElem.getAttribute('clos'),type));
//如果是正序排序,加上正序排列的标志。
if(this.ascSort){
addClass(tdElem,'sort-asc');
}else{
//反序排列则将原有排序取反,并加上排序标志
showGroup
?each(this.rows,function(i,o){o.reverse();})
:this.rows.reverse();
addClass(tdElem,'sort-desc');
}
}
//将排序后的数据渲染到表格
varinsertTrs=this.insertTrs,
len=insertTrs.length-1,
arr=[];
each(this.rows,function(i,tr){
arr=[insertTrs[len-i]].concat(tr);
showGroup
?each(arr,function(idx,obj){frag.appendChild(obj);})
:frag.appendChild(tr);
});
this.tbody.appendChild(frag);
this.sortColumn=tdElem;
}
//-------------------------------------------------------------------------------------
/*
如果点击的是表头中的A标签,则弹出菜单
*/
if(elemName==='a'){
/*
当在菜单外面点击的时候会执行改函数
用于清空document的click事件 隐藏层去掉td,a的样式
*/
functiondocumentClick(){
self.popMenu.style.display='none';
self.subPopMenu.style.display='none';
if(self.isMenuOpen){
removeListener(document,'click');
removeClass($q('div',self.isMenuOpen)[0],'theadfocus');
$q('a',self.isMenuOpen)[0].style.display='none';
}
self.isMenuOpen=false;
}
varpos =objPos(elem),
left=pos.left+Math.max(document.documentElement.scrollLeft,document.documentElement.scrollLeft),
top =pos.top+Math.max(document.documentElement.scrollTop,document.documentElement.scrollTop)+elem.offsetHeight,
td =elem.parentNode.parentNode,
lis =$q('li',this.popMenu);
//如果this.isMenuOpen是真表示层是打开状态的 执行关闭相关的处理
this.isMenuOpen&&documentClick();
if(!checkReg(td.className,'type')){
addClass(lis[0],'disabled');
addClass(lis[1],'disabled');
}else{
removeClass(lis[0],'disabled');
removeClass(lis[1],'disabled');
}
Sys.ie
?e.cancelBubble=true
:e.stopPropagation();
//当显示层的时候吧该td附到this.isMenuOpen上
this.isMenuOpen=td;
addListener(document,'click',documentClick);
setStyle(this.popMenu,{
left :left+'px',
top :top+'px',
display:'block'
});
}
},
compare:function(n,type){
varsortType=this.defaults.sortType,
txt=Sys.ie?'innerText':'textContent';
!sortType[type]&&(type='string');
returnfunction(a1,a2){
a1=sortType[type](a1.cells[n][txt]);
a2=sortType[type](a2.cells[n][txt]);
returna1==a2?0:a1<a2?1:-1;
}
},
pageBarClick:function(e){
var elem =e.target||e.srcElement,
options =this.defaults,
typePage=elem.getAttribute('page'),
isGo =elem.getAttribute('go');
isDel =elem.getAttribute('del');
if(typePage){
varnumber={
start:0,
end :options.totalPage-1,
next :options.currPage-1,
pre :options.currPage+1
}[typePage];
this.toPage(number);
}
if(isDel){
this.del();
}
if(isGo){
varnumber=~~elem.parentNode.getElementsByTagName('input')[0].value-1;
this.toPage(number);
}
},
toPage:function(num){
if(typeofnum!=='number'||isNaN(num))return;
varoptions =this.defaults,
self =this,
dataConfig=options.dataConfig;
//如果请求的分页数小于0就默认为0 如果打越最大分页数就默认为最大分页数
num>=options.totalPage
&&(num=options.totalPage-1);
num<0&&(num=0);
//s为当前面板的第一页 e为当前面板的最后
varbasePage=options.count/options.perPage,
s=options.page*basePage,
e=s+basePage-1;
this.tbody.style.display='none';
this.loading_bg.style.display='';;
this.loading.style.display='';
setTimeout(function(){self.buildTbody(num);},10);
},
del:function(){
//做删除的时候需要有主键的索引 我全部保存在tr的
varselectedRows=this.selectedRows,
arr=[]
for(varnameinselectedRows){
arr.push(selectedRows[name].getAttribute('dataIndex'));
}
alert('选择了主键值为'+arr.join(','));
},
theadOver:function(e){
varelem=e.target||e.srcElement;
if(elem.nodeName.toLowerCase()==='div'){
$q('a',elem)[0].style.display='block';
addClass(elem,'theadfocus');
}
},
theadOut:function(e){
varelem =e.target||e.srcElement,
toElem =e.toElement||e.relatedTarget,
elemName=elem.nodeName.toLowerCase();
if(this.isMenuOpen&&contains(this.isMenuOpen,elem))
return;
//如果离开了当前的td隐藏显示出来的东西
if(elemName==='div'&&elem!==this.isMenuOpen){
if(!contains(elem,toElem)){
$q('a',elem)[0].style.display='none';
removeClass(elem,'theadfocus');
}
}
if(elemName==='a'||elemName==='span'||elemName==='p'){
var parent=elem.parentNode;
if(!contains(elem,toElem)){
$q('a',parent)[0].style.display='none';
removeClass(parent,'theadfocus');
}
}
},
menuClick:function(e){
varelem =e.target||e.srcElement,
className =this.isMenuOpen.className;
if(elem.nodeName.toLowerCase()==='a'){
//如果td的样式中不存在type也就是说不需要排序则不进行排序阻止事件冒泡
if(!checkReg(className,'type')){
Sys.ie
?e.cancelBubble=true
:e.stopPropagation();
return;
}
//如果a标签的menuType
varmenuOp=elem.getAttribute('menuType'),
sortOrder=checkReg(className,'sort');
//选择所有列 不进行排序
if(menuOp==='columns')
return;
/*
如果没有排序 就根据menuOp来进行排序
如果已排序 且与menuOp排序方式不同 则进行排序
*/
if(sortOrder){
if(menuOp!=sortOrder){
vartd=$q('td',this.thead)[this.isMenuOpen.getAttribute('clos')];
fireEvent(td,'click');
}
}else{
this.ascSort={
desc:false,
asc :true
}[menuOp];
vartd=$q('td',this.thead)[this.isMenuOpen.getAttribute('clos')];
fireEvent(td,'click');
}
//完成上面的操作后设置成正序 因为之后点别的列默认还是按正序列来排
this.ascSort=true;
}
},
menuOver:function(e){
varelem=e.target||e.srcElement;
if(elem.nodeName.toLowerCase()==='a'&&elem.getAttribute('menuType')==='columns'){
varpos =objPos(elem),
left=pos.left+Math.max(document.documentElement.scrollLeft,document.documentElement.scrollLeft)+elem.offsetWidth,
top =pos.top+Math.max(document.documentElement.scrollTop,document.documentElement.scrollTop);
setStyle(this.subPopMenu,{left:left+'px',top:top+'px',display:'block'});
}
},
subMenuClick:function(e){
varelem=e.target||e.srcElement,
isA =elem.nodeName.toLowerCase()==='a';
Sys.ie
?e.cancelBubble=true
:e.stopPropagation();
if(isA||elem.nodeName.toLowerCase()==='input'){
varinput=isA
?$q('input',elem.parentNode)[0]
:elem,
clos =input.getAttribute('cols'),
self =this;
isA
&&(input.checked=(!input.checked));&nbs