先上插件代碼javascript
(function ($) { var aop = {}; /** *aop攔截算法 */ (function($adv) { $adv.before = function (method, advice) { var original = methodFactory[method]; methodFactory[method] = function (renderTarget) { advice(); original(renderTarget); }; }, $adv.after = function (method, advice) { var original = methodFactory[method]; methodFactory[method] = function (renderTarget) { original(renderTarget); advice(); }; }, $adv.callback = function (method, callback){ var original = methodFactory[method]; methodFactory[method] = function (renderTarget) { original(callback); }; }; })(aop); /** *配置格式 method - {before:method,after:method,callback:method} *aop工廠,主要是配置須要攔截的的方法,及攔截方式, */ var aopFactory = { createPagination : { before : "onBeforeCreatePagination", after : "onAfterCreatePagination" }, createHeader : { before : "onBeforeCreateHeader", after : "onAfterCreateHeader" }, testCallBack : { callback : "callbacktest" } }; /** *@target 用來渲染grid的元素id * aop引擎,先到aopFactory裏找到須要攔截的方法,檢查初始化參數裏面是否有對應的方法,若是有, * 則經過aop攔截算法去改變methodFactory的相對應方法進行攔截 */ var aopEngine = function (target) { var opts = target.data("datagrid"); for (var i in aopFactory) { var advice = aopFactory[i]; if (advice) { aop.renderTarget = target; var before = opts[advice["before"]]; if (before) { aop.before(i, before); }; var after = opts[advice["after"]]; if (after) { original = aop.after(i, after); }; var callback = opts[advice["callback"]]; if (callback) { original = aop.callback(i, callback); }; }; }; }; //方法工廠,全部方法都入住,也必須經過methodFactory來調用纔可以被aop攔截器攔截 var methodFactory = {}; /** * 事件工廠,配置格式{method:{eventType:value,reg:value}} * method : 在grid初始化參數能夠觸發的方法,eventType:jQuery支持的時間類型,reg觸發元素尋址表達式。 * 若是須要發佈新的觸發事件函數,只須要再eventFactory裏配置 */ var eventFactory = { onClickRow : { eventType : 'click', reg : 'tbody>tr' }, onDoubleClickRow : { eventType : 'dblclick', reg : 'tbody>tr' }, onClickCell : { eventType : 'click', reg : 'tbody>tr>td' } }; /** * @target 用來渲染grid的id * 事件匹配算法 * 循環eventFactory裏面配置了的方法 和grid初始化參數裏面的方法碰撞,若是相撞的話,則入住match 而後返回。 */ var matchEvent = function (target) { var opts = target.data("datagrid"); var match = []; for (key in eventFactory) { if (opts[key]){ match.push(key); }; }; return match; }; /** *對返回數據進行格式化處理,爲jQuery觸發事件方法服務 * */ var callBackDataFilter = function (target, container, event) { var opts = container.data("datagrid"); if (event == "onClickRow" || event == "onDoubleClickRow") { return opts.data.items[target.attr("grid-row-index")]; }; if (event == "onClickCell") { var retData = opts.data.items[target.parent().attr("grid-row-index")]; retData.mapping = opts.column[target.context.cellIndex].mapping; return retData; } return null; }; /** *jQuery事件綁定核心算法 */ var bindEvent = function (target) { var match = matchEvent(target); var opts = target.data("datagrid"); $(match).each(function () { var _this = this; var event = eventFactory[this]; var callback = opts[this]; var eventType = event['eventType']; target.find(event['reg']).unbind(eventType).bind(eventType, function () { var container = target; var _target = $(this); var retBack = callBackDataFilter(_target, container, _this); callback(retBack); }); }); }; //grid初始化默認參數 defaut = { column : [], url : null, data : null, pagination : true, pageSizeList : null }; //數據加載方法 var loadData = function (url, callback) { $.ajax({ url : url, // data: objThis.params, dataType : 'json', error : function (XMLHttpRequest, textStatus, errorThrown) { alert("請求數據失敗,緣由爲:" + textStatus); }, success : function (json) { if (json) { if (typeof(callback) === "function") { callback(json); }; }; } }); }; //建立表頭 methodFactory.createHeader = function (target) { target.append("<table class='jGrid'><thead><tr></tr></thead><tbody></tbody></table>"); var headerTd = []; var opt = target.data("datagrid"); $(opt.column).each(function () { headerTd.push("<th>" + this.name + "</th>"); }); target.find("table>thead>tr:eq(0)").append(headerTd.join("")); }; //建立表格內容 var createBody = function (target) { var bodyTr = []; var opts = target.data("datagrid"); $(opts.data.items).each(function (index) { //[{},{}] 格式 var _this = this; var bodyTd = []; $(opts.column).each(function () { bodyTd.push("<td>" + (_this[this.mapping] || "") + "</td>"); }) bodyTr.push("<tr grid-row-index=" + index + ">" + bodyTd.join("") + "</td>"); }); target.find("table>tbody").append(bodyTr); }; //建立分頁條 methodFactory.createPagination = function (target) { var opts = target.data("datagrid"); if (opts.pagination) { var paginationArr = [ createPageSizeList(opts), "<td><a class='pgBtn btn_pre'></a></td>", "<td><a class='pgBtn btn_next'></a></td>" ]; var pgnHtml = "<div class='pagination_content'><table><tr>" + paginationArr.join("") + "</tr></table></div>"; target.append(pgnHtml); }; }; //建立頁碼選項 var createPageSizeList = function (opts) { return "<td><select>" + createSelectOptions(opts) + "</select><td>"; }; var createSelectOptions = function (opts) { var selectOptData = opts.pageSizeList; var selectOptHtml = ""; if (selectOptData) { $(selectOptData).each(function () { selectOptHtml += "<option>" + this + "</option>"; }); }; return selectOptHtml; }; // grid 渲染入口 var render = function (target) { methodFactory.createHeader(target); var data = target.data("datagrid").data; if (data) { createBody(target); } else { loadData(options.url, createBody); }; methodFactory.createPagination(target); }; //jQuery插件 $.fn.datagrid = function (options) { options = $.extend({}, defaut, options); this.data("datagrid", options); aopEngine(this); render(this); bindEvent(this); methodFactory.testCallBack(); } //測試 methodFactory.testCallBack = function (callBack){ if (typeof(callBack) === 'function') { callBack(); } }; })(jQuery)
粗糙的csscss
html,body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,p,blockquote,th,td { padding: 0; } .jGrid{ background-color:#e6EEEE; border: 1px solid #63A0BF; font-size: 8px; padding: 4px; font-family:arial;border:1px solid #63A0BF; border-collapse:collapse; margin:1px 0pt 0px; font-size: 8pt; width: 100%; text-align: left;} .jGrid thead tr th { background-color:#e6EEEE; border: 1px solid #63A0BF; font-size: 8px; padding: 4px; } .jGrid td { font-size:12px;border: 1px solid #ccc;height:22px;} .pagination_content{font-size:12px; padding:0px; color:#3b6498; border:1px solid #9bbde8; height:28px; margin:0px 0px; background: #e6EEEE; } .pgBtn { float:left; display:block; width:20px; height:18px; cursor:hand; margin:1px; } .btn_pre{background:url(img/prev.gif) no-repeat center center;} .btn_next{background:url(img/next.gif) no-repeat center center;}
demo示例html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>grid Demo</title> <script type="text/javascript" src="jquery-1.8.3.js"></script> <script type="text/javascript" src="grid.js"></script> <link rel="stylesheet" href="grid.css" /> <script type="text/javascript"> $(function(){ var jsonData = { IsSuccess: true, Message: '無錯誤', totalCount: 5, items: [ { name: '小張', sex: '1', age: 20, addr: '北京' }, { name: '小李', sex: '2', age: 15, addr: '北京' }, { name: '小成', sex: '1', age: 44, addr: '北京' }, { name: '小王', sex: '1', age: 21, addr: '北京6'}, { name: '小郭', sex: '2', age: 33, addr: '北京' }, { name: '土興', sex: '2', age: 33, addr: '廣州1'}, { name: '土興', sex: '2', age: 33, addr: '廣州1'}, { name: '測試', sex: '2', age: 33, addr: '廣州2'} ] }; $("#divDemoBox").datagrid({ column: [ { name: '姓名', mapping: 'name'}, { name: '年齡', mapping: 'age'}, { name: '性別', mapping: 'sex'}, { name: '地址', mapping: 'addr'} ], pageSizeList:[10,20,30,49], data:jsonData, onClickRow:function(){}, onDoubleClickRow:function(ll){}, onClickCell:function(data){alert(JSON.stringify(data));}, onBeforeCreatePagination:function(){}, onAfterCreatePagination:function(){}, onBeforeCreateHeader:function(){}, onAfterCreateHeader:function(){}, callbacktest:function(){} }); console.info($("div")) }) </script> </head> <body> <div id="divDemoBox" style="width:500px;float:left;"></div> </body> </html>
收工java