Easyui.datagrid扩展——Ext.grid rowediting风格

使用过Ext的人都知道,在Ext.grid组件中有个Ext.grid.plugin.RowEditing插件,它会在行编辑状态下,在行的下方出现一组按钮,方便你确定和取消当前行的编辑内容。

Easyui.datagrid扩展——Ext.grid rowediting风格_第1张图片


有朋友反映看的有点乱,我也懒的再排版了,嫌乱的可以从后向前反着看。最后面给出了完整扩展。


首先我们要达到如下目的:
1、保留easyui.datagrid原有编辑风格
2、增加一个类似Ext.grid的Rowediting编辑风格
3、可以通过一个属性来控制Rowediting编辑风格
4、因为扩展而被使用过的事件,要能保证在datagrid在初始化时设置后,还能正常触发。


下面我们来看看如何在Easyui中实现这个效果。
首先,我们给Easyui.datagrid扩展一个方法叫_registRowEditingHandler,使它能为我们构建Rowediting编辑风格。这个方法名前加了一个“-”表示当作一个私有方法使用,不打算将它公布给调用者使用。当然你也可以通过其他方法来实现,完全按个人习惯。

function _registRowEditingHandler(jq){

    var getEditorButtonsPanelId = function(target){
        return $(target).attr('id')+'_editor_buttons_panel';
    }

    var buildEditorButtonsPanel = function(target){
        var panelId = getEditorButtonsPanelId(target);
        if($('#'+panelId).length > 0) return;

        var panel = $(target).datagrid('getPanel');
        var datagrid_body = $('>div.datagrid-view>div.datagrid-view2>div.datagrid-body', panel);
        datagrid_body.css('position', 'relative');

        var edtBtnPanel = $('<div>', {id: panelId})
            .addClass('dialog-button')
            .appendTo(datagrid_body)
            .css({
                'position': 'absolute',
                'display': 'block',
                'border-bottom': '1px solid #ddd',
                'border-left': '1px solid #ddd',
                'border-right': '1px solid #ddd',
                'left': parseInt(panel.width()/2)-120,
                'z-index': 2013,
                'display': 'none',
                'padding': '4px 5px'
            });

        $('<a href="javascript:void(0)">确定</a>')
            .css('margin-left','0px')
            .linkbutton({iconCls: 'icon-ok'})
            .click(function(){
                var editIndex = $(target).datagrid('getRowIndex', $(target).datagrid('getEditingRow'));
                $(target).datagrid('endEdit', editIndex);
            })
            .appendTo(edtBtnPanel);
        $('<a href="javascript:void(0)">取消</a>')
            .css('margin-left', '6px')
            .linkbutton({iconCls: 'icon-cancel'})
            .click(function(){
                var editIndex = $(target).datagrid('getRowIndex', $(target).datagrid('getEditingRow'));
                $(target).datagrid('cancelEdit', editIndex);
            })
            .appendTo(edtBtnPanel);

    }

    var showEditorButtonsPanel = function(target, index){
        var opts = $.data(target, "datagrid").options;
        var tr = opts.finder.getTr(target, index);
        var position = tr.position();

        var fixPosition = function(){
            var offset = tr.height() * 2 + 10;
            var t = position.top + datagrid_body.scrollTop();

            if((position.top+offset) > datagrid_body.height()){
                return {top: t - offset};
            }else{
                return {top: t};
            }
        }

        var edtBtnPanelId = '#'+getEditorButtonsPanelId(target);
        var panel = $(target).datagrid('getPanel');
        var datagrid_body = $('>div.datagrid-view>div.datagrid-view2>div.datagrid-body', panel);

        $(edtBtnPanelId).css({
            top: fixPosition().top
        }).show();
    }

    var hideEditorButtonsPanel = function(target){
        var edtBtnPanelId = '#'+getEditorButtonsPanelId(target);
        $(edtBtnPanelId).hide();
    }


    jq.each(function(){
        var target = this;
        var opts = $.data(target, "datagrid").options;
        
        var onLoadSuccessCallBack = opts.onLoadSuccess;
        var onBeforeEditCallBack = opts.onBeforeEdit;
        var onAfterEditCallBack = opts.onAfterEdit;
        var onCancelEditCallBack = opts.onCancelEdit;

        $(this).datagrid({
            onLoadSuccess: function(data){
                onLoadSuccessCallBack.call(this, data);
                buildEditorButtonsPanel(this);
            },
            onBeforeEdit: function(index, data){
                showEditorButtonsPanel(target, index);
                onBeforeEditCallBack.call(this, index, data);
            },
            onAfterEdit: function(index, data){
                hideEditorButtonsPanel(target);
                onAfterEditCallBack.call(this, index, data);
            },
            onCancelEdit: function(index, data){
                hideEditorButtonsPanel(target);
                onCancelEditCallBack.call(this, index, data);
            }
        });

    });
}

方法中用到了另一个easyui.datagrid的扩展方法getEditingRow,作用就是返回当前正被编辑的row。注意这个row不是dom元素,而是用来填充datagrid的数据对象中rows中的一个{}行对象。不理解的自己看Easyui.datagrid的API,不再多做解释。

$.extend($.fn.datagrid.methods, {
    ...... 此处省略其他扩展方法

    getEditingRow: function(jq){
        var datagrid = $.data(jq[0], "datagrid");
        var opts = datagrid.options;
        var data = datagrid.data;
        var editingRow = [];
        opts.finder.getTr(jq[0], "", "allbody").each(function(){
            if($(this).hasClass('datagrid-row-editing')){
                var index = parseInt($(this).attr('datagrid-row-index'));
                editingRow.push(data.rows[index]);
            }
        });

        return editingRow.length>0?editingRow[0]:null;
    }  
});

好了,到目前为止,我们需要的方法都已经构建完成。


接下来,我准备通过一个叫rowediting的属性,来控制这个编辑风格。为了防止与Easyui.datagrid以后扩展的属性冲突,我将其方式到另一个自定义属性customAttr中。以后所有自己扩展的属性都放置到这个属性中。

$.fn.datagrid.defaults.customAttr={
    rowediting: true
}

现在,方法有了,控制属性也有了,那如何将二者关联起来?有人说通过onLoadSuccess事件,有的说再扩展一个方法等等,形式很多。我这里不准备再使用onLoadSuccess事件,因为在构建RowEditing风格的方法中已经使用过这个事件,再用代码就写的太麻烦了。所以这里采用再扩展一个方法的方式,我们将这个方法命名为followCustomHandle。目的是为了处理我所有的自定义属性,目前先用来处理$.fn.datagrid.defaults.customAttr.rowediting属性的解析。

$.extend($.fn.datagrid.methods, {
    followCustomHandle: function(jq){
        return jq.each(function(){
            var opts = $.extend(true, {}, $.fn.datagrid.defaults, $.data(this, 'datagrid').options);
            if(opts.customAttr.rowediting){           
                _registRowEditingHandler(jq);
            } 
        }); 
    }, 
    ......以下省略其它扩展方法 
});

好了,都关联起来了,使用者如何调用?

$('#datagrid').datagrid({
    columns:[[
        {field: 'username', title: 'Name', width: 150, editor: 'text'},
        {field: 'sex', title: 'Sex', width: 50, editor: 'text'},
        {field: 'age', title: 'Age', width: 80, editor: 'numberspinner'},
        {field: 'brithday', title: 'Birthday', width: 100, editor: 'my97'},
        {field: 'registdate', title: 'Regist Date', width: 150, editor: 'datetimebox'},
        {field: 'arrivaltime', title: 'Arrival Time (AT)', width: 110, editor: 'timespinner'}
    ]],
    title: 'Row Editing DataGrid',
    singleSelect: true,
    rownumbers: true,
    height: 250,
    width: 700,
    url: '../datagrid/datagrid_data2.json',
    //customAttr:{
    //    rowediting: false
    //},
    onClickRow: function(index){
        var editingRow = $('#datagrid').datagrid('getEditingRow');
        var editingRowIndex = $('#datagrid').datagrid('getRowIndex', editingRow);
        if(!editingRow){
            $('#datagrid').datagrid('selectRow', index)
                    .datagrid('beginEdit', index);
        }else{
            $('#datagrid').datagrid('selectRow', editingRowIndex);
        }
    }
})
.datagrid('followCustomHandle');

你可以将上段JavaScript代码放入到这里调用。

<script type="text/javascript">
    $(function(){
         //上段的JavaScript代码扔到这里。为啥?jquery基础,不解释。
    })
</script>

效果:


图2

Easyui.datagrid扩展——Ext.grid rowediting风格_第2张图片

图3


下面给出完整扩展

jquery.easyui.datagrid.extend.js

(function($){
    function _registRowEditingHandler(jq){

        var getEditorButtonsPanelId = function(target){
            return $(target).attr('id')+'_editor_buttons_panel';
        }

        var buildEditorButtonsPanel = function(target){
            var panelId = getEditorButtonsPanelId(target);
            if($('#'+panelId).length > 0) return;

            var panel = $(target).datagrid('getPanel');
            var datagrid_body = $('>div.datagrid-view>div.datagrid-view2>div.datagrid-body', panel);
            datagrid_body.css('position', 'relative');

            var edtBtnPanel = $('<div>', {id: panelId})
                .addClass('dialog-button')
                .appendTo(datagrid_body)
                .css({
                    'position': 'absolute',
                    'display': 'block',
                    'border-bottom': '1px solid #ddd',
                    'border-left': '1px solid #ddd',
                    'border-right': '1px solid #ddd',
                    'left': parseInt(panel.width()/2)-120,
                    'z-index': 2013,
                    'display': 'none',
                    'padding': '4px 5px'
                });

            $('<a href="javascript:void(0)">确定</a>')
                .css('margin-left','0px')
                .linkbutton({iconCls: 'icon-ok'})
                .click(function(){
                    var editIndex = $(target).datagrid('getRowIndex', $(target).datagrid('getEditingRow'));
                    $(target).datagrid('endEdit', editIndex);
                })
                .appendTo(edtBtnPanel);
            $('<a href="javascript:void(0)">取消</a>')
                .css('margin-left', '6px')
                .linkbutton({iconCls: 'icon-cancel'})
                .click(function(){
                    var editIndex = $(target).datagrid('getRowIndex', $(target).datagrid('getEditingRow'));
                    $(target).datagrid('cancelEdit', editIndex);
                })
                .appendTo(edtBtnPanel);

        }

        var showEditorButtonsPanel = function(target, index){
            var opts = $.data(target, "datagrid").options;
            var tr = opts.finder.getTr(target, index);
            var position = tr.position();

            var fixPosition = function(){
                var offset = tr.height() * 2 + 10;
                var t = position.top + datagrid_body.scrollTop();

                if((position.top+offset) > datagrid_body.height()){
                    return {top: t - offset};
                }else{
                    return {top: t};
                }
            }

            var edtBtnPanelId = '#'+getEditorButtonsPanelId(target);
            var panel = $(target).datagrid('getPanel');
            var datagrid_body = $('>div.datagrid-view>div.datagrid-view2>div.datagrid-body', panel);

            $(edtBtnPanelId).css({
                top: fixPosition().top
            }).show();
        }

        var hideEditorButtonsPanel = function(target){
            var edtBtnPanelId = '#'+getEditorButtonsPanelId(target);
            $(edtBtnPanelId).hide();
        }


        jq.each(function(){
            var target = this;
            var opts = $.data(target, "datagrid").options;
            
            var onLoadSuccessCallBack = opts.onLoadSuccess;
            var onBeforeEditCallBack = opts.onBeforeEdit;
            var onAfterEditCallBack = opts.onAfterEdit;
            var onCancelEditCallBack = opts.onCancelEdit;

            $(this).datagrid({
                onLoadSuccess: function(data){
                    onLoadSuccessCallBack.call(this, data);
                    buildEditorButtonsPanel(this);
                },
                onBeforeEdit: function(index, data){
                    showEditorButtonsPanel(target, index);
                    onBeforeEditCallBack.call(this, index, data);
                },
                onAfterEdit: function(index, data){
                    hideEditorButtonsPanel(target);
                    onAfterEditCallBack.call(this, index, data);
                },
                onCancelEdit: function(index, data){
                    hideEditorButtonsPanel(target);
                    onCancelEditCallBack.call(this, data);
                }
            });

        });
    }

    $.fn.datagrid.defaults.customAttr={
        rowediting: true
    }

    $.extend($.fn.datagrid.methods, {
        followCustomHandle: function(jq){
            return jq.each(function(){
                var opts = $.extend(true, {}, $.fn.datagrid.defaults, $.data(this, 'datagrid').options);
                if(opts.customAttr.rowediting){
                    _registRowEditingHandler(jq);
                }
            });
        },
        getEditingRow: function(jq){
            var datagrid = $.data(jq[0], "datagrid");
            var opts = datagrid.options;
            var data = datagrid.data;
            var editingRow = [];
            opts.finder.getTr(jq[0], "", "allbody").each(function(){
                if($(this).hasClass('datagrid-row-editing')){
                    var index = parseInt($(this).attr('datagrid-row-index'));
                    editingRow.push(data.rows[index]);
                }
            });

            return editingRow.length>0?editingRow[0]:null;
        }  
    });

})(jQuery)

编写仓促,有Bug的地方自己修改修改。因为简单,应该很容易看懂,所以没写多少注释。



升级后的代码,请访问我的jquery.easyui.1.3.3扩展库






你可能感兴趣的:(JavaScript,easyui,扩展)