自定义JS组件——系列1(TableGrid | Toolbar | LinkButton | Pager)

2月份第一次JS组件,写了几个:TableGrid, Toolbar, LinkButton, Pager,现在发出来。 TableGrid可以包含Toolbar, Pager。 Toolbar可以包含LinkButton。这样就构成了具有工具栏、分页栏的数据表格控件。也就是说,这4个组件可以独立使用,也可以结合使用。通篇只采用一种结构来编写,若能看懂编写规则,往后就可以按照这种模式自定义JS控件了。
自定义JS组件——系列1(TableGrid | Toolbar | LinkButton | Pager)
  1 var fjn=fjn?fjn:{};
  2 (function($,global){
  3     // 确保先加载jQuery.js
  4     if($!=jQuery) {
  5         throw Error("you must load jQuery.js before this javascript file");
  6     }
  7     /*
  8     container可以是jQuery对象,jQuery selector, DOM对象
  9     1:jQuery
 10     2:DOM,jQuery Selector
 11     3:Other
 12     */
 13     function getRealContainer(container){
 14         var real,
 15             containerType=container instanceof jQuery ? 1 : container.nodeType ? 2 : typeof(container)!=‘string‘ ? 3 : $(container)[0] ? 2 : 3 ;
 16         switch(containerType){
 17             case 1:
 18                 real=container;
 19                 break;
 20             case 2:
 21                 real=$(container);
 22                 break;
 23             case 3:
 24                 real=null;
 25                 throw new Error("参数conatiner="+container+"不能代表一个容器!当前对象是:"+this);
 26         }
 27         return real;
 28     };
 29     
 30     
 31     function TableGrid(container,options){
 32         if(!(this instanceof TableGrid)) return;
 33         this.container=getRealContainer.call(this,container);
 34         this._init(options);
 35     }
 36     
 37     TableGrid.cssClass={
 38         DEFAULT:"tablegrid",
 39         SELECT_All:"selectAll",
 40         ROW_CHECK:"rowCheck",
 41         EVEN:"even",
 42         ODD:"odd",
 43         DATA_CELL:"dataCell",
 44         HEADER:"header",
 45         TR_MOUSEOVER:"mouseover",
 46         TR_SELECTED:"selected"
 47     };
 48 
 49     TableGrid.defaultOptions={
 50         title:"TableGrid",
 51         checkable:true,
 52         columns:[],
 53         cls:TableGrid.cssClass.DEFAULT,
 54         toolbar:null,
 55         pager:null
 56     };
 57     
 58     TableGrid.otherInfo={
 59         bgcolor_onmouseover:"YELLOW"
 60     };
 61 
 62         /**
 63          * @param options {Object}
 64          * 必要的选项
 65          *    
 66             columns:[{
 67                     name:"", // 表格的列名
 68                     field:""//
 69                 }]
 70             可选项:
 71                 toolbarCfg:{}//其实是Toolbar的options
 72                 cls:cssClass
 73                 style:"" // 也可以使用自定义style,这个优先级高
 74                 pagerCfg:{}//可以在表格下面加入分页工具
 75          */
 76     TableGrid.prototype._init=function(options){
 77             
 78         this.cfg=$.extend({},TableGrid.defaultOptions,options);
 79         // 添加工具条
 80         if(this.cfg.toolbarCfg){
 81             this._initToolbar();
 82         }
 83         // 检查配置项
 84         if(!(this.cfg.columns && this.cfg.columns.length>0)){
 85             new Error("配置项columns必须设置");
 86         }
 87 
 88         this.table=$("<table class=‘"+this.cfg.cls+"‘></table>");
 89         
 90         // 添加表头
 91         var thead=$("<thead></thead>");
 92         var tr=$("<tr></tr>"),
 93             td,
 94             me=this;
 95         // 添加选择框
 96         if(this.cfg.checkable){
 97             var checkbox=$("<input type=‘checkbox‘>");
 98             checkbox.click(function(){
 99                 if(this.checked){
100                     $("tbody td."+TableGrid.cssClass.ROW_CHECK+" input[type=‘checkbox‘]",me.table).attr("checked","checked");
101                     $("tbody tr", me.table).addClass(TableGrid.cssClass.TR_SELECTED);
102                 }else{
103                     $("tbody td."+TableGrid.cssClass.ROW_CHECK+" input[type=‘checkbox‘]",me.table).removeAttr("checked");
104                     $("tbody tr", me.table).removeClass(TableGrid.cssClass.TR_SELECTED);
105                 }
106             });
107             td=$("<th></th>").append(checkbox);
108             tr.append(td);
109         }
110         // 添加表头
111         for(var i=0; i<this.cfg.columns.length; i++){
112             var style=this.cfg.columns[i].style || "";
113             td=$("<th class=‘"+TableGrid.cssClass.HEADER+"‘ style=‘"+style+"‘></th>").html(this.cfg.columns[i].name);
114             tr.append(td);
115         }
116         this.container.append(this.table.append(thead.append(tr)));
117         this.table.append("<tbody></tbody>");
118         
119         // 初始化分页工具
120         if(this.cfg.pagerCfg){
121             this._initPager();
122         }
123         
124     };
125     
126     /**
127      * 
128      * @param url        是要访问的资源的URL,可以是一个JSON文件,也可以是action地址
129      * @param params    是异步访问传递的参数
130      * @param filter    暂时没有使用到
131      * @param success    数据加载后的处理
132      */
133     TableGrid.prototype.load=function(url, params, filter, success){
134         params=params||{};
135         if(this.cfg.pagerCfg){
136             params.pageNumber=this.getPager().getPageNumber();
137             params.pagesize=this.getPager().getPageSize();
138             params.recordTotal=this.getPager().getRecordTotal();
139         }
140         
141     //    console.log(params);
142         var me=this;
143         $.getJSON(url,params,function(list){
144             if(list){
145                 var tbody=$("tbody", me.table);
146                 tbody.empty();
147                 for(var i=0; i<list.length; i++){
148                     var tr_odd_even=i&1==1?TableGrid.cssClass.EVEN:TableGrid.cssClass.ODD;
149                     var tr=$("<tr class=‘"+tr_odd_even+"‘ ></tr>");
150                     
151                     // 添加选择框
152                     if(me.cfg.checkable){
153                         var checkbox=$("<input type=‘checkbox‘>");
154                         td=$("<td class=‘"+TableGrid.cssClass.ROW_CHECK+"‘></td>").append(checkbox);
155                         checkbox.click(function(event){
156                             event.stopPropagation();
157                             if(this.checked){
158                                 $(this).parent().parent().addClass(TableGrid.cssClass.TR_SELECTED);
159                             }else{
160                                 $(this).parent().parent().removeClass(TableGrid.cssClass.TR_SELECTED);
161                             }
162                         });
163                         tr.append(td);
164                         
165                     }
166 
167                     var obj=list[i],
168                         field,    // 后台对象的属性
169                         value;
170                     for(var j=0; j<me.cfg.columns.length; j++){
171                         field=me.cfg.columns[j].field;
172                         value=obj[field];
173                         td=$("<td></td>").html(value);
174                         
175                         tr.append(td);
176                     }
177                     tr.bind({
178                         mouseover:function(){
179                             this.className+=" "+TableGrid.cssClass.TR_MOUSEOVER;
180                         },
181                         mouseout:function(){
182                             $(this).removeClass(TableGrid.cssClass.TR_MOUSEOVER);
183                         },
184                         click:function(){
185                             if(me.cfg.checkable){
186                                 var checkbox=$("td."+TableGrid.cssClass.ROW_CHECK+" input[type=‘checkbox‘]",this);
187                                 
188                                 if(checkbox[0].checked){
189                                     checkbox.removeAttr("checked");
190                                     $(this).removeClass(TableGrid.cssClass.TR_SELECTED);
191                                 }else{
192                                     checkbox.attr("checked","checked");
193                                     this.className+=" "+TableGrid.cssClass.TR_SELECTED;
194                                 }
195                             }
196                             
197                         }
198                     
199                     });
200                     tbody.append(tr);
201                 }
202             }
203             
204             if(typeof success==‘function‘) success();
205         });
206         
207     };
208 
209     TableGrid.prototype._initToolbar=function(){
210         this.toolbar=new Toolbar(this.container, this.cfg.toolbarCfg);
211     };
212     
213     TableGrid.prototype._initPager=function(){
214         this.pager=new Pager(this.container, this.cfg.pagerCfg);
215     };
216     // 获取到表格组件内的中的分页组件
217     TableGrid.prototype.getPager=function(){
218         return this.pager;
219     }
220         
221     // 获取到所有选择项
222     TableGrid.prototype.getSelected=function(){
223         
224     }
225     
226     
227     
228     /*---------------------------------------Toolbar-----------------------------------------*/
229     function Toolbar(container, options){
230         if(!(this instanceof Toolbar)) return;
231         this.container=getRealContainer.call(this,container);
232         this._init(options);
233     }
234     
235     Toolbar.cssClass={
236         DEFAULT:"toolbar"
237     };
238     
239     Toolbar.defaultOptions={
240         buttons:[],
241         cls:Toolbar.cssClass.DEFAULT
242     };
243     
244     /**
245      * @param options
246      *         buttons:Array    工具条上的按钮
247      */
248     Toolbar.prototype._init=function(options){
249         this.cfg=$.extend({}, Toolbar.defaultOptions, options);
250         this.toolbar=$("<div class=‘"+Toolbar.cssClass.DEFAULT+"‘></div>");
251         if(this.cfg.buttons){
252             for(var i=0; i< this.cfg.buttons.length; i++){
253                 new LinkButton(this.toolbar, this.cfg.buttons[i]);
254             }
255         }
256         this.container.append(this.toolbar);
257     };
258     
259     
260     /*----------------------------------------LinkButton-------------------------------------*/
261     
262     function LinkButton(container,options){
263         if(!(this instanceof LinkButton)) return;
264         this.container=getRealContainer.call(this,container);
265         this._init(options);
266         if(this.container){
267             this.container.append(this.btn);
268         }
269     }
270     
271     LinkButton.cssClass={
272         DEFAULT:"button",
273         SAVE:"btn_save",
274         EDIT:"btn_edit",
275         DELETE:"btn_del"
276     };
277     
278     LinkButton.defaultOptions={
279         href:"javascript:void(0)",
280         target:"_blank",    //是<a>的target属性
281         text:"Button", //    是按钮上的文本
282         cls:LinkButton.cssClass.DEFAULT
283     };
284     
285     /**
286      * @param options
287      *         cls:{String} // 按钮的class属性
288      *         text:{String}// 按钮上显示的文本
289      *         click:{Function}//点击事件处理
290      *         href:{String}链接地址,点击事件处理完毕,会将页面链接到指定的URL
291      *         target:{String}就是Anchor的target
292      */
293     LinkButton.prototype._init=function(options){
294         this.cfg=$.extend({}, LinkButton.defaultOptions, options);
295         var css_class=this.cfg.cls,
296             href=this.cfg.href || LinkButton.defaultOptions.href; 
297         this.btn=$("<a class=‘"+css_class+"‘ href=‘"+href+"‘>"+this.cfg.text+"</a>");
298         if(typeof this.cfg.click ==‘function‘){
299             this.btn.on("click",this.cfg.click);
300         }
301     };
302     
303     /*------------------------------------Pager----------------------------------------*/
304     //    每页【xx】条    共X页        【首页】【上一页】【第N页】【下一页】【尾页】
305     function Pager(container, options){
306         if(!(this instanceof Pager)) return;
307         this.container=getRealContainer.call(this,container);
308         this._init(options);
309     }
310     
311     Pager.cssClass={
312         DEFAULT:"pager",
313         PAGE_SIZE:"pagesize",// 页面大小
314         FIRST:"first",//首页
315         LAST:"last",//尾页
316         PREV:"prev",//上一页
317         NEXT:"next",//下一页
318         PAGE_NUMBER:"pageNumber",//第N页
319         PAGE_RIGHT:"pagerRight",
320         MAX_PAGE:"maxPage",
321         RECORD_TOTAL:"recordTotal",
322         CURRENT_PAGE:"currentPage"
323     };
324         
325     Pager.defaultOptions={
326         cls:Pager.cssClass.DEFAULT,
327         pageSizeList:[5,10,15,20],
328         handler:{
329             onSelectPage:function(pageNum, pagesize){},
330             onPageSizeChanged:function(pagesize){}
331         },
332         pageNumber:1,    //     要请求的页码
333         recordTotal:0,    //    总的记录数目
334         maxPage:0,        //    最大页码数
335         pagesize:10,    //    每页数据行数
336         currentPage:1    //    当前显示的页码
337     };
338     
339     /**
340      * @param options
341      *         pageSizeList:[5, 10, 15, 20],
342      *         handler:{
343      *             onPageSizeChanged:function(pagesize){}// 参数是页面记录数目
344      *             onSelectPage:function(pageNum, pagesize){}
345      *         },
346      *         pagesize:10,
347      *         recordTotal:10
348      */
349     Pager.prototype._init=function(options){
350         this.cfg=$.extend({}, Pager.defaultOptions, options);
351         this.page=$("<div class=‘"+Pager.cssClass.DEFAULT+"‘></div>");
352         
353         // 设置页面记录长度
354         var me=this,
355             pagesizeHTML="<select class=‘"+Pager.cssClass.PAGE_SIZE+"‘ name=‘pagesize‘>";
356         for(var i=0; i<this.cfg.pageSizeList.length; i++){
357             var value=parseInt(this.cfg.pageSizeList[i],10);
358             if(value==this.cfg.pagesize){
359                 pagesizeHTML+="<option value=‘"+value+"‘ selected=‘selected‘>"+value+"</option>";
360             }else{
361                 pagesizeHTML+="<option value=‘"+value+"‘>"+value+"</option>";
362             }
363         }
364         pagesizeHTML+="</select>";
365         
366         var pagesizeSelect=$(pagesizeHTML).change(function(){
367             me.cfg.pagesize=parseInt(pagesizeSelect.val(),10);
368             //    执行自定义操作
369             me.cfg.handler.onPageSizeChanged(me.cfg.pagesize);
370             //    更新page数据
371             me._updateSelf();
372         });
373         
374         
375         // 首页,上一页,下一页,尾页
376         var firstSpan=$("<span title=‘首页‘ class=‘"+Pager.cssClass.FIRST+"‘>&nbsp;&nbsp;&nbsp;</span>"),
377             prevSpan=$("<span title=‘上一页‘ class=‘"+Pager.cssClass.PREV+"‘>&nbsp;&nbsp;&nbsp;</span>"),
378             nextSpan=$("<span title=‘下一页‘ class=‘"+Pager.cssClass.NEXT+"‘>&nbsp;&nbsp;&nbsp;</span>"),
379             lastSpan=$("<span title=‘尾页‘ class=‘"+Pager.cssClass.LAST+"‘>&nbsp;&nbsp;&nbsp;</span>");
380         firstSpan.click(function(){
381             me.cfg.pageNumber=1;
382             me.cfg.handler.onSelectPage(me.cfg.pageNumber, me.cfg.pagesize);
383             me._updateSelf();
384         });
385         prevSpan.click(function(){
386             if(me.cfg.currentPage>1){
387                 me.cfg.pageNumber=me.cfg.currentPage-1;
388                 me.cfg.handler.onSelectPage(me.cfg.pageNumber, me.cfg.pagesize);
389                 me.cfg.currentPage-=1;
390                 me._updateSelf();
391             }
392         });
393         nextSpan.click(function(){
394         //    console.log("当前第"+me.cfg.currentPage+"页");
395             if(me.cfg.currentPage<me.cfg.maxPage){
396                 me.cfg.pageNumber=me.cfg.currentPage+1;
397                 me.cfg.handler.onSelectPage(me.cfg.pageNumber, me.cfg.pagesize);
398                 me.cfg.currentPage+=1;
399                 me._updateSelf();
400             }
401         });
402         lastSpan.click(function(){
403             me.cfg.pageNumber=me.cfg.maxPage;
404             me.cfg.handler.onSelectPage(me.cfg.pageNumber, me.cfg.pagesize);
405             me.cfg.currentPage=me.cfg.maxPage;
406             me._updateSelf();
407         });
408         
409         // 第N页
410         var pageNumberSpan=$("<input class=‘"+Pager.cssClass.PAGE_NUMBER+"‘ maxlength=‘3‘>");
411         pageNumberSpan.change(function(){
412             var v=parseInt(pageNumberSpan.val(),10);
413             if(v<=0){
414                 v=1;
415                 pageNumberSpan.val(v);
416             }else if(v>me.cfg.maxPage){
417                 v=me.cfg.maxPage;
418                 pageNumberSpan.val(v);
419             }
420             me.cfg.pageNumber=v;
421             me.cfg.handler.onSelectPage(me.cfg.pageNumber, me.cfg.pagesize);
422             me.cfg.currentPage=me.cfg.maxPage;
423             me._updateSelf();
424         });
425         var descDiv="<div class="+Pager.cssClass.PAGE_RIGHT+">共<span class=‘"+Pager.cssClass.RECORD_TOTAL+"‘>"+me.cfg.recordTotal+"</span>条,第<span class=‘"+Pager.cssClass.CURRENT_PAGE+"‘>"+me.cfg.currentPage+"</span>页&nbsp;&nbsp;共<span class=‘"+Pager.cssClass.MAX_PAGE+"‘>"+me.cfg.maxPage+"</span>页</div>";
426         this.page.append(pagesizeSelect)
427                 .append(firstSpan)
428                 .append(prevSpan)
429                 .append(pageNumberSpan)
430                 .append(nextSpan)
431                 .append(lastSpan)
432                 .append(descDiv);
433         this.container.append(this.page);
434         
435         this._updateSelf();
436     };
437         
438     Pager.prototype._clac=function(){
439         if(this.cfg.recordTotal<=0){
440             this.cfg.pageNumber=1;
441             return;
442         }
443         // 下面是存在记录时的处理:
444         if(this.cfg.pagesize<=0){
445             this.cfg.pagesize=Pager.defaultOptions.pagesize;
446         }
447         if(this.cfg.pageNumber<=0){
448             this.cfg.pageNumber==1;
449         }
450 //        console.log(this.cfg.recordTotal, this.cfg.pagesize, this.cfg.pageNumber);
451         this.cfg.maxPage=parseInt(this.cfg.recordTotal%this.cfg.pagesize==0?this.cfg.recordTotal/this.cfg.pagesize:(this.cfg.recordTotal/this.cfg.pagesize+1),10);
452 //        console.log("maxpage=",this.cfg.maxPage);
453     },
454         
455     /**
456      * 修改页面显示,显示正确的totalRecord, maxPage, currentPage
457      */ 
458     Pager.prototype._updateSelf=function(){
459         this._clac();
460         $("span."+Pager.cssClass.MAX_PAGE,this.page).html(this.cfg.maxPage);
461         $("span."+Pager.cssClass.RECORD_TOTAL,this.page).html(this.cfg.recordTotal);
462         $("span."+Pager.cssClass.CURRENT_PAGE,this.page).html(this.cfg.currentPage);
463     };
464     
465     /**
466      * 设置总数
467      * @param total
468      */
469     Pager.prototype.setRecordTotal=function(total){
470         this.cfg.recordTotal=total;
471         this._updateSelf();
472     }
473     
474     Pager.prototype.getRecordTotal=function(total){
475         return this.cfg.recordTotal;
476     }
477     
478     Pager.prototype.getPageNumber=function(){
479         return this.cfg.pageNumber;
480     }
481     
482     Pager.prototype.getPageSize=function(){
483         return this.cfg.pagesize;
484     }
485     
486     
487     
488     /*--------------------------------------------------------------------*/
489     
490     $.extend(global,{
491         getRealContainer:getRealContainer,
492         TableGrid:TableGrid,
493         Toolbar:Toolbar,
494         LinkButton:LinkButton,
495         Pager:Pager
496     });
497     
498 })(jQuery,fjn);
TableGrid、Toolbar、LinkButton、Pager 的源码

 

相关CSS,实现JS代码和CSS样式的分离:
自定义JS组件——系列1(TableGrid | Toolbar | LinkButton | Pager)
 1 @CHARSET "UTF-8";
 2 /*-------------------------------TableGrid---------------------------*/
 3 table.TableGrid{
 4     border-collapse: collapse;
 5     border: 2px solid #ACE;
 6     width: 100%;
 7     height: 95%;
 8 }
 9 
10 table.TableGrid thead th{
11     width:auto;
12     border: 1px solid #ACE;
13     font: ‘宋体‘;
14     font-size:14px; 
15     height: 1.5em;
16     color: blue;
17     background: #ACE;
18     border-right: 1px solid #FFF;
19 }
20 
21 table.TableGrid tbody tr{
22     height: 1.2em;
23 }
24 
25 table.TableGrid tbody tr.mouseover.even{
26     background-color: YELLOW;
27 }
28 
29 table.TableGrid tbody tr.mouseover{
30     background-color: YELLOW;
31 }
32 
33 table.TableGrid tbody tr.selected{
34     background-color: YELLOW;
35 }
36 table.TableGrid tbody tr.selected.even{
37     background-color: YELLOW;
38 }
39 
40 table.TableGrid tbody tr.even{
41     background-color: #beddde;
42 }
43 
44 table.TableGrid tbody td{
45     border: 1px solid #ACE;
46     text-align: right;
47     height: 1.2em;
48 }
49 
50 table.TableGrid tbody td.rowCheck{
51     text-align: center;
52 }
53 
54 /*----------------------------------ToolBar LinkButton----------------------------------*/
55 div.toolbar a.button{
56     border: 1px solid #ACE;
57     padding: 2px 3px;
58     text-decoration: none;
59     margin: 2px 2px 3px 0;
60 }
61 /*----------------------------------Pager---------------------------------------*/
62 div.pager div.pagerRight{
63     display: inline;
64     float: right;
65 }
66 div.pager input.pageNumber{
67     width:30px;
68 }
69 
70 div.pager span{
71     margin:3px 3px;
72 }
73 div.pager span.first{
74     background: url(‘../img/pagination_first.gif‘) no-repeat;
75     cursor: pointer;
76     padding: 2px 1px;
77 }
78 div.pager span.prev{
79     background: url(‘../img/pagination_prev.gif‘) no-repeat;
80     cursor: pointer;
81     padding: 2px 1px;
82 }
83 div.pager span.next{
84     background: url(‘../img/pagination_next.gif‘) no-repeat;
85     cursor: pointer;
86     padding: 2px 1px;
87 }
88 div.pager span.last{
89     background: url(‘../img/pagination_last.gif‘) no-repeat;
90     cursor: pointer;
91     padding: 2px 1px;
92 }
TableGrid、Toolbar、LinkButton、Pager 的样式

 

自定义JS组件——系列1(TableGrid | Toolbar | LinkButton | Pager),布布扣,bubuko.com

自定义JS组件——系列1(TableGrid | Toolbar | LinkButton | Pager)

上一篇:UI自动化常见精华面试题整理


下一篇:restful风格,restcontroller与controller