开发背景
表格插件之前我也写个一篇,当时写那个插件的时候,我自己还没有总结出写插件的方法,虽然功能实现了,但是使用起来还是有点别扭的,并且需要在调用写添加特定名称的方法,这个地方着实违背了开发插件的易用性。所以,我今天决定重构之前的代码,按照现有的开发插件框架进行一次大修整。这也类似于软件开发过程中的代码重构阶段吧,把一些不合理的代码、思想、逻辑等及时修改掉。
其实代码重构在软件开发过程中特别重要。开发过程中,可能会由于开发时间的限制等因素,为了及时完成任务,不得已写一些没有经过斟酌的代码,我们不能对已经写的代码置之不理,要在闲下来的事件将这些代码重构下,这样使自己的代码冗余减少,质量也提高很多。并且逻辑会更加清晰等等好处。这里就不一一说了。太乱的代码,时间久了,可能连自己都不想看了,也许也是看不懂了。很多程序猿都没有重构代码的习惯,以完成任务为目的,同时也担心修改错了等,以各种理由说服自己不去QA自己的代码。在这里,我还是那句话,作为想成为“攻城狮”的“猿们”,请对自己负责,对自己的代码负责。我不是牛人,但是我有一颗必须成为牛人的心。和我一样,奋斗在“一线”的猿们,努力吧,自勉吧。
背景交代完毕,其实那个多也就汇成一句话,请不定时去QA自己代码。以下就是我对上次GridData代码的重构吧。当然,思想也改变了。
记得之前写了很多自定义属性,当然这次也有,但是,就不放在代码层次的最外层了,为了代码结构的整齐,就将其放在插件开发的里面了。这次我还是重头开始说起吧。说实话,本插件的参数很多都是仿照easy ui 中的GridData。为啥要仿照呢,其实我本人是不建议使用easy ui的,虽然功能强大,但是功能太死,二次开发时间成本比较高。因为他们开发团队将很多东西都分装的太死。其实也不能怪别人。人家辛辛苦苦开发的东西,当然不想被别人那个轻易就拿走喽。理解万岁!当然也不是完全不能二次开发,你得去理解人家的规范,那样就是可以了。之前我有对其中的Tree控件、TreeGrid控件等做了二次开发。目的当然是为了适应工作需要了。^_^
所以呢,很多大公司都会有自己的一套插件库的。这样便于维护、扩展。这个好处就不用我多说了,大家都懂的。好了,回归正题,不然又扯远了。
哦,对了,上一篇博文中漏了公共Js代码了,不好意思。。。。这边等会我将补上。
先说下本插件的功能吧:1、支持分页;2、支持多种皮肤选择;3、支持对列设置样式。4、其他正常的表格功能(不多说了)。
开发过程
本次开发过程中分五个部分:
第一部分:公共js和公共css样式部分;
第二部分:自定义特性(如:皮肤风格选择等)部分;
第三部分:具体定义及实现部分;
第四部分:对外开放部分;
第五部分:具体使用部分;
接下来我将对开发过程中的五个部分进行具体说明。
详细开发设计
第一部分:公共js和公共css样式开发,这里涉及克隆对象(cloneObject)、创建委托(delegate)、获取参数(getParam)、判断元素是否存在某个属性(boolHasAttr)、字符串是否为空(IsNull)等。该部分可以以后继续添加公共代码,具体代码实现如下:
1 $(function () { 2 /// 创建委托函数 3 /// context:函数上下文 4 /// params:参数【必须是数组形式】,可以为空 5 Function.prototype.delegate = function (context, params) { 6 var func = this; 7 return function () { 8 if (params == null) { 9 return func.apply(context); 10 } 11 return func.apply(context, params); 12 }; 13 }; 14 $.extend({ 15 coverObject: function (obj1, obj2) { 16 var o = this.cloneObject(obj1, false); 17 var name; 18 for (name in obj2) { 19 if (obj2.hasOwnProperty(name)) { 20 o[name] = obj2[name]; 21 } 22 } 23 return o; 24 }, 25 cloneObject: function (obj, deep) { 26 if (obj === null) { 27 return null; 28 } 29 var con = new obj.constructor(); 30 var name; 31 for (name in obj) { 32 if (!deep) { 33 con[name] = obj[name]; 34 } else { 35 if (typeof (obj[name]) == "object") { 36 con[name] = $.cloneObject(obj[name], deep); 37 } else { 38 con[name] = obj[name]; 39 } 40 } 41 } 42 return con; 43 }, 44 ///说明: 45 /// 创建委托 46 delegate: function (func, context, params) { 47 if ($.isFunction(func)) { 48 return func.delegate(context, params); 49 } else { 50 return $.noop; 51 } 52 }, 53 getParam: function (param) { 54 if (typeof (param) == "undefined") { 55 return ""; 56 } else { 57 return param; 58 } 59 }, 60 ///说明: 61 /// 判断元素是否存在某个属性 62 boolHasAttr: function (id, attr) { 63 if (typeof ($("#" + id).attr(attr)) != "undefined") { 64 return false; 65 } 66 return true; 67 }, 68 IsNull: function (str) { 69 if ($.trim(str) == "" || isNaN(str)) { 70 return true; 71 } 72 return false; 73 } 74 }); 75 });
.gridData_tableFoot{ width: auto;height:24px;margin: 0px auto;line-height: 24px; } .gridData_tableFoot div{ width: auto;height :100%;margin-left: 5px;cursor: pointer;float: left } .tableBodyCur { cursor: pointer } .lieStyle{ color: #205ed7 ; border-color:#D4DBE1 } thead td,tbody td{ border: 1px solid #D4DBE1;/*这个是解决兼容IE浏览器的属性*/ } .tableDataGridFoot { border-collapse:collapse; } .theadStyle { background-repeat: repeat-x ; }
第二部分:自定义特性部分,该部分可以根据以后需求进行扩展。现在本部分只有皮肤风格枚举(enumSkin)、表格头部数据参数枚举(enumTHeadDataParamsType),具体代码实现如下:
1 $.extend({ 2 enumDdataGrid: { 3 //表格头部数据参数 类型 4 enumTHeadDataParamsType: { 5 number: 1, 6 string: 2, 7 ip: 3 8 }, 9 //皮肤风格 10 enumSkin: { 11 classic: 1, //经典 12 traditional: 2, //传统 13 gorgeous: 3 //绚丽 14 } 15 } 16 });
第三部分:具体定义及实现部分。这部分是逻辑分装的主体,同时也是最难的部分。由于太多太多,所以只说一下思想。本次开发的插件使用 委托 和 事件句柄,思想开发。这样写的确实现了元素和事件间的解耦。当然这个也是模仿面向对象思想中的开发了。这个思想我在导航菜单中也有使用,并且这个思想也是我力推的思想。希望还不理解的猿们,好好学习一下,当你会了之后,你会感谢委托和事件句柄的,因为他让你的代码逻辑清晰了,代码也解耦了。。。自己去感受吧。我在代码中都加了注释,想必大家看也很好理解。但是逻辑还是有点复杂的,如果有想详细了解的可以联系我,在最下面我会将自己的联系QQ附上。^_^
1 var dataGrid = function () { 2 //参数定义 3 this.defaultParams = { 4 //参数定义 5 id: "", 6 data: null, 7 url: null, 8 tWidth: 1000, 9 tHeadColor: "", 10 tHeadBgColor: "", 11 tHeadBgImgUrl: "", 12 tHeadHeight: 32, 13 tHeadStyle: "", 14 tHeadCols: null, 15 tHeadDataParams: { //表格头部数据参数 16 field: "", 17 title: "", 18 width: "", 19 align: "", 20 sortable: "", 21 type: "" 22 }, 23 tBodyColor: "", 24 tBodyBgColor: "", 25 tBodyHeight: 35, 26 tBodyOddTrBgcolor: "", //基数行颜色 27 tBodyEvenTrBgcolor: "", //偶数行颜色 28 tBodyMouserOverBgcolor: "", //鼠标经过颜色 29 tBodyMouserOutBgcolor: "", //鼠标移出颜色 30 tBodyTrSelectedBgColor: "yellow", //被选中行颜色 31 tFootColor: "", //底部文字颜色 32 tFootBgColor: "", //底部背景 33 tFootPosition: "right", //底部对其方式 34 tBoolPage: true, //是否分页 35 tBoolCheckbox: true, //是否显示check box 36 pageCount: 10, //总页数 37 pageSize: 10, //每页显示个数 38 currentPage: 1, //当前页 39 trTdentity: null, //行标识 40 tEnumDataGridSkin: null, //选择皮肤风格 41 tBoolRowNumbers: true, //是否显示行号 42 tBodyTrDblclickCallBack: $.noop //双击行 的回到函数 43 }; 44 this.options = {}; 45 }; 46 dataGrid.prototype = { 47 constructor: dataGrid, 48 init: function (params) { 49 this.options = $.coverObject(this.defaultParams, params); 50 this._init(); 51 }, 52 _init: function () { 53 //初始化皮肤 54 this.tInitializeSelectPSkin(); 55 //初始化元素 56 this.tInitializeElement(); 57 this.tInitializeGetData(); 58 //创建table head 59 this.createTableHead(); 60 //创建table body 61 this.createTableBody(); 62 //选择是否分页 63 if (this.options.tBoolPage) { 64 this.createTableFoot(); 65 } 66 //选择是否显示多选按钮 67 if (this.options.tBoolCheckbox) { 68 this.addCheckbox(); 69 } 70 //是否显示行号 71 if (this.options.tBoolRowNumbers) { 72 this.addRowNumbers(); 73 } 74 //设置属性和样式 75 this.setTableAttribute(); 76 //注册事件 77 this._registerTableFootGoTo(); 78 this._registerTableFootFirstPage(); 79 this._registerTableFootLastPage(); 80 this._registerTableFootUpPage(); 81 this._registerTableFootNextPage(); 82 this._registerTbodyTrMouseover(); 83 this._registerTbodyTrMouseout(); 84 this._registerTbodyTrDblclick(); 85 this._registerTbodyTrCheckbox(); 86 this._registerTbodyTrClick(); 87 this._registerPageNumberKeyup(); 88 this._registerPageNumberPaste(); 89 this._registerPageNumberFocus(); 90 this._registerCheckboxCheckAll(); 91 }, 92 93 ///说明: 94 /// 初始化选择皮肤 95 tInitializeSelectPSkin: function () { 96 switch (this.options.tEnumDataGridSkin) { 97 case $.enumDdataGrid.enumSkin.classic: 98 this.options.tWidth = 1000; 99 this.options.tHeadColor = "black"; 100 this.options.tHeadBgColor = "#e1e1e1"; 101 this.options.tHeadHeight = 32; 102 this.options.tHeadBgImgUrl = ""; 103 this.options.tHeadStyle = "theadStyle"; 104 this.options.tBodyHeight = 35; 105 this.options.tBodyOddTrBgcolor = "white"; 106 this.options.tBodyEvenTrBgcolor = "white"; 107 this.options.tBodyMouserOverBgcolor = "silver"; 108 this.options.tBodyTrSelectedBgColor = "yellow", 109 this.options.tColNumber = 2; 110 this.options.tColStyle = "lieStyle"; 111 break; 112 case $.enumDdataGrid.enumSkin.traditional: 113 this.options.tWidth = 1000; 114 this.options.tHeadColor = "black"; 115 this.options.tHeadHeight = 32; 116 this.options.tHeadBgImgUrl = "url(../Images/TableImg/tableHeadBg.jpg)"; 117 this.options.tHeadStyle = "theadStyle"; 118 this.options.tBodyHeight = 35; 119 this.options.tBodyOddTrBgcolor = "white"; 120 this.options.tBodyEvenTrBgcolor = "#e1e1e1"; 121 this.options.tBodyMouserOverBgcolor = "silver"; 122 this.options.tBodyTrSelectedBgColor = "yellow", 123 this.options.tColNumber = 2; 124 this.options.tColStyle = "lieStyle"; 125 break; 126 case $.enumDdataGrid.enumSkin.gorgeous: 127 this.options.tWidth = 1000; 128 this.options.tHeadColor = "black"; 129 this.options.tHeadHeight = 32; 130 this.options.tHeadBgImgUrl = "url(../Images/TableImg/tableHeadBg.jpg)"; 131 this.options.tHeadStyle = "theadStyle"; 132 this.options.tBodyHeight = 35; 133 this.options.tBodyOddTrBgcolor = "pink"; 134 this.options.tBodyEvenTrBgcolor = "#e1e1e1"; 135 this.options.tBodyMouserOverBgcolor = "silver"; 136 this.options.tBodyTrSelectedBgColor = "yellow", 137 this.options.tColNumber = 2; 138 this.options.tColStyle = "lieStyle"; 139 break; 140 default: 141 break; 142 } 143 }, 144 ///说明: 145 /// 初始化元素 146 tInitializeElement: function () { 147 var id = this.options.id; 148 $("#" + id).attr({ "cellpadding": 1, "cellspacing": 0, "align": "center", "bordercolor": "#D4DBE1" }); 149 $("#" + id).css("border-collapse", "collapse"); 150 //添加区域 151 var headArea = "<thead gdThead=''></thead>"; 152 var bodyArea = "<tbody gdTbody=''></tbody>"; 153 var footArea = "<tfoot gdTfoot=''><tr><td></td></tr></tfoot>"; 154 var area = headArea + bodyArea + footArea; 155 $("#" + id).html(area); 156 //设置自定义属性标识 157 $("#" + id).attr("datagrid", id); 158 $("table[datagrid $='" + id + "'] thead").attr("gdThead", id); 159 $("table[datagrid $='" + id + "'] tbody").attr("gdTbody", id); 160 $("table[datagrid $='" + id + "'] tfoot").attr("gdTfoot", id); 161 //判断是不是存在checkAll 162 if ($("input:checkbox[name='chk_All_" + id + "']").length > 0) { 163 $("table[datagrid $='" + id + "'] thead tr").find("td:first").remove(); 164 } 165 $("table[datagrid $='" + id + "'] tbody[gdTbody ='" + id + "']").empty(); 166 }, 167 168 ///说明: 169 /// 获取数据源 170 tInitializeGetData: function () { 171 var optionsData = null; 172 var pageCount = 0; 173 var paramsData = {}; 174 175 //对是否分页做处理,当不分页的时候,需要在后台做判断的。 176 if (this.options.tBoolPage) { 177 paramsData = { "pageSize": this.options.pageSize, "currentPage": this.options.currentPage }; 178 } 179 $.ajax({ 180 type: "POST", 181 url: this.options.url, 182 data: paramsData, 183 dataType: "json", 184 async: false, 185 success: function (result) { 186 optionsData = result.Data; 187 pageCount = result.PageCount; 188 } 189 }); 190 if (optionsData == null || optionsData.length < 1) { 191 return; 192 } 193 this.options.data = optionsData; 194 this.options.pageCount = pageCount; 195 }, 196 197 ///说明: 198 /// 创建 table head 199 createTableHead: function () { 200 var id = this.options.id; 201 if (this.options.tHeadCols != null) { 202 var cols = this.options.tHeadCols; 203 var colsLen = cols.length; 204 if (colsLen > 0) { 205 var htmlHead = ""; 206 htmlHead += "<tr>"; 207 for (var i = 0; i < colsLen; i++) { 208 var col = cols[i]; 209 var colLen = col.length; 210 if (colLen > 0) { 211 for (var j = 0; j < colLen; j++) { 212 this.options.tHeadDataParams = $.coverObject(this.options.tHeadDataParams, col[j]); 213 htmlHead += "<td width=" + this.options.tHeadDataParams.width + " align='" + this.options.tHeadDataParams.align + "'>"; 214 htmlHead += this.options.tHeadDataParams.title; 215 htmlHead += "</td>"; 216 } 217 } 218 } 219 htmlHead += "</tr>"; 220 $("table[datagrid $='" + id + "'] thead[gdThead $='" + id + "']").html(htmlHead); 221 } 222 } 223 }, 224 225 ///说明: 226 /// 创建 table body 227 createTableBody: function () { 228 var options = this.options; 229 var id = options.id; 230 var data = options.data; 231 if ($("table[datagrid $='" + id + "'] tbody[gdTbody ='" + id + "']").length <= 0) { 232 return; 233 } 234 var htmlBody = ""; 235 var colLen = $("table[datagrid $='" + id + "'] thead tr td").length; 236 $.each(data, function (i, ob) { 237 htmlBody += "<tr trId='" + eval("ob." + options.trTdentity) + "' trRowNumber='" + (i + 1) + "' style='background-color:"; 238 if ((i + 1) % 2 == 0) { 239 htmlBody += options.tBodyEvenTrBgcolor + "'>"; 240 } else { 241 htmlBody += options.tBodyOddTrBgcolor + "' >"; 242 } 243 var realityCount = 0; 244 $.each(ob, function (j, d) { 245 realityCount += 1; 246 htmlBody += " <td >" + d + "</td>"; 247 }); 248 //判断数据源中的数据列数是否 小于 table头部的列数 249 if (realityCount < colLen) { 250 var difference = colLen - realityCount; 251 for (var j = 0; j < difference; j++) { 252 htmlBody += " <td></td>"; 253 } 254 } 255 htmlBody += "</tr>"; 256 }); 257 258 $("table[datagrid $='" + id + "'] tbody[gdTbody ='" + id + "']").html(htmlBody); 259 $("table[datagrid $='" + id + "'] tbody[gdTbody ='" + id + "'] tr").attr("height", options.tBodyHeight); //设置行高 260 261 }, 262 263 ///说明: 264 /// 创建 table foot 265 createTableFoot: function () { 266 var id = this.options.id; 267 if ($("table[datagrid $='" + id + "']").length <= 0) { 268 return; 269 } 270 var tableFootHtml = ""; 271 tableFootHtml += "<div class='gridData_tableFoot' style='float:" + this.options.tFootPosition + "'>"; 272 tableFootHtml += " <div id='tableFootGoTo_" + id + "'>转到</div>"; 273 tableFootHtml += " <div><input id='txtPageNumber_" + id + "' value='" + this.options.currentPage + "' style='width: 30px;height:auto;'/></div>"; 274 tableFootHtml += " <div id='tableFootFirstPage_" + id + "' >首页</div>"; 275 tableFootHtml += " <div id='tableFootUpPage_" + id + "' >上一页</div>"; 276 tableFootHtml += " <div id='tableFootNextPage_" + id + "' >下一页</div>"; 277 tableFootHtml += " <div id='tableFootLastPage_" + id + "' >末页</div>"; 278 tableFootHtml += " <div id='tableFootPageCount_" + id + "' style='cursor:default'>共" + this.options.pageCount + "页</div>"; 279 tableFootHtml += "</div>"; 280 $("table[datagrid $='" + id + "'] tfoot tr td").html(tableFootHtml); 281 $("#txtPageNumber_" + id).css("ime-mode", "disabled");//CSS设置输入法不可用 282 }, 283 ///说明: 284 /// 添加多选框 285 addCheckbox: function () { 286 var id = this.options.id; 287 $("table[datagrid $='" + id + "'] thead tr").find("td:first").each(function (i) { 288 $(this).before("<td align='center' width='30'><input type='checkbox' name='chk_All_" + id + "' value='checkbox'> </td>"); 289 }); 290 $("table[datagrid $='" + id + "'] tbody[gdTbody ='" + id + "'] tr").find("td:first").each(function (i) { 291 $(this).before("<td align='center'><input type='checkbox' name='chk_" + i + "' chkNumber='" + (i + 1) + "' value='checkbox'> </td>"); 292 }); 293 }, 294 295 ///说明: 296 /// 添加行号 297 addRowNumbers: function () { 298 var id = this.options.id; 299 $("table[datagrid $='" + id + "'] thead tr").find("td:first").each(function (i) { 300 $(this).before("<td align='center' style='background-color:#bababa' width='30'> </td>"); 301 }); 302 $("table[datagrid $='" + id + "'] tbody[gdTbody ='" + id + "'] tr").find("td:first").each(function (i) { 303 $(this).before("<td align='center' style='background-color:#bababa;'>" + (i + 1) + "</td>"); 304 }); 305 306 }, 307 308 ///说明: 309 /// 设置属性、样式 310 setTableAttribute: function () { 311 var id = this.options.id; 312 if ($("table[datagrid $='" + id + "']").length <= 0) { 313 return; 314 } 315 $("table[datagrid $='" + id + "']").attr("width", this.options.tWidth); 316 317 $("table[datagrid $='" + id + "'] thead").css("background", this.options.tHeadBgColor); 318 $("table[datagrid $='" + id + "'] thead").css("color", this.options.tHeadColor); 319 $("table[datagrid $='" + id + "'] thead").css("background-image", this.options.tHeadBgImgUrl); 320 $("table[datagrid $='" + id + "'] thead").css("height", this.options.tHeadHeight); 321 $("table[datagrid $='" + id + "'] thead").addClass(this.options.tHeadStyle); 322 $("table[datagrid $='" + id + "'] thead tr").css("height", this.options.tHeadHeight); 323 $("table[datagrid $='" + id + "'] tbody").css("background", this.options.tBodyBgColor); 324 $("table[datagrid $='" + id + "'] tbody").css("color", this.options.tBodyColor); 325 $("table[datagrid $='" + id + "'] tbody").addClass("tableBodyCur"); 326 if ($("table[datagrid $='" + id + "']").length <= 0) { 327 return; 328 } 329 $("table[datagrid $='" + id + "']").attr("width", this.options.tWidth); 330 $("table[datagrid $='" + id + "'] tfoot").css("background", this.options.tFootBgColor); 331 $("table[datagrid $='" + id + "'] tfoot").css("color", this.options.tFootColor); 332 333 //设置列样式 334 if (this.options.tColStyle != "") { 335 var options = this.options; 336 var colLen = $("table[datagrid $='" + id + "'] thead tr td").length; 337 $("table[datagrid $='" + id + "'] tbody[gdTbody ='" + id + "']").find("td").each(function (i) { 338 if ((i + 1) % colLen == options.tColNumber) { 339 $(this).addClass(options.tColStyle); //给区间加上特定样式 340 } 341 }); 342 } 343 var colLens = $("table[datagrid $='" + id + "'] thead tr td").length; 344 $("table[datagrid $='" + id + "'] tfoot tr td").attr("colspan", colLens); 345 }, 346 /// 说明: 347 /// 跳转到首页 348 firstPage: function () { 349 var options = this.options; 350 options.currentPage = 1; 351 $("#txtPageNumber_" + options.id).val(options.currentPage); 352 this.jumpPage(); 353 }, 354 /// 说明: 355 /// 跳转到上一页 356 lastPage: function () { 357 var options = this.options; 358 if (options.currentPage === 1) { 359 alert("已经到第一页了!"); 360 return; 361 } 362 options.currentPage = parseInt(options.currentPage) - 1; 363 $("#txtPageNumber_" + options.id).val(options.currentPage); 364 this.jumpPage(); 365 }, 366 /// 说明: 367 /// 跳转到下一页 368 nextPage: function () { 369 var options = this.options; 370 if (options.currentPage >= options.pageCount) { 371 alert("超出了最大页数!"); 372 return; 373 } 374 options.currentPage = parseInt(options.currentPage) + 1; 375 $("#txtPageNumber_" + options.id).val(options.currentPage); 376 this.jumpPage(); 377 }, 378 /// 说明: 379 /// 跳转到末页 380 finalPage: function () { 381 var options = this.options; 382 options.currentPage = options.pageCount; 383 $("#txtPageNumber_" + options.id).val(options.currentPage); 384 this.jumpPage(); 385 }, 386 /// 说明: 387 /// 跳转到跳到某一页 388 jumpPage: function () { 389 var options; 390 if ($.getParam(arguments[0]) != "") { 391 options = arguments[0];//这里特殊,判断是不是从PageNumber Keyup过来的 392 } else { 393 options = this.options; 394 } 395 var id = options.id; 396 397 $("#" + id).gridData.init(options); 398 }, 399 /******************************(注册事件 begin)******************************/ 400 401 /// 说明: 402 /// Go To 403 _registerTableFootGoTo: function () { 404 var handleEvent = $.delegate(this._handleTableFootGoTo, this); 405 $("#tableFootGoTo_" + this.options.id).click(handleEvent); 406 }, 407 /// 说明: 408 /// First Page 409 _registerTableFootFirstPage: function () { 410 var handleEvent = $.delegate(this._handleTableFootFirstPage, this); 411 $("#tableFootFirstPage_" + this.options.id).click(handleEvent); 412 }, 413 /// 说明: 414 /// Last Page 415 _registerTableFootLastPage: function () { 416 var handleEvent = $.delegate(this._handleTableFootLastPage, this); 417 $("#tableFootLastPage_" + this.options.id).click(handleEvent); 418 }, 419 /// 说明: 420 /// Up Page 421 _registerTableFootUpPage: function () { 422 var handleEvent = $.delegate(this._handleTableFootUpPage, this); 423 $("#tableFootUpPage_" + this.options.id).click(handleEvent); 424 }, 425 /// 说明: 426 /// Next Page 427 _registerTableFootNextPage: function () { 428 var handleEvent = $.delegate(this._handleTableFootNextPage, this); 429 $("#tableFootNextPage_" + this.options.id).click(handleEvent); 430 }, 431 /// 说明: 432 /// Tr Mouseover 433 _registerTbodyTrMouseover: function () { 434 var options = this.options; 435 $("table[datagrid $='" + this.options.id + "'] tbody tr").each(function () { 436 var handleEvent = $.delegate(dataGrid.prototype._handleTbodyTrMouseover, this, [{ options: options }]); 437 $(this).mouseover(handleEvent); 438 }); 439 }, 440 /// 说明: 441 /// Tr Mouseout 442 _registerTbodyTrMouseout: function () { 443 var options = this.options; 444 $("table[datagrid $='" + options.id + "'] tbody tr").each(function () { 445 var handleEvent = $.delegate(dataGrid.prototype._handleTbodyTrMouseout, this, [{ options: options }]); 446 $(this).mouseout(handleEvent); 447 }); 448 }, 449 /// 说明: 450 /// Tr Dblclick 451 _registerTbodyTrDblclick: function () { 452 var options = this.options; 453 $("table[datagrid $='" + options.id + "'] tbody tr").each(function () { 454 var handleEvent = $.delegate(dataGrid.prototype._handleTbodyTrDblclick, this, [{ options: options }]); 455 var itemDblclickCallBack = $.delegate(options.tBodyTrDblclickCallBack, this, [{ id: $(this).attr("trId") }]);//回调事件 456 $(this).dblclick(handleEvent); 457 $(this).dblclick(itemDblclickCallBack); 458 }); 459 }, 460 /// 说明: 461 /// Tr Checkbox 462 _registerTbodyTrCheckbox: function () { 463 var options = this.options; 464 //点击checkbox时候屏蔽tr的click事件,以防和tr的click事件重复 465 var objCheckAll = $("table[datagrid $='" + options.id + "'] tbody[gdTbody ='" + options.id + "'] tr").find("input:checkbox"); 466 objCheckAll.each(function () { 467 var handleEvent = $.delegate(dataGrid.prototype._handleTbodyTrCheckbox, this, [{ options: options, objCheckAll: objCheckAll }]); 468 $(this).click(function (event) { 469 event.stopPropagation(); 470 handleEvent(); 471 }); 472 }); 473 }, 474 /// 说明: 475 /// Tr Click 476 _registerTbodyTrClick: function () { 477 var options = this.options; 478 $("table[datagrid $='" + options.id + "'] tbody tr").each(function () { 479 var handleEvent = $.delegate(dataGrid.prototype._handleTbodyTrClick, this, [{ options: options }]); 480 $(this).click(handleEvent); 481 }); 482 }, 483 /// 说明: 484 /// PageNumber Keyup 485 _registerPageNumberKeyup: function () { 486 var options = this.options; 487 $("#txtPageNumber_" + options.id).bind('keyup', function (e) { 488 dataGrid.prototype._handlePageNumberKeyup(e, options); 489 }); 490 }, 491 /// 说明: 492 /// PageNumber paste 493 _registerPageNumberPaste: function () { 494 var options = this.options; 495 $("#txtPageNumber_" + options.id).bind("paste", function () { //CTR+V事件处理 496 dataGrid.prototype._handlePageNumberPaste(options); 497 }); 498 }, 499 /// 说明: 500 /// PageNumber Focus 501 _registerPageNumberFocus: function () { 502 var options = this.options; 503 $("#txtPageNumber_" + options.id).focus(); 504 }, 505 /// 说明: 506 /// Checkbox CheckAll 507 _registerCheckboxCheckAll: function () { 508 var options = this.options; 509 var handleEvent = $.delegate(this._handleCheckboxCheckAll, this); 510 $("input:checkbox[name='chk_All_" + options.id + "']").change(handleEvent); 511 }, 512 /******************************(注册事件 end)******************************/ 513 /******************************(事件句柄 begin)******************************/ 514 /// 说明: 515 /// Go To 516 _handleTableFootGoTo: function () { 517 var options = this.options; 518 var pageNumber = $("#txtPageNumber_" + options.id).val(); 519 if ($.IsNull(pageNumber)) { 520 $("#txtPageNumber_" + options.id).val(options.currentPage); 521 alert("输入的页数必须是数字且不能为空!"); 522 return; 523 } 524 var cuPage = parseInt($("#txtPageNumber_" + options.id).val()); 525 if (cuPage > options.pageCount) { 526 alert("超出了最大页数!"); 527 $("#txtPageNumber_" + options.id).val(options.currentPage); 528 return; 529 } 530 options.currentPage = cuPage; 531 this.jumpPage(); 532 }, 533 /// 说明: 534 /// First Page 535 _handleTableFootFirstPage: function () { 536 this.firstPage(); 537 }, 538 /// 说明: 539 /// Last Page 540 _handleTableFootLastPage: function () { 541 this.finalPage(); 542 }, 543 /// 说明: 544 /// Up Page 545 _handleTableFootUpPage: function () { 546 this.lastPage(); 547 }, 548 /// 说明: 549 /// Next Page 550 _handleTableFootNextPage: function () { 551 this.nextPage(); 552 }, 553 /// 说明: 554 /// Tr Mouseover 555 _handleTbodyTrMouseover: function (params) { 556 var options = params.options; 557 var obj = $(this).find("td input:checkbox"); 558 if (obj.attr("checked")) { 559 options.tBodyMouserOutBgcolor = options.tBodyTrSelectedBgColor; 560 } 561 $(this).css("background-color", options.tBodyMouserOverBgcolor); 562 }, 563 /// 说明: 564 /// Tr Mouseout 565 _handleTbodyTrMouseout: function (params) { 566 var options = params.options; 567 var obj = $(this).find("td input:checkbox"); 568 if (obj.attr("checked")) { 569 $(this).css("background-color", options.tBodyTrSelectedBgColor); 570 } else { 571 var trRowNumber = parseInt($(this).attr("trRowNumber")); 572 if (trRowNumber % 2 == 1) { 573 $(this).css("background-color", options.tBodyOddTrBgcolor); 574 } else { 575 $(this).css("background-color", options.tBodyEvenTrBgcolor); 576 } 577 } 578 if (obj.attr("checked")) { 579 options.tBodyMouserOutBgcolor = options.tBodyTrSelectedBgColor; 580 $(this).css("background-color", options.tBodyMouserOutBgcolor); 581 } 582 }, 583 /// 说明: 584 /// Tr Dblclick 585 _handleTbodyTrDblclick: function (params) { 586 var options = params.options; 587 var obj = $(this).find("td input:checkbox"); 588 obj.attr("checked", true); 589 $(this).css("background-color", options.tBodyTrSelectedBgColor); 590 }, 591 /// 说明: 592 /// Tr Checkbox 593 _handleTbodyTrCheckbox: function (params) { 594 var options = params.options; 595 var objCheckAll = params.objCheckAll; 596 var chkAll = true; 597 objCheckAll.each(function (i, trCheck) { 598 if (!trCheck.checked) { 599 $("input:checkbox[name='chk_All_" + options.id + "']").attr("checked", false); 600 chkAll = false; 601 } 602 }); 603 if (chkAll) { 604 $("input:checkbox[name='chk_All_" + options.id + "']").attr("checked", true); 605 } 606 var objCheck = $(this); 607 var chkNumber = objCheck.attr("chkNumber"); 608 var objTr = $("table[datagrid $='" + options.id + "'] tbody[gdTbody ='" + options.id + "'] tr[trRowNumber='" + chkNumber + "']"); 609 dataGrid.prototype.setSelectedRowStyle(objCheck, objTr, options); 610 }, 611 /// 说明: 612 /// Tr Click 613 _handleTbodyTrClick: function (params) { 614 var options = params.options; 615 var objCheck = $(this).find("td input:checkbox"); 616 objCheck.attr("checked", !objCheck.attr("checked")); 617 var objTr = $(this); 618 dataGrid.prototype.setSelectedRowStyle(objCheck, objTr, options); 619 var chkAll = true; 620 $("table[datagrid $='" + options.id + "'] tbody[gdTbody ='" + options.id + "'] tr").find("input:checkbox").each(function (i, trCheck) { 621 if (!trCheck.checked) { 622 $("input:checkbox[name='chk_All_" + options.id + "']").attr("checked", false); 623 chkAll = false; 624 } 625 }); 626 if (chkAll) { 627 $("input:checkbox[name='chk_All_" + options.id + "']").attr("checked", true); 628 } 629 }, 630 /// 说明: 631 /// PageNumber Keyup 632 _handlePageNumberKeyup: function (e, options) { 633 var curKey = e.which; 634 if (curKey == 13) { 635 $("#txtPageNumber_" + options.id).blur(); //失去焦点,目的为了增强火狐的用户体验 636 var pageNumber = $("#txtPageNumber_" + options.id).val(); 637 if ($.IsNull(pageNumber)) { 638 $("#txtPageNumber_" + options.id).val(options.currentPage); 639 alert("输入的页数必须是数字且不能为空!"); 640 return; 641 } 642 var cuPage = parseInt(pageNumber); 643 if (cuPage > options.pageCount) { 644 alert("超出了最大页数!"); 645 $("#txtPageNumber_" + options.id).val(options.currentPage); 646 return; 647 } 648 options.currentPage = cuPage; 649 dataGrid.prototype.jumpPage(options); 650 } 651 var objThis = $("#txtPageNumber_" + options.id); 652 objThis.val(objThis.val().replace(/\D|^0/g, '')); 653 }, 654 655 /// 说明: 656 /// PageNumber paste 657 _handlePageNumberPaste: function (options) { 658 var objThis = $("#txtPageNumber_" + options.id); 659 objThis.val(objThis.val().replace(/\D|^0/g, '')); 660 }, 661 662 /// 说明: 663 /// Checkbox CheckAll 664 _handleCheckboxCheckAll: function () { 665 var options = this.options; 666 var objThis = $("input:checkbox[name='chk_All_" + options.id + "']"); 667 var objCheck = $("table[datagrid $='" + options.id + "'] tbody[gdTbody ='" + options.id + "'] tr").find("input:checkbox"); 668 if (objThis.attr("checked")) { 669 objCheck.each(function () { 670 $(this).attr("checked", true); 671 }); 672 $("table[datagrid $='" + options.id + "'] tbody tr").css("background-color", options.tBodyTrSelectedBgColor); 673 return; 674 } 675 objCheck.each(function () { 676 $(this).attr("checked", false); 677 var trRowNumber = parseInt($(this).attr("chkNumber")); 678 var objTr = $("table[datagrid $='" + options.id + "'] tbody tr[trRowNumber='" + trRowNumber + "']"); 679 if (trRowNumber % 2 == 1) { 680 objTr.css("background-color", options.tBodyOddTrBgcolor); 681 } else { 682 objTr.css("background-color", options.tBodyEvenTrBgcolor); 683 } 684 }); 685 }, 686 /******************************(事件句柄 end)******************************/ 687 //设置选中行的样式 688 // objCheck:选中行中的checkbox 689 // objTr:选中行 690 // options:参数 691 setSelectedRowStyle: function (objCheck, objTr, options) { 692 if (objCheck.attr("checked")) { 693 objTr.css("background-color", options.tBodyTrSelectedBgColor); 694 } else { 695 var trRowNumber = parseInt(objTr.attr("trRowNumber")); 696 if (trRowNumber % 2 == 1) { 697 objTr.css("background-color", options.tBodyOddTrBgcolor); 698 } else { 699 objTr.css("background-color", options.tBodyEvenTrBgcolor); 700 } 701 } 702 } 703 };
第四部分:对外开放部分。这部分代码很少也是老生常谈的代码了。定义对外开放,也就是一句话的事。代码如下:
1 $.fn.gridData = new dataGrid();
第五部分:具体使用部分。下面分两块代码叙说,第一块就是html页面,第二块就是js使用代码。代码如下:
1 <table id="aa" datagrid=""></table>
1 $(function () { 2 var options = { 3 pageCount: 10, //总页数 4 pageSize: 10, //每页显示个数 5 currentPage: 1, //当前页 6 tBoolPage: true 7 }; 8 options.tHeadCols = [ 9 [ 10 { field: 'ID', title: '产品编号', width: 150, align: 'center', sortable: true }, 11 { field: 'ProductName', title: '产品名称', width: 150, align: 'center', sortable: true }, 12 { field: 'Description', title: '描述', width: 200, align: 'center' }, 13 { field: 'Mark', title: '备注', width: 150, align: 'center' }, 14 { field: 'ProductCategoryID', title: '产品类别', width: 150, align: 'center' }, 15 { field: 'Price', title: '价格', width: 150, align: 'center' } 16 ] 17 ]; 18 $("#aa").gridData.init({ 19 id: "aa", 20 url: "../Product/GetPageProductInfo", 21 tHeadCols: options.tHeadCols, 22 tEnumDataGridSkin: $.enumDdataGrid.enumSkin.gorgeous, 23 tBoolRowNumbers: false, 24 trTdentity: "ID", 25 pageSize: options.pageSize, 26 currentPage: options.currentPage, 27 pageCount: options.pageCount, 28 tBoolPage: options.tBoolPage, 29 tBodyTrDblclickCallBack: function (params) { 30 var id = params.id; 31 alert("this id is:" + id); 32 } 33 }); 34 });
效果图
下面是我贴的几个效果图,本人审美不好,随意加的样式,没有搭配感,还请各位看官一笑而过,只要知道有啥作用就好。
效果图一(绚丽):
效果图二(传统):
总结
虽然写的不好,但是总结还是要的。本次开发属于重构之前代码开发。在此还是希望各位能注重重构,对自己代码负责。好的插件、好的代码也是重构出来的。哈哈,我是这么想的。不要嫌麻烦,也不要以为做的是无用功。
文章比较长,很多知识点我也没有写详细。如果有需要源码的或者想共同探讨的同仁,随时联系我,QQ:296319075 ,注明园友就好,同时也希望大家也能提出宝贵意见,不吝赐教。秉承共同探讨、共同进步!如有转载,请注明出处,谢谢!^_^