【jquery模仿net控件】初步GridView模型实现,及其简单应用
最近日子不好过,主要原因是要毕业了,学校那边的毕业论文让人很头痛,就跟写八股文似的,个人非常头疼并且厌恨这种
对我无意义的东西,哎!!!体制啊,既然无法改变,何不将之做好呢!!!对,于是我还是不想写论文,拖着吧,到哪天确实
拖不下去了再说;加之公司项目也非常紧,又要写论文,虽说没写,心里就是一个不舒服啊!!!所以平时抽了点时间模拟了下
gridview,个人是菜鸟自不必多说,但是这几个月来,模拟写着写着感觉学到了不少东西哟!!!
算了....扯远了,进入正文。
前期工作
之前主要模拟了一次datalist,基本上以它为基础将igoogle功能完全实现,并且应用到项目中去了,控件不好,但也不是完全没有意义,
过程中需要类似gridview的功能,索性也就写了一下,思路与datalist差距不大。
因为马上要写论文了,而且是不完全版本这里就不画图什么的了,以后发完整版本再说吧:
效果图
简单说明
该简单应用也是我第一次做测试,有一下几个事件:
① 鼠标滑动时变色事件
② 点击大类选取小类事件
③ 点击获取时候全部获取事件
④ 当然,不能忘了行绑定事件,初期只是绑定了大类,小类根据大类id作出的加载
核心代码
<!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></title> <script src="../js/jquery-1.7.1.min.js" type="text/javascript"></script> <script src="http://www.cnblogs.com/../scripts/jquery-1.7.1.js" type="text/javascript"></script> <script src="../js/GridViewBase.js" type="text/javascript"></script> <script src="../js/GridColum.js" type="text/javascript"></script> <script src="../js/GridRow.js" type="text/javascript"></script> <script src="../js/GridView.js" type="text/javascript"></script> <script src="http://www.cnblogs.com/../scripts/jquery.cookie.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready(function () { var url = '../Ajax.aspx?sql=select * from bigType '; $.getJSON(url, function (data) { var g = new GridView(); $("#www").click(function () { var rows = g.rows; var str = ""; $.each(rows, function (i, row) { var checks = row.getEl("input:checkbox"); checks.each(function (ii, jj) { if ($(this).attr("checked")) { str += $(this).val() + " , " } }); }); alert(str); }); g.style.width = "500px"; g.colModel = [{ 'th': { 'title': '大类' }, 'td': { 'template': '{%title%}<input value="{%id%}" type="checkbox" class="bigId" />', 'attribute': {}, 'style': {} } }, { 'th': { 'title': '小类' }, 'td': { 'template': '<div class="type"></div>', 'attribute': {}, 'style': {} } } ]; g.trEvent = [ { eventType: 'ready', func: function (param, e) { var scope = this; var tr = scope.el; var back = tr.css('background-color'); tr.unbind('mousemove'); tr.bind('mousemove', function () { tr.css('background-color', '#efefef'); }); tr.unbind('mouseout'); tr.bind('mouseout', function () { tr.css('background-color', back); }); } }, { eventType: 'ready', func: function (param, e) { var scope = this; var type = scope.getEl(".type"); var id = param.id; var _url = "../Ajax.aspx?sql=select * from smallType where bigTypeId='" + id + "' " $.getJSON(_url, function (data) { $.each(data, function (i, item) { var html = ' ' + item.title + '<input value="' + item.id + '" type="checkbox" class="sId" disabled="disabled" />'; type.append(html); }); var bigId = scope.getEl(".bigId"); bigId.unbind("change"); bigId.bind("change", function () { var smallTyle = scope.getEl(".sId"); if (bigId.attr('checked') == 'checked') { smallTyle.attr("checked", "checked"); smallTyle.removeAttr('disabled'); } else { smallTyle.removeAttr('checked'); smallTyle.attr('disabled', 'disabled'); } }); }); } } ]; g.dataSource = data; g.render(); }); }); </script> </head> <body> <input type="button" value="获取" id="www" /> </body> </html>
/// <reference path='jquery-1.7.1.min.js' /> /// <reference path='GridViewBase.js' /> /// <reference path='GridColum.js' /> /// <reference path='GridRow.js' /> /* 控件生成流程: 1 先初始化表格每列的【列头】以及【body信息】,最好可指定列id,用于后期检索 2 赋予控件二维数据(但控件字段最好可支持多维数据获取) 3 初始化外围table,并赋予其属性样式,最外层结束 4 根据二维数据依次初始化每行数据,【其实可在此处初始化表头,因为若是没有数据表头将不初始化】 5 每行获得其数据源,先形成tr,然后将数据源直接赋予单元行进行初始化 6 单元化格式化单元模板,生成html标签 */ var GridView = function (id) { var scope = this; this.style = {}; this.attribute = { id: id && id.length > 0 ? id : new Date().getTime().toString(), className: 'wl' }; this.id = this.attribute.id; this.thId = this.id + '_header'; this.dataSource = []; this.header = null; this.rows = []; this.el = null; this.parentData = null; this.thEvent = [ { func: function (rows, e) { var scope = this; var select = scope.getThEl('.th_select'); select.unbind('click'); select.bind('click', function (e) { var th_s = select.attr('checked'); $.each(rows, function (i, row) { var td_select = row.getEl('.td_select'); // var td_s = td_select.attr('checked'); if (th_s && th_s == 'checked') { td_select.attr('checked', 'checked'); } else { td_select.removeAttr('checked'); } }); }); } } ]; this.trEvent = [ { eventType: 'ready', func: function (param, e) { var scope = this; var tr = scope.el; var back = tr.css('background-color'); tr.unbind('mousemove'); tr.bind('mousemove', function () { tr.css('background-color', '#efefef'); }); tr.unbind('mouseout'); tr.bind('mouseout', function () { tr.css('background-color', back); }); } }, { eventType: 'ready', func: function (param, e) { var scope = this; var edit = scope.getEl('.td_edit'); edit.unbind('click'); edit.bind('click', function (ee) { var div = scope.getEl('div'); div.hide(); }); } } ]; this.tdEvent = [ { // eventType: 'click', // func: function (param, e) { // var scope = this; // var td = scope.el; // var input = $('<input style="width:100%;height:100%;" value="' + td.text() + '" />'); // td.html(input); // } } ]; this.preInit = new EventHandler(); this.initComplete = new EventHandler(); this.preLoad = new EventHandler(); this.loadComplete = new EventHandler(); this.parentEl = $('body'); this.colModel = [{ 'th': { 'title': '<input value="" type="checkbox" class="th_select" />', 'attribute': {}, 'style': {} }, 'td': { 'type': '', 'value': '', 'template': '<input value="{%title%}" type="checkbox"class="td_select" />', 'attribute': {}, 'style': {} } }, { 'th': { 'title': '111', 'attribute': {}, 'style': {} }, 'td': { 'type': '', 'value': '', 'template': '<input style="display:none;" value="{%title%}" /><div class="td_title">{%title%}</div>', 'attribute': { className: 'wlR' }, 'style': { 'color': 'Blue'} } }, { 'th': { 'title': '222', 'attribute': {}, 'style': {} }, 'td': { 'type': '', 'value': '', 'template': '<textarea style="display:none;" >{%summary%}</textarea><div class="td_summary">{%summary%}</div>', 'attribute': {}, 'style': {} } }, { 'th': { 'title': '编辑', 'attribute': {}, 'style': {} }, 'td': { 'type': '', 'value': '', 'template': '<input type="button" value="编辑" class="td_edit" />', 'attribute': {}, 'style': {} } } ]; }; GridView.prototype.render = function () { var scope = this; scope.onInit(); scope.onLoad(); scope.eventBind(); }; GridView.prototype.onInit = function () { var scope = this; scope.preInit.invoke(); scope.initHtml(); scope.initAttr(); scope.initStyle(); scope.initComplete.invoke(); }; GridView.prototype.initHtml = function () { var scope = this; var el = $('<table></table>'); scope.el = el; var parentEl = scope.parentEl; parentEl.append(el); scope.initHeader(); }; GridView.prototype.initHeader = function () { var scope = this; var header = $('<tr></tr>'); header.attr('id', scope.thId); var model = scope.colModel; $.each(model, function (i, col) { var th = col['th']; if (th) { var val = th['title']; var td = $('<th>' + val + '</th>'); header.append(td); } }); scope.header = header; var table = scope.el; table.append(header); }; GridView.prototype.initAttr = function () { utils.initAttr(this); }; GridView.prototype.initStyle = function () { utils.initStyle(this); }; GridView.prototype.onLoad = function () { var scope = this; scope.preLoad.invoke(); scope.loadHtml(); scope.loadRows(); scope.loadComplete.invoke(); }; GridView.prototype.loadHtml = function () { utils.loadhtml(this); }; GridView.prototype.loadRows = function () { var scope = this; var dataSource = scope.dataSource; $.each(dataSource, function (index, item) { var gridRow = new GridRow(); gridRow.parentObj = scope; gridRow.dataSource = item; gridRow.rowIndex = index; gridRow.event = scope.trEvent; gridRow.tdEvent = scope.tdEvent; gridRow.colModel = scope.colModel; gridRow.render(); scope.rows.push(gridRow); }); }; GridView.prototype.eventBind = function () { var scope = this; scope.headerEventBind(); }; GridView.prototype.headerEventBind = function () { var scope = this; var el = scope.el; var thEvent = scope.thEvent; $.each(thEvent, function (i, item) { var func = item.func; el.ready(function (e) { func.call(scope, scope.rows, e); }); }); }; GridView.prototype.getThEl = function (elementKey) { var scope = this; var thId = scope.thId; var id = "#" + thId + " " + elementKey; var element = $(id); return element; };
// <reference path="jquery-1.7.1.min.js" /> /// <reference path="GridViewBase.js" /> /// <reference path="GridColum.js" /> var GridRow = function () { var scope = this; this.parentObj = null; this.el = null; this.style = {}; this.attribute = {}; this.dataSource = []; this.columns = []; this.rowIndex; this.colModel = null; this.id = ""; this.event = []; this.preInit = new EventHandler(); this.initComplete = new EventHandler(); this.preLoad = new EventHandler(); this.loadComplete = new EventHandler(); }; GridRow.prototype.render = function () { var scope = this; scope.onInit(); scope.onLoad(); scope.eventBind(); }; GridRow.prototype.onInit = function () { var scope = this; scope.parentEl = scope.parentObj.el; scope.parentId = scope.parentObj.id; scope.preInit.invoke(); scope.initHtml(); scope.initAttr(); scope.initStyle(); scope.initComplete.invoke(); }; GridRow.prototype.initHtml = function () { var scope = this; var el = $('<tr></tr>'); scope.el = el; var parentEl = scope.parentEl; parentEl.append(el); }; GridRow.prototype.initAttr = function () { var scope = this; utils.initAttr(this); var el = scope.el; var parentId = scope.parentId; var rowIndex = scope.rowIndex; var id = parentId + "_row_" + rowIndex; scope.id = id; scope.attribute.id = id; el.attr("id", id); }; GridRow.prototype.initStyle = function () { utils.initStyle(this); }; GridRow.prototype.onLoad = function () { var scope = this; scope.preLoad.invoke(); scope.loadHtml(); scope.loadCols(); scope.loadComplete.invoke(); }; GridRow.prototype.loadHtml = function () { utils.loadhtml(this); }; GridRow.prototype.loadCols = function () { var scope = this; var dataSource = scope.dataSource; var colModel = scope.colModel; utils.formatColTemplate(this); $.each(colModel, function (i, model) { var td = model.td; var gridColumn = new GridColumn(); gridColumn.parentObj = scope; gridColumn.dataSource = dataSource; gridColumn.colIndex = i; gridColumn.model = model; gridColumn.attribute = td.attribute; gridColumn.style = td.style; gridColumn.event = scope.tdEvent; gridColumn.render(); scope.columns.push(gridColumn); }); }; GridRow.prototype.eventBind = function () { utils.eventBind(this, this.dataSource); }; GridRow.prototype.getEl = function (elementKey) { var scope = this; var id = scope.id; var id = "#" + id + " " + elementKey; var element = $(id); return element; };
/// <reference path="jquery-1.7.1.min.js" /> /// <reference path="GridViewBase.js" /> var GridColumn = function (cfg) { var scope = this; this.parentObj = null; this.el = null; this.style = {}; this.attribute = {}; this.type = 'field'; //暂时提供filed数据字段、template模板两种 this.model = {}; this.colIndex; this.dataSource = null; this.event = []; this.preInit = new EventHandler(); this.initComplete = new EventHandler(); this.preLoad = new EventHandler(); this.loadComplete = new EventHandler(); }; GridColumn.prototype.render = function () { var scope = this; scope.onInit(); scope.onLoad(); scope.eventBind(); }; GridColumn.prototype.onInit = function () { var scope = this; scope.parentEl = scope.parentObj.el; scope.parentId = scope.parentObj.attribute.id; scope.preInit.invoke(); scope.initHtml(); scope.initAttr(); scope.initStyle(); scope.initComplete.invoke(); }; GridColumn.prototype.initBody = function (td, dataSource) { var scope = this; var parentEl = scope.parentEl; var templateObj = td['templateObj']; var tempHtm = ""; $.each(templateObj, function (i, item) { if (item.field) { tempHtm = tempHtm + item.html + dataSource[item.field]; } else { tempHtm = tempHtm + item.html; } }); var newHtm = tempHtm; var reg = /\[%(.*?)%\]/; var para = reg.exec(newHtm); while (para && para.length > 0) { var len = para.index; var comStr = para[0].substr(2, para[0].length - 4); var s1 = newHtm.substr(0, len); var s2 = newHtm.substr(len + para[0].length); newHtm = s1 + eval(comStr) + s2; para = reg.exec(newHtm); } tempHtm = newHtm; var td = $('<td>' + tempHtm + '</td>'); scope.el = td; parentEl.append(td); }; GridColumn.prototype.initHtml = function () { var scope = this; var dataSource = scope.dataSource; var col = scope.model; var td = col['td']; scope.initBody(td, dataSource); }; GridColumn.prototype.initAttr = function () { var scope = this; var el = scope.el; var parentId = scope.parentId; var id = parentId + "_"+scope.colIndex; scope.id = id; scope.attribute.id = id; utils.initAttr(this); el.attr("id", id); }; GridColumn.prototype.initStyle = function () { utils.initStyle(this); }; GridColumn.prototype.onLoad = function () { var scope = this; scope.preLoad.invoke(); scope.loadHtml(); scope.loadComplete.invoke(); }; GridColumn.prototype.loadHtml = function () { }; GridColumn.prototype.eventBind = function () { utils.eventBind(this, this.dataSource); };
/// <reference path="jquery-1.7.1.min.js" /> var Delegate = function (func, sender, param) { this.target = sender; this.method = func; this.invoke = function () { if (func && typeof (func) == "function") { func.call(sender, param); }; }; }; var EventHandler = function () { this.delegate = []; this.add = function (func, sender, param) { var delegate = new Delegate(func, sender, param); this.delegate.push(delegate); }; this.remove = function (func) { for (var i = 0, len = this.delegate.length; i < len; i++) { if (this.delegate[i][func] == func) { this.delegate[func] = null; } } }; this.invoke = function () { for (var i = 0, len = this.delegate.length; i < len; i++) { this.delegate[i].invoke(); } }; }; var GridViewUtils = function () { }; GridViewUtils.prototype.initStyle = function (sender) { var scope = sender; var el = scope.el; $.each(scope.style, function (key, value) { if (typeof (key) == 'string' && key.length > 0) { el.css(key, value); } }); }; GridViewUtils.prototype.initAttr = function (sender) { var scope = sender; var el = scope.el; $.each(scope.attribute, function (key, value) { if (typeof (key) == 'string' && key.length > 0) { if (key == 'className') key = 'class'; el.attr(key, value); } }); }; GridViewUtils.prototype.eventBind = function (sender,param) { var scope = sender; var el = scope.el; $.each(scope.event, function (i, item) { var func = item.func; var eventType = item.eventType; if (eventType == "ready") { el.ready(function (e) { func.call(scope, param, e); }); } else { el.unbind(eventType); el.bind(eventType, function (e) { func.call(scope, param, e); }); } }); }; GridViewUtils.prototype.loadhtml = function (sender) { // var scope = sender; // var parentEl = scope.parentEl; // var el = scope.el; // parentEl.append(el); }; GridViewUtils.prototype.formatColTemplate = function (sender) { var scope = sender; var model = scope.colModel; var reg = /\{%[\w]*\%}/; $.each(model, function (i, v) { model[i]['td']['templateObj'] = []; var template = v['td']['template']; var para = reg.exec(template); var tempHtml = template; while (para && para.length > 0) { var len = para.index; var temp = {}; temp.html = tempHtml.substr(0, len); temp.field = para[0].substr(2, para[0].length - 4); model[i]['td']['templateObj'].push(temp); tempHtml = tempHtml.substr(len + para[0].length); para = reg.exec(tempHtml); } var end = {}; end.html = tempHtml; model[i]['td']['templateObj'].push(end); var sss = ""; }); }; var utils = new GridViewUtils();
后续
做的过程中,想模拟.net控件的生命周期,并且实现委托那种高级东西,只不过自己学的太浅了,有点不够力啊。
详细请看下个版本吧,此版本欢迎拍砖