先上插件代码
(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)
粗糙的css
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示例
<!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>
收工