且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

【jquery模仿net控件】初步GridView模型实现,及其简单应用

更新时间:2022-09-02 15:30:59

前期工作

之前主要模拟了一次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控件的生命周期,并且实现委托那种高级东西,只不过自己学的太浅了,有点不够力啊。

详细请看下个版本吧,此版本欢迎拍砖

 

本文转自叶小钗博客园博客,原文链接:http://www.cnblogs.com/yexiaochai/archive/2012/05/17/2507029.html,如需转载请自行联系原作者