首页 > 代码库 > 自定义JS组件——系列1(TableGrid | Toolbar | LinkButton | Pager)

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

2月份第一次JS组件,写了几个:TableGrid, Toolbar, LinkButton, Pager,现在发出来。 TableGrid可以包含Toolbar, Pager。 Toolbar可以包含LinkButton。这样就构成了具有工具栏、分页栏的数据表格控件。也就是说,这4个组件可以独立使用,也可以结合使用。通篇只采用一种结构来编写,若能看懂编写规则,往后就可以按照这种模式自定义JS控件了。
  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=http://www.mamicode.com/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.DEFAULT242     };243     244     /**245      * @param options246      *         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.DEFAULT283     };284     285     /**286      * @param options287      *         cls:{String} // 按钮的class属性288      *         text:{String}// 按钮上显示的文本289      *         click:{Function}//点击事件处理290      *         href:{String}链接地址,点击事件处理完毕,会将页面链接到指定的URL291      *         target:{String}就是Anchor的target292      */293     LinkButton.prototype._init=function(options){294         this.cfg=$.extend({}, LinkButton.defaultOptions, options);295         var css_class=this.cfg.cls,296             href=http://www.mamicode.com/this.cfg.href || LinkButton.defaultOptions.href; 297         this.btn=$("<a class=‘"+css_class+"‘ href=http://www.mamicode.com/‘"+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 options341      *         pageSizeList:[5, 10, 15, 20],342      *         handler:{343      *             onPageSizeChanged:function(pagesize){}// 参数是页面记录数目344      *             onSelectPage:function(pageNum, pagesize){}345      *         },346      *         pagesize:10,347      *         recordTotal:10348      */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=http://www.mamicode.com/parseInt(this.cfg.pageSizeList[i],10);358             if(value=http://www.mamicode.com/=this.cfg.pagesize){359                 pagesizeHTML+="<option value=http://www.mamicode.com/‘"+value+"‘ selected=‘selected‘>"+value+"</option>";360             }else{361                 pagesizeHTML+="<option value=http://www.mamicode.com/‘"+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, currentPage457      */ 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 total468      */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:Pager496     });497     498 })(jQuery,fjn);
TableGrid、Toolbar、LinkButton、Pager 的源码

 

相关CSS,实现JS代码和CSS样式的分离:
 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 的样式