原生javascript实现简单的datagrid数据表格


Posted in Javascript onJanuary 02, 2015

简单的datagrid

1.排序 自定义排序方式

2.编辑

3.拖拽

4.分页

5.单选 多选(ctrl) 线性选(shift)

6.文字render  就是给文字着色  比如 大于0红色  小于0绿色

7.对列的显示隐藏

8.分组

只是一个示例  没有什么与后台的借口

其实可以写几个回调就行了  里面有loading条 可以在没返回结果前一直显示

 <!DOCTYPE html >

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>table</title>

<style type="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:20px auto; 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:1px solid #99bbe8;

 height:auto;

}

.demo .i_a{border:1px solid #ccc;margin-top:2px;}

.demo .t_a{border-left:1px solid #99bbe8;border-bottom:1px solid #99bbe8;}

.demo .t_a td{background-color:#fff;border-right:1px solid #ccc;border-top:1px solid #ccc;}

.demo table td{

 line-height:22px;

 height:20px;

}

.demo table thead .theadfocus{

 background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png) repeat-x 0 -163px;

}

.demo table thead td{

 overflow:hidden;

}

.demo .t_a tbody td{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-x 0 -300px; }

.demo .bar{_display:inline-block;line-height:20px; height:20px; border-top:1px solid #99bbe8; background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png) repeat-x 0 -350px;padding:2px 0 2px 20px;}

.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 .rowfocus td{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:-55px 0;}

.demo .delbtn:hover{background-position:-55px -30px;color:#666}

.demo table{

 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 :2px 0 0 2px;

background-color:#FFFBF7;

position:relative;

}

.demo table thead td{background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png) repeat-x 0 -100px;}

.demo table thead a{

 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;

}

.demo table thead div{ position:relative; z-index:1;}

.demo table thead p{

 width:1px;

 height:22px;

 background-color:#99BBE8;

 float:left;

 display:block;

 cursor:e-resize;

 margin-right:2px;

}

.demo table tr.trfocus td{

 background-color:#ebf2fb

}

.demo div table,.demo div table tr,.demo div table tr td{

 -moz-user-select: -moz-none;

 -webkit-user-select:none;

}

.demo table tr td{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:1px solid #6593cf;background:#fff url(http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png) repeat-x 0 -300px;padding:2px;}

.demo .loadgif{background:#fff url(images/loading_small.gif) no-repeat 4px 5px; padding:5px 0 0 27px;width:68px;height:21px;border:1px solid #6593cf;}

.demo .loadtext{color:#000;}

.demo .edittable{border:1px solid #c4c4c4;}

.demo .edittable td{background:#ebf2fb;height:24px;}

.demo .editbtn{padding:5px;width:100px;margin:0 auto;background:#ebf2fb;border:1px solid #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:-55px 0;}

.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:0 0;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-repeat right -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-repeat right -391px;

}

.x-menu{

 position:absolute;

 background:url(menu.gif) repeat-y #f0f0f0;

 border:1px solid #718bb7;

 width:134px;

 display:none;

}

.x-menu .disabled a{

 color:#999;

}

.x-menu-list{padding:2px; overflow:hidden; margin:0;}

.x-menu-list li{padding:1px; white-space:nowrap; height:20px;}

.x-menu-list li.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-item input{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:1px solid #718bb7;

 width:134px;

 display:none;

}

.x-menu-list .child-menu{background:url(http://images.cnblogs.com/cnblogs_com/wtcsy/294024/r_ajaxtable.png) no-repeat right -444px;}

a.x-m_a{padding-left:8px;width:120px;}

a.x-menu-item input{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>

<div id='demo' class='demo'></div>

<br><br>下面是分组的  且有一个自定义排序方式  很好 一般 很差<br><br>

<div id='demo1' class='demo'></div>

<script type="text/javascript">

(function(doc,undefined){

 var win = this;

 win.Sys = function (ua){

  var b = {

   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 (var i in b) {

   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;  

  return b;

 }(win.navigator.userAgent.toLowerCase());

 

 win.Sys.ie6&&doc.execCommand("BackgroundImageCache", false, true);

 

 win.$$ = function(id){

  return typeof id === 'string'

   ? doc.getElementById(id)

   : id;

 };

 win.$q = function(name,parent){

  return parent.getElementsByTagName(name);

 }

 win.$c = function(name,parent){

  var elem = typeof name ==='object'? name : doc.createElement(name);

  parent&&parent.appendChild(elem);

  return elem;  

 };

 

 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){

  var handlers = element.events[e],type;

  if(fn){

   for(type in handlers)

    if(handlers[type]===fn){

     element.removeEventListener?element.removeEventListener(e,fn,false):element.detachEvent("on" + e,fn);

     delete handlers[type];

    }

  }else{

   for(type in handlers){

    element.removeEventListener?element.removeEventListener(e,handlers[type],false):element.detachEvent("on" + e,handlers[type]);

    delete handlers[type];

   }

  }       

 };

 win.fireEvent = function(element,eventName){

  if(element[eventName]){

   element[eventName]();

  }else if(element.fireEvent){

   element.fireEvent('on'+eventName);

  }else if(doc.createEvent){

   var evt = doc.createEvent("MouseEvents");

   evt.initEvent(eventName, true, true);

   element.dispatchEvent(evt);

  } 

 };

 win.setStyle = function(elems, style, value){

  if( !elems.length ) elems = [elems];

  if( typeof style == "string"){       

   style = value === undefined?{cssText:style}:(function(o){

    return (o[style] = value,o);           

   })({});

  };

  each(elems,function(i,elem,style){

   var value,name,ie=Sys.ie ;

   for(name in style){

    value = style[name];

    if (name === "opacity" && ie) {

     elem.style.filter = (elem.currentStyle.filter || "").replace( /alpha\([^)]*\)/, "" ) + "alpha(opacity=" + value * 100 + ")";

    }else if(name === "float"){

     elem.style[ ie ? "styleFloat" : "cssFloat" ] = value;

    }else{

     name = name.replace(/-([a-z])/ig, function(all, letter){

      return letter.toUpperCase();

     });

     elem.style[name] = value;

    }

   }

  },style);

 };

 win.setAttr = function(dom,attr){

  if(typeof attr !== 'object')

   return;

  for(var name in attr)

   dom.setAttribute(name,attr[name]);

 }

 

 var slice = Array.prototype.slice;

 win.bind = function(object, fun) {

  var args = slice.call(arguments).slice(2);

  return function() {

    return fun.apply(object, args);

  };

 };

 

 win.bindAsEventListener = function(object, fun,args) {

  var args = slice.call(arguments).slice(2);

  return function(event) {

   return fun.apply(object, [event || win.event].concat(args));

  }

 };

 win.extend = function(){

  var target = arguments[0] || {}, i = 1, length = arguments.length, deep = true, options;

  if ( typeof target === "boolean" ) {

   deep = target;

   target = arguments[1] || {};

   i = 2;

  }

  if ( typeof target !== "object" && Object.prototype.toString.call(target)!="[object Function]")

   target = {};

  for(;i<length;i++){

   if ( (options = arguments[ i ]) != null )

    for(var name in options){

     var src = target[ name ], copy = options[ name ];

     if ( target === copy )

      continue;

     if ( deep && copy && typeof copy === "object" && !copy.nodeType ){

      target[ name ] = arguments.callee( deep, src || ( copy.length != null ? [ ] : { } ), copy );

     }   

     else if(copy !== undefined)

      target[ name ] = copy;                       

    }

  }

  return target;           

 };

 

 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 ) {  

  var name, i = 0, length = object.length;  

  if ( args ) {

   args = Array.prototype.slice.call(arguments).slice(2);

   if ( length === undefined ) {  

    for ( name in object )  

     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 ( name in object )  

     if ( callback.call( object[ name ], name, object[ name ] ) === false )  

      break;  

   } else

    for ( var value = object[0];  

     i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}  

  }  

  return object;  

 };  

 win.currentStyle = function(element){

  return element.currentStyle || doc.defaultView.getComputedStyle(element, null);

 };

 win.objPos = function(elem){

  var left = 0, top = 0, right = 0, bottom = 0,doc = elem ? elem.ownerDocument : doc;

  if ( !elem.getBoundingClientRect || win.Sys.ie8 ) {

   var n = elem;

   while (n) { left += n.offsetLeft, top += n.offsetTop; n = n.offsetParent; };

   right = left + elem.offsetWidth; bottom = top + elem.offsetHeight;

  } else {

   var rect = 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){

  return document.compareDocumentPosition

   ? k.compareDocumentPosition(j)&16

   : k!==j&&k.contains(j);

 };

 win.hasClass = function(element, className){

  return element.className.match(new RegExp('(\\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(new RegExp('(\\s*|^)'+className+'(\\s*|$)'),' '));

 }

})(document);

(function(doc,undefined){

 var win      = this,

  uuid    = -1;

 /*  

  检查 字符串 中是否有key 

  如果有 且key后面是-  返回-后面的东西 否则返回true

  检测不到返回false

 */

 function checkReg(str,key){

  var reg = new RegExp('(?:^|\\s)'+key+'\\b-?(.*?)(?:\\s|$)','i');

  if(reg.exec(str)!=null){

   return RegExp.$1===''?true:RegExp.$1;

  }else{

   return false; 

  }

 };

 /*

  修改字符串中key对应的value

 */

 function modify(str,key,value){

  var reg = new RegExp('(^|\\s)('+key+'\\b-).*?(\\s|$)','i'); 

  return str.replace(reg,'$1$2'+value+'$3');

 }; 

 win.easyGrid = new Class({

  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){return parseInt(v)},

    float  : function(v){return parseFloat(v)},

    date   : function(v){return v.toString()},

    string : function(v){return v.toString()}

   },   

   title        : '标题'  

  },      

  initialize : function(options){

   var op         = 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 = '<div class="c"><a  href="javascript:;" class="first_div_no" page="start"></a><a href="javascript:;" class="prev_div_no" page="next"></a><div class="br"></div><div class="l m_a"><input type="text" style="width:40px" class="i_a" /></div><div class="br"></div><a href="javascript:;" class="next_div" page="pre"></a><a href="javascript:;" class="last_div" page="end"></a><div class="br"></div><a href="javascript:;" class="delbtn m_a" go="go">跳转</a><a href="javascript:;" class="delbtn" del="del">删除</a><div class="r m_a">当前第<span class="f_a"></span>页 总共<span class="f_a"></span>页 一页<span class="f_a"></span>条数据 共<span class="f_a"></span>条数据</div></div>';

   var tabContainer = this.tabContainer  = $c('div',container);

   this.bottom = $c(this.top.cloneNode(true),container);

   tabContainer.className = 'tabcontainer';

   tabContainer.style.height =  ~~options.container.offsetHeight - 83+'px';

   var table = 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 = '<div class="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 = '<ul class="x-menu-list"><li><a href="javascript:;" class="x-menu-item asc" menuType="asc">升序</a></li><li><a href="javascript:;" class="x-menu-item desc" menuType="desc">降序</a></li><li><a href="javascript:;" class="x-menu-item columns" 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'

   });

   var btnC = $c('div',this.editForm);

   btnC.className = 'editbtn';

   btnC.style.textAlign = 'center';

   btnC.innerHTML = '<div class="c"><a class="btn_a m_a" do="submit" href="javascript:;">提交</a><a class="btn_a" do="cancel" href="javascript:;">取消</a></div>';

   this.editTable.className = 'edittable';

   var etr = $c('tr', $c('tbody',this.editTable));

      

   //创建一个 tr 的副本  因为后面生成tr的时候 可以直接复制节点 

   this.copyTr  = $c('tr');

   this.groupTr = $c('tr');

   this.groupTr.setAttribute('g','y');

   var ctd= $c('td',this.groupTr)

   ctd.setAttribute('colSpan',options.fields.length);

 

   var theadTr = $c('tr',this.thead),

    tWidth  = 0,

    self    = this,

    ul      = $c('ul',this.subPopMenu),

    li;

   each(options.fields,function(i,o){

    var td = $c('td',theadTr),

     width = o.width?o.width:'80',

     div = i===0?'<div class="c nobreak">':'<div class="c nobreak"><p></p>';

    td.innerHTML = [div,'<span class="head_span">',o.name,'</span><a href="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 = [

     '<a href="javascript:;" class="x-menu-item x-m_a" ><input type="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生成 它是显示当前一共有多少条数据的配置项

   var i=0,

    trsLen = options.perPage,

    frag   = doc.createDocumentFragment(),

    arr    = new Array(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(typeof dataConfig === '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){

   var options = this.defaults,

    self    = this,

    totla   = 0;

   

   this.data.length = 0;

   

   if(data.data){

    if(data.data[0].groupName){

     var grouphead = this.grouphead;

     grouphead.length = 0;

     

     each(data.data,function(i,o){

      var gtr = 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; 

   }

   

   var i       = 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){

    var group = {},

     index,

     arr = [],

     insertTrs = this.insertTrs;

           

    //清除掉之前插入的 分组tr

    insertTrs.length!=0&&each(insertTrs,function(i,o){

     self.tbody.removeChild(o);

    });

    insertTrs.length = 0;     

    

    //遍历填充数据 给this.rows赋值    

    var num = - 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为 分组的不同组的标识

     var x = 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为分组的序号  

     !(num in group)&&(group[num] = i + start,arr.push([num,i]));

     for(j = 0;j<tdsLen;j++){

      td = tds[j];

      var txt   = 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++){

      var txt   = 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; 

   var topAs = 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';

   }else if(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'; 

   }else if(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){

   var options     = 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){

   var elem = 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();

    } 

   }

   var issort = checkReg(tdElem.className,'sort'),

    type   = checkReg(tdElem.className,'type')

   

   //进行排序

   if(elemName !=='a'&&type){

    

    var frag = 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');

     }    

    }

    

    // 将排序后的数据渲染到表格

    var insertTrs = 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的样式             

    */ 

    function documentClick(){

     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;

    }

     

    var pos  = 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){

   var sortType = this.defaults.sortType,

    txt =Sys.ie?'innerText':'textContent';

   !sortType[type]&&(type = 'string');

   return function(a1,a2){

    a1 = sortType[type](a1.cells[n][txt]);

    a2 = sortType[type](a2.cells[n][txt]);

    return a1==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){

     var number = {

      start : 0,

      end   : options.totalPage-1,

      next  : options.currPage-1,

      pre   : options.currPage+1

     }[typePage];

     this.toPage(number);

    }

    if(isDel){

     this.del();

    }

    

    if(isGo){

     var number = ~~elem.parentNode.getElementsByTagName('input')[0].value-1;

     this.toPage(number);

    }  

  },

  toPage : function(num){

   if(typeof num !=='number'||isNaN(num))return;

   var options    = this.defaults,

    self       = this,

    dataConfig = options.dataConfig;    

   //如果请求的分页数小于0就默认为0  如果打越最大分页数 就默认为最大分页数

   num>=options.totalPage

    &&(num = options.totalPage-1);

   num<0&&(num = 0);

   

   //s为当前面板的第一页  e为当前面板的最后

   var basePage = 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的

   var selectedRows = this.selectedRows,

    arr = []

    for(var name in selectedRows){     

     arr.push(selectedRows[name].getAttribute('dataIndex'));

    }

   alert('选择了主键值为'+arr.join(','));

  },

  theadOver : function(e){

   var elem = e.target || e.srcElement;

   if(elem.nodeName.toLowerCase() === 'div'){

    $q('a',elem)[0].style.display = 'block';

    addClass(elem,'theadfocus');

   }

  },

  theadOut : function(e){

   var elem     = 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){

   var elem       = 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        

    var menuOp = elem.getAttribute('menuType'),

     sortOrder = checkReg(className,'sort'); 

    //选择所有列  不进行排序  

    if(menuOp==='columns')

     return;

    /*

     如果没有排序  就根据menuOp来进行排序

     如果已排序   且与 menuOp排序方式不同  则进行排序

    */

    if(sortOrder){   

     if(menuOp != sortOrder){

      var td = $q('td',this.thead)[this.isMenuOpen.getAttribute('clos')];

      fireEvent(td,'click');

     }

    }else{

     this.ascSort = {

      desc : false,

      asc  : true

     }[menuOp];

     var td = $q('td',this.thead)[this.isMenuOpen.getAttribute('clos')];

     fireEvent(td,'click');

    } 

    

    //完成上面的操作后 设置成正序  因为 之后点别的列 默认还是按正序列来排

    this.ascSort = true;    

   } 

  },

  menuOver : function(e){

   var elem = e.target || e.srcElement;

   if(elem.nodeName.toLowerCase()==='a'&&elem.getAttribute('menuType')==='columns'){

    var pos  = 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){

   var elem = e.target || e.srcElement,

    isA  = elem.nodeName.toLowerCase() === 'a';

   Sys.ie

    ? e.cancelBubble = true

    : e.stopPropagation();     

   if(isA||elem.nodeName.toLowerCase() === 'input'){

    var input = isA

      ? $q('input',elem.parentNode)[0]

      : elem,

     clos  = input.getAttribute('cols'),

     self  = this;

    

    isA

     &&(input.checked = (!input.checked));     

    

    var checked = input.checked,

     hideOrShow = checked ? '' : 'none';

     

    //如果还剩一列  并且这次是取消选中的 

    //则 不执行隐藏

    if(this.isShowTrs.num===1&&!checked){     

     input.checked = true;

     return false; 

    }

    

    checked

     ?(this.isShowTrs.num++,this.isShowTrs.clos[clos]=true)

     :(this.isShowTrs.num--,this.isShowTrs.clos[clos]=false);

    //如果实现了分组  还必须把组tr的colSpan属性改变

    this.showGroup

     &&each(this.insertTrs,function(i,tr){

      $q('td',tr)[0].setAttribute('colSpan',self.isShowTrs.num);

     });

    //显示或隐藏选中列

    each(this.columns[clos],function(i,o){

     o.style.display = hideOrShow;         

    });

    

    var width = ~~this.columns[clos][0].getAttribute('width');

     

    setTimeout(function(){ 

     checked

      ? self.table.setAttribute('width',~~self.table.getAttribute('width') + width)

      : self.table.setAttribute('width',~~self.table.getAttribute('width') - width)

    },0);    

   }

  },

  rowHighlight : function(e,isHight){

   var elem   = e.target || e.srcElement,

    toElem = e.toElement||e.relatedTarget,

    parent = elem.parentNode; 

    Sys.ie

     ? e.cancelBubble = true

     : e.stopPropagation();

   while(parent.nodeName.toLowerCase()!='tr'){

    parent = parent.parentNode;

   }

   

   if(isHight&&hasClass(parent,'rowfocus'))

    return;      

   //如果是分组的行tr 就返回  

   if(elem.nodeName.toLowerCase()==='td'&&parent.getAttribute('g')==='y')

    return;

   

   isHight

    ? addClass(parent,'rowfocus')

    : removeClass(parent,'rowfocus');

  },

  selectRow : function(e){

   var elem = e.target || e.srcElement;

   if(elem.getAttribute('g')||elem.parentNode.getAttribute('g'))

    return;

   var self          = this,

    selectedRows  = this.selectedRows,

    lastSelectRow = this.lastSelectRow,

    cellClick     = false,

    ctrlClick     = false,

    shiftClick    = false;

   if(elem.nodeName.toLowerCase() === 'td' ){

    var parent    = elem.parentNode,

     className = parent.className,

     options   = this.defaults;

     

    //按ctrl进行选择

    if(e.ctrlKey===true){

     index = checkReg(className,'select');

     //选中那行的如果已经选中了  就取消选中 并且 删除样式

     //从 this.selectedRows 中删除  设置lastSelectRow={dom:null,index:null 

     if(hasClass(parent,'trfocus')){

      if(index){

       delete selectedRows[index];

       removeClass(parent,'select-'+index);

       removeClass(parent,'trfocus');

       lastSelectRow.dom = lastSelectRow.index = null;

      }       

      ctrlClick = false;

     }else{

      selectedRows[++uuid] = parent;

      addClass(parent,'trfocus ');

      addClass(parent,'select-'+uuid);

      ctrlClick = true;  

     }

    }

    

    //按住shift进行选择

    if(e.shiftKey===true){

     var lastDom;

     if(lastSelectRow.dom===null){

      shiftClick=true;

      selectedRows[++uuid] = parent;

      addClass(parent,'trfocus ');

      addClass(parent,'select-'+uuid);      

     }else{

      

      var allRows = [];

      //如果有分组  个并所有的tr到一个数组

      this.showGroup

       ? each(this.rows, function(i, o){

        allRows = allRows.concat(o);

       }) 

       : allRows = this.rows;

 

      each(allRows,function(i,o){             

       if(parent===o){

        lastDom = {dom:o,index:i}

        return false;

       }       

      });

     

      //清空掉之前所有选中tr的样式 

      each(selectedRows,function(i,o){

       removeClass(o,'trfocus'); 

       removeClass(o,'select-'+i);

       delete selectedRows[i];        

      });

 

      var len = Math.max(lastSelectRow.index,lastDom.index);

      

      for(var i = Math.min(lastSelectRow.index,lastDom.index);i<=len;i++){

       selectedRows[++uuid] = allRows[i];

       addClass(allRows[i],'trfocus ');

       addClass(allRows[i],'select-'+uuid);       

      } 

     }    

    }

    

    //进行单选

    if(e.ctrlKey===false&&e.shiftKey===false){     

     each(selectedRows,function(i,o){

      removeClass(o,'trfocus');

      removeClass(o,'select-'+i);

      delete selectedRows[i]; 

     });     

     selectedRows[++uuid] = parent;     

     addClass(parent,'trfocus');

     addClass(parent,'select-'+uuid);

     

     if(parent != lastSelectRow.dom)

      cellClick=true;          

    }

    

    // 点击后记录最后点击的行。

    if(ctrlClick||cellClick||shiftClick){

     var allRows = [];

          

     //如果有分组  个并所有的tr到一个数组

     this.showGroup

      ? each(this.rows, function(i, o){allRows = allRows.concat(o);}) 

      : allRows = this.rows;

     

     //寻找parent的索引

     each(allRows,function(i,o){

      if(o===parent){

       self.lastSelectRow.dom = o;

       self.lastSelectRow.index = i;

       return false;

      }

     });

    }    

   }

  },

  dragWidth : function(e){

   var elem = e.target || e.srcElement;

   if(elem.nodeName.toLowerCase() === "p"){

    /*

     遍历 当前选中的列的 前面所有的列      

     如果没有 或 全部是隐藏的   则返回

    */

   

    for(var i=parseInt(elem.parentNode.parentNode.getAttribute('clos'))-1;i>=0;i--)

     if(this.isShowTrs.clos[i]===true)break;

    if(i<0)

     return;

    var options = this.defaults,

     self = this,    

     widthConfig = options.widthConfig,    

     td = elem.parentNode.parentNode;

     

     widthConfig.x = e.clientX;

     widthConfig.td = td;

     

     Sys.ie

      ? this.table.setCapture(false)

      : e.preventDefault();

      

     widthConfig.prevTd    = this.columns[i][0]; 

     widthConfig.tdWidth   = ~~td.width;     

     widthConfig.prevWidth = ~~widthConfig.prevTd.width;

     var height = Math.min(this.tabContainer.offsetHeight,this.table.offsetHeight),

      scrollHeight = this.tabContainer.offsetHeight>=this.table.offsetHeight?0:18,

      documentScrollLeft = doc.body.scrollLeft;     

     setStyle(this.line,{

      left    : e.clientX + doc.documentElement.scrollLeft + 'px',

      height  : height-scrollHeight +"px",

      top     : objPos(this.tabContainer).top+Math.max(document.documentElement.scrollTop,document.documentElement.scrollTop)+2+'px'

     });

     addListener(doc,'mousemove',bindAsEventListener(this,this.widthMove));

     addListener(doc,'mouseup',bindAsEventListener(this,this.widthUp));

   }

  },

  widthMove : function(e){

   win.getSelection 

    ? win.getSelection().removeAllRanges() 

    : doc.selection.empty();

   var options      = this.defaults,

    widthConfig  = options.widthConfig,

    left         = e.clientX,

    clientX      = left,

    cellMinWidth = options.cellMinWidth;

   if(clientX>widthConfig.x&&e.clientX - widthConfig.x>widthConfig.tdWidth-cellMinWidth){

    left = widthConfig.x +widthConfig.tdWidth -cellMinWidth;

   }

 

   if(clientX<widthConfig.x&&widthConfig.x-clientX>widthConfig.prevWidth-cellMinWidth){

    left = widthConfig.x - widthConfig.prevWidth +cellMinWidth;

   }

   

   setStyle(this.line,{

    left    : left + Math.max(document.documentElement.scrollLeft,document.body.scrollLeft)+"px",

    display : "block"    

   });

  },

  widthUp : function(e){

   this.line.style.display = 'none';

   var widthConfig = this.defaults.widthConfig, 

    x = parseInt(this.line.style.left)- Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft) - widthConfig.x ;

   widthConfig.prevTd.width = ~~widthConfig.prevWidth + x   ;   

   widthConfig.td.width = ~~widthConfig.tdWidth -x;

   Sys.ie && this.table.releaseCapture();

   removeListener(doc,'mousemove');

   removeListener(doc,'mouseup');

  },

  createInput : function(i,obj, parent){

   var etd     = $c('td',parent),

    input   = $c('input',etd),

    type    = obj.edit;

   etd.width  = obj.width

   input.type = 'text';

   input.setAttribute('index',i);

   !type

    &&input.setAttribute('readonly','readonly')

   etd.appendChild(input);

   input.className ='x-form-text i_a';

   setStyle(input,{

    width      : obj.width - 1 +'px',

    background : 'white'

   });

  },

  editRow : function(e){

   var elem     = e.target || e.srcElement,

    self     = this,

    options  = this.defaults,

    nodeName = elem.nodeName.toLowerCase();

   if(nodeName!=='td'){

    while(elem.nodeName.toLowerCase()!=='td'){

     elem = elem.parentNode;

    }

   }

   var tr = elem.parentNode;

   this.currentEditRow.index = tr.getAttribute('dataindex');

   this.currentEditRow.dom   = tr;

   if(tr.getAttribute('g'))

    return;

   var sTop  = ~~this.tabContainer.scrollTop,

    sLeft = ~~this.tabContainer.scrollLeft,

    cTds  = $q('td',tr);

    pTds  = $q('td',$q('tr',this.editTable)[0]),

    txt   = Sys.ie?'innerText':'textContent';

   setStyle(this.editForm,{

    top     : tr.offsetTop  + 'px',

    left    : tr.offsetLeft + 'px',

    display : ''

   });

   each(cTds,function(i,td){

    $q('input',pTds[i])[0].value = td[txt];

   });     

  },

  modifyTr : function(e){

   var elem = e.target || e.srcElement;

   if(elem.nodeName.toLowerCase()==='a'){

    var tds = $q('td',this.editTable),

     txt = txt =Sys.ie?'innerText':'textContent',

     isC = false;

    if(elem.getAttribute('do')==='submit'){

     alert('索引为'+this.currentEditRow.index)

    } 

    this.editForm.style.display = 'none'; 

   }

  } 

 }); 

})(document);

window.onload = function(){

 var data ={

  //total:'55',

  data : []

 }

 var s='阿斯达三大散打三个而个呃 奋斗个我是地方我师父 威尔 地方威尔威尔威尔 豆腐干 沃尔与体育 56  范甘迪威尔 请问额请问散阿萨德b你吗 吗吗 阿斯 zweas dqwesdf 阿凡达散打有人6 斯蒂芬与',

  b = ['人民币','欧元','美元'],

  n = ['张三','李四','王五','赵六','陈七','猪八']

 

 each(new Array(3000),function(i,o){

  data.data.push([i+1,n[i%5]+i,(i%3===0?'-':'')+parseInt(Math.random()*1000),b[i%2],'1984-05-27',s.substring(Math.random()*10,Math.random()*10+15)])         

 });

 data5 = {

  total:   11,

  data  : [               

   {

    groupName : '平安银行',

    rows : [

     [1,'平安银行一张同-账单','-29792.66','日元','1928-06-15','一般'],

     [2,'平安银行信用卡-账单','26268.99','欧元','1950-04-14','一般'],

     [3,'平安银行基金-账单','-84149.12','英磅','1927-05-08','一般'],

     [4,'平安银行信用卡-账单','23782.40','欧元','1995-01-05','一般'],

     [5,'平安银行国债-账单','-48355.53','人民币','1953-07-01','很好'],

     [6,'平安银行信用卡-账单','14922.48','人民币','1954-08-04','一般'],

     [7,'平安银行信用卡-账单','87252.78','人民币','1956-10-01','很好'],

     [8,'平安银行基金-账单','-67287.72','英磅','1948-02-24','一般'],

     [9,'平安银行基金-账单','-51724.44','美元','1943-09-11','很差']

    ]

   },

   {

    groupName : '交通银行',

    rows : [      

     [151,'交通银行一张同-账单','23062.39','英磅','1959-01-03','一般'],

     [152,'交通银行信用卡-账单','10634.01','英磅','1967-09-23','很好'],

     [153,'交通银行基金-账单','-69832.32','美元','2000-06-07','很差'],

     [154,'交通银行信用卡-账单','-22260.14','英磅','1999-05-27','很差'],

     [155,'交通银行国债-账单','92868.28','英磅','1911-01-03','一般'],

     [156,'交通银行信用卡-账单','77059.80','英磅','1990-08-03','一般']

    ]

   },

   {

    groupName : '渣打银行',

    rows : [

     [182,'渣打银行一张同-账单','26046.45','英磅','1923-01-22','很好'],

     [183,'渣打银行信用卡-账单','-57036.21','欧元','1974-04-20','很差']

    ]

   },

   {

    groupName : '浦发银行',

    rows : [

     [218,'渣打银行信用卡-账单','51027.86','日元','1970-01-08','很好'],

     [219,'渣打银行基金-账单','-58048.75','英磅','1948-02-12','一般'],

     [220,'渣打银行信用卡-账单','-79938.95','欧元','1957-11-22','很差'],

     [221,'渣打银行国债-账单','-65972.99','欧元','1953-07-01','很差'],

     [222,'渣打银行信用卡-账单','44483.17','欧元','2000-06-11','一般']

    ]

   },

   {

    groupName : '招商银行',

    rows : [

     [238,'招商银行信用卡-账单','77695.90','美元','1919-09-20','很好'],

     [239,'招商银行信用卡-账单','52517.41','欧元','1921-11-12','很好'],

     [240,'招商银行基金-账单','-45174.21','欧元','1949-03-08','很差'],

     [241,'招商银行信用卡-账单','-60409.65','英磅','1950-04-02','一般'],

     [242,'招商银行国债-账单','32741.68','美元','2005-11-17','很差']  

    ]

   },        

   {

    groupName : '农业银行',

    rows : [

     [430,'农业银行一张同-账单','23474.59','日元','1983-01-13','一般'],

     [431,'农业银行信用卡-账单','-64526.95','日元','1952-06-10','很好'],

     [432,'农业银行基金-账单','49975.19','美元','1975-05-18','一般']

    ]

   }        

  ]

 }

 function xx(v){

  return ~~v<0

   ? '<span class="greed">'+v+'</span>'

   : '<span class="red">'+v+'</span>'

 } 

 

 new easyGrid({

  container  : $$('demo'),

  //主键名  删除 编辑 的时候 需要这个东西

  primaryKey : 'id',

  fields     : [

   {name:'序号',param:'id',type:'int',width:'100'},

   {name:'名称',param:'name',type:'string',edit:'edit',width:'140'},

   {name:'余额',param:'money',type:'float',edit:'edit',render:xx,width:'100'},

   {name:'币种',param:'type',type:'string',edit:'edit',width:'100'},

   {name:'日期',param:'date',type:'date',edit:'edit',width:'100'},

   {name:'备注',param:'note',type:'string',width:'255'}

  ],

  dataConfig : data,

  //一页有多少条

  perPage    : 1000,

  //当前在第几页

  currPage   : 0,

  //一共多少页

  totalPage  : 0,

  //一次请求多少条数据

  count      : 2000,

  //第几版数据

  page       : 0

 });

 

 easyGrid.prototype.options.sortType.cp=function(v){   

  if(v==='很好')

   return 3

  if(v==='一般')

   return 2

  if(v==='很差')

   return 1    

 }

 new easyGrid({

  container  : $$('demo1'),

  //主键名  删除 编辑 的时候 需要这个东西

  primaryKey : 'id',

  fields     : [

   {name:'序号',param:'id',type:'int',width:'100'},

   {name:'名称',param:'name',type:'string',edit:'edit',width:'140'},

   {name:'余额',param:'money',type:'float',edit:'edit',render:xx,width:'100'},

   {name:'币种',param:'type',type:'string',edit:'edit',width:'100'},

   {name:'日期',param:'date',type:'date',edit:'edit',width:'100'},

   {name:'备注',param:'note',type:'cp',width:'255'}

  ],

  dataConfig : data5,

  //一页有多少条

  perPage    : 20,

  //当前在第几页

  currPage   : 0,

  //一共多少页

  totalPage  : 0,

  //一次请求多少条数据

  count      : 2000,

  //第几版数据

  page       : 0

 }); 

 

};

</script>

</body>

</html>

水平有限  请多指教

Javascript 相关文章推荐
仿服务器端脚本方式的JS模板实现方法
Apr 27 Javascript
JS解析XML实例分析
Jan 30 Javascript
javascript弹出窗口实现代码
Nov 12 Javascript
javascript基础知识分享之类与函数化
Feb 13 Javascript
AngularJs自定义服务之实现签名和加密
Aug 02 Javascript
正则表达式基本语法及表单验证操作详解【基于JS】
Apr 07 Javascript
tangram.js库实现js类的方式实例分析
Jan 06 Javascript
浅谈vue限制文本框输入数字的正确姿势
Sep 02 Javascript
vue element-ui读取pdf文件的方法
Nov 26 Javascript
微信小程序上传帖子的实例代码(含有文字图片的微信验证)
Jul 11 Javascript
Element-ui upload上传文件限制的解决方法
Jan 22 Javascript
create-react-app开发常用配置教程
Jun 25 Javascript
浅谈jQuery事件绑定原理
Jan 02 #Javascript
js+jquery实现图片裁剪功能
Jan 02 #Javascript
javascript 构造函数方式定义对象
Jan 02 #Javascript
深入探寻javascript定时器
Jan 02 #Javascript
JavaScript中的Truthy和Falsy介绍
Jan 01 #Javascript
JavaScript中的null和undefined区别介绍
Jan 01 #Javascript
JavaScript中的全局对象介绍
Jan 01 #Javascript
You might like
thinkphp的c方法使用示例
2014/02/24 PHP
无需数据库在线投票调查php代码
2016/07/20 PHP
HTML IMG标签 onload 内存溢出导致浏览器CPU占用过高
2021/03/09 Javascript
top.location.href 没有权限 解决方法
2008/08/05 Javascript
jquery中实现标签切换效果的代码
2011/03/01 Javascript
jquery原创弹出层折叠效果点击折叠弹出一个层
2014/03/12 Javascript
jQuery CSS()方法改变现有的CSS样式
2014/08/20 Javascript
js点击列表文字对应该行显示背景颜色的实现代码
2015/08/05 Javascript
基于Jquery和html5实现炫酷的3D焦点图动画
2016/03/02 Javascript
JS数组操作(数组增加、删除、翻转、转字符串、取索引、截取(切片)slice、剪接splice、数组合并)
2016/05/20 Javascript
很酷的星级评分系统原生JS实现
2016/08/25 Javascript
jQuery zTree树插件动态加载实例代码
2017/05/11 jQuery
javascript完美实现给定日期返回上月日期的方法
2017/06/15 Javascript
JS+HTML5 FileReader实现文件上传前本地预览功能
2020/03/27 Javascript
input输入框内容实时监测(附代码)
2017/08/15 Javascript
vue中v-for加载本地静态图片方法
2018/03/03 Javascript
JS加密插件CryptoJS实现AES加密操作示例
2018/08/16 Javascript
小程序中设置缓存过期的实现方法
2020/01/14 Javascript
详解JavaScript中精度失准问题及解决方法
2020/02/04 Javascript
vue 实现根据data中的属性值来设置不同的样式
2020/08/04 Javascript
Python实现简单截取中文字符串的方法
2015/06/15 Python
简介Django中内置的一些中间件
2015/07/24 Python
Python元组拆包和具名元组解析实例详解
2018/03/26 Python
解决python3 urllib 链接中有中文的问题
2018/07/16 Python
css3模拟jq点击事件的实例代码
2017/07/06 HTML / CSS
CSS3属性box-shadow使用详细教程
2012/01/21 HTML / CSS
白俄罗斯在线大型超市:e-dostavka.by
2019/07/25 全球购物
澳大利亚在线奢侈品时尚零售平台:Azura Runway
2021/01/13 全球购物
西班牙购买隐形眼镜、眼镜和太阳镜网站:Lentiamo.es
2020/06/11 全球购物
如何清空Session
2015/02/23 面试题
客服主管岗位职责
2013/12/13 职场文书
《蜗牛》教学反思
2014/02/18 职场文书
党的群众路线教育实践活动个人对照检查材料(乡镇)
2014/11/05 职场文书
九不准学习心得体会
2016/01/23 职场文书
导游词之山海关
2019/12/10 职场文书
SQL Server实现分页方法介绍
2022/03/16 SQL Server