项目中遇到的问题汇总以及解决方案(easyUI+jsp篇)

本文档详细分析了easyUI combobox组件中回车选中数据时出现的问题,即当鼠标悬停在某一行时,回车确认会选中鼠标所在行的值。为了解决这个问题,文章提供了一个扩展easyUI combobox的方法,重写了相关事件处理,确保回车仅根据当前选中值进行确认。此外,还提醒开发者不要在Array上使用for-in循环,因为这可能导致不预期的行为,建议使用常规的for循环或Array的迭代方法。
摘要由CSDN通过智能技术生成

一、easyUI

问题:在easyUI的下拉选框combobox组件中,默认上下选择并回车选中数值,但是当鼠标正好在数据框的一行时,用户按回车选中数据,回车确定却选中了鼠标悬停在那的数据。

原因:easyui的组件combobox中默认设置了回车选中事件。

分析:通过easyUI的官网找到combobox组件的文档,找到它combobox有可扩展的方法。

解决方案:

对combobox扩展,并重写相关调用方法,从而上下和回车选中去掉鼠标的影响。
(function(){
    function getRowIndex(target, value){
        var state = $.data(target, 'combobox');
        return $.easyui.indexOfArray(state.data, state.options.valueField, value);
    }

    /**
     * do the query action
     */
    function doQuery(target, q){
        var state = $.data(target, 'combobox');
        var opts = state.options;

        var highlightItem = $();
        var qq = opts.multiple ? q.split(opts.separator) : [q];
        if (opts.mode == 'remote'){
            _setValues(qq);
            //request(target, null, {q:q}, true);
        } else {
            var panel = $(target).combo('panel');
            panel.find('.combobox-item-hover').removeClass('combobox-item-hover');
            panel.find('.combobox-item,.combobox-group').hide();
            var data = state.data;
            var vv = [];
            $.map(qq, function(q){
                q = $.trim(q);
                var value = q;
                var group = undefined;
                highlightItem = $();
                for(var i=0; i<data.length; i++){
                    var row = data[i];
                    if (opts.filter.call(target, q, row)){
                        var v = row[opts.valueField];
                        var s = row[opts.textField];
                        var g = row[opts.groupField];
                        var item = opts.finder.getEl(target, v).show();
                        if (s.toLowerCase() == q.toLowerCase()){
                            value = v;
                            if (opts.reversed){
                                highlightItem = item;
                            } else {
                                select(target, v, true);
                            }
                        }
                        if (opts.groupField && group != g){
                            opts.finder.getGroupEl(target, g).show();
                            group = g;
                        }
                    }
                }
                vv.push(value);
            });
            _setValues(vv);
        }
        function _setValues(vv){
            if (opts.reversed){
                highlightItem.addClass('combobox-item-hover');
            } else {
                setValues(target, opts.multiple ? (q?vv:[]) : vv, true);
            }
        }
    }

    function doEnter(target){
        var t = $(target);
        var opts = t.combobox('options');
        var panel = t.combobox('panel');
        // var item = panel.children('div.combobox-item-hover');
        // if (item.length){
        //     item.removeClass('combobox-item-hover');
        //     var row = opts.finder.getRow(target, item);
        //     var value = row[opts.valueField];
        //     if (opts.multiple){
        //         if (item.hasClass('combobox-item-selected')){
        //             t.combobox('unselect', value);
        //         } else {
        //             t.combobox('select', value);
        //         }
        //     } else {
        //         t.combobox('select', value);
        //     }
        // }
        var vv = [];
        $.map(t.combobox('getValues'), function(v){
            if (getRowIndex(target, v) >= 0){
                vv.push(v);
            }
        });
        t.combobox('setValues', vv);
        if (!opts.multiple){
            t.combobox('hidePanel');
        }
    }

    function nav(target, dir){
        var opts = $.data(target, 'combobox').options;
        var panel = $(target).combobox('panel');
        // var item = panel.children('div.combobox-item-hover');
        // if (!item.length){
        //     item = panel.children('div.combobox-item-selected');
        // }
        var item = panel.children('div.combobox-item-selected');
        //item.removeClass('combobox-item-hover');
        var firstSelector = 'div.combobox-item:visible:not(.combobox-item-disabled):first';
        var lastSelector = 'div.combobox-item:visible:not(.combobox-item-disabled):last';
        if (!item.length){
            item = panel.children(dir=='next' ? firstSelector : lastSelector);
        } else {
            if (dir == 'next'){
                item = item.nextAll(firstSelector);
                if (!item.length){
                    item = panel.children(firstSelector);
                }
            } else {
                item = item.prevAll(firstSelector);
                if (!item.length){
                    item = panel.children(lastSelector);
                }
            }
        }
        if (item.length){
            //item.addClass('combobox-item-hover');
            var row = opts.finder.getRow(target, item);
            if (row){
                $(target).combobox('scrollTo', row[opts.valueField]);
                if (opts.selectOnNavigation){
                    select(target, row[opts.valueField]);
                }
            }
        }
    }

    /**
     * select the specified value
     */
    function select(target, value, remainText){
        var opts = $.data(target, 'combobox').options;
        var values = $(target).combo('getValues');
        if ($.inArray(value+'', values) == -1){
            if (opts.multiple){
                values.push(value);
            } else {
                values = [value];
            }
            setValues(target, values, remainText);
        }
    }

    /**
     * set values
     */
    function setValues(target, values, remainText){
        var opts = $.data(target, 'combobox').options;
        var panel = $(target).combo('panel');

        if (!$.isArray(values)){
            values = values.split(opts.separator);
        }
        if (!opts.multiple){
            values = values.length ? [values[0]] : [''];
        }

        // unselect the old rows
        var oldValues = $(target).combo('getValues');
        if (panel.is(':visible')){
            panel.find('.combobox-item-selected').each(function(){
                var row = opts.finder.getRow(target, $(this));
                if (row){
                    if ($.easyui.indexOfArray(oldValues, row[opts.valueField]) == -1){
                        $(this).removeClass('combobox-item-selected');
                    }
                }
            });
        }
        $.map(oldValues, function(v){
            if ($.easyui.indexOfArray(values, v) == -1){
                var el = opts.finder.getEl(target, v);
                if (el.hasClass('combobox-item-selected')){
                    el.removeClass('combobox-item-selected');
                    opts.onUnselect.call(target, opts.finder.getRow(target, v));
                }
            }
        });

        var theRow = null;
        var vv = [], ss = [];
        for(var i=0; i<values.length; i++){
            var v = values[i];
            var s = v;
            var row = opts.finder.getRow(target, v);
            if (row){
                s = row[opts.textField];
                theRow = row;
                var el = opts.finder.getEl(target, v);
                if (!el.hasClass('combobox-item-selected')){
                    el.addClass('combobox-item-selected');
                    opts.onSelect.call(target, row);
                }
            } else {
                s = findText(v, opts.mappingRows) || v;
            }
            vv.push(v);
            ss.push(s);
        }

        if (!remainText){
            $(target).combo('setText', ss.join(opts.separator));
        }
        if (opts.showItemIcon){
            var tb = $(target).combobox('textbox');
            tb.removeClass('textbox-bgicon ' + opts.textboxIconCls);
            if (theRow && theRow.iconCls){
                tb.addClass('textbox-bgicon ' + theRow.iconCls);
                opts.textboxIconCls = theRow.iconCls;
            }
        }
        $(target).combo('setValues', vv);
        panel.triggerHandler('scroll');    // trigger the group sticking

        function findText(value, a){
            var item = $.easyui.getArrayItem(a, opts.valueField, value);
            return item ? item[opts.textField] : undefined;
        }
    }

    /**
     * combobox扩展,去掉鼠标放在展开面板时默认选中鼠标悬停数值
     */
    $.extend($.fn.combobox.defaults, {
        keyHandler: {
            up: function(e){nav(this,'prev');e.preventDefault()},
            down: function(e){nav(this,'next');e.preventDefault()},
            left: function(e){},
            right: function(e){},
            enter: function(e){doEnter(this)},
            query: function(q,e){doQuery(this, q)}
        },
    });

})(jQuery)

二、不要在 Array 上使用 for-in 循环

for-in 循环只用于 object/map/hash 的遍历, 对 Array 用 for-in 循环有时会出错. 因为它并不是从 0 到 length - 1 进行遍历, 而是所有出现在对象及其原型链的键值。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值