原生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