easyui源码翻译1.32--ComboBox(下拉列表框)

前言

  

扩展自$.fn.combo.defaults。使用$.fn.combobox.defaults重写默认值对象。下载该插件翻译源码

下拉列表框显示一个可编辑文本框和下拉式列表,用户可以选择一个值或多个值。用户可以直接输入文本到列表顶部或选择一个或多个当前列表中的值

依赖关系

  • combo

源码

 

/**
 * jQuery EasyUI 1.3.2
 * 
 *翻译:qq 1364386878
 */
(function ($) {
    //设置下拉面板滚动条位置
    function scrollTo(jq, value) {
        var panel = $(jq).combo("panel");
        var item = panel.find("div.combobox-item[value=\"" + value + "\"]");
        if (item.length) {
            if (item.position().top <= 0) {
                var h = panel.scrollTop() + item.position().top;
                panel.scrollTop(h);
            } else {
                if (item.position().top + item.outerHeight() > panel.height()) {
                    var h = panel.scrollTop() + item.position().top + item.outerHeight() - panel.height();
                    panel.scrollTop(h);
                }
            }
        }
    };
    //小键盘向上选择操作
    function _up(jq) {
        var panel = $(jq).combo("panel");
        var values = $(jq).combo("getValues");
        //获取到combo值在下拉面板panel里面对应的item项的前一选项
        var item = panel.find("div.combobox-item[value=\"" + values.pop() + "\"]");
        if (item.length) {
            var prevItem = item.prev(":visible");
            if (prevItem.length) {
                item = prevItem;//若有前一项,则item指向前一个选项
            }
        } else {
            //若不存在前一项,则直接指向最后一个选项
            item = panel.find("div.combobox-item:visible:last");
        }
        //获取上一选项的值
        var value = item.attr("value");
        _select(jq, value);
        scrollTo(jq, value);
    };
    //小键盘向下选择操作
    function _down(jq) {
        var panel = $(jq).combo("panel");
        var values = $(jq).combo("getValues");
        //获取到combo值在下拉面板panel里面对应的item项的下一选项
        var item = panel.find("div.combobox-item[value=\"" + values.pop() + "\"]");
        if (item.length) {
            var nextItem = item.next(":visible");//获取下一项
            if (nextItem.length) {
                item = nextItem;//若有下一项,则item指向下一个选项
            }
        } else {
            //若不存在下一项,则直接指向第一个选项
            item = panel.find("div.combobox-item:visible:first");
        }
        var value = item.attr("value");
        _select(jq, value);
        scrollTo(jq, value);
    };
    //选中指定值对应的选项
    function _select(jq, value) {
        var opts = $.data(jq, "combobox").options;
        var data = $.data(jq, "combobox").data;
        //重新设置combobox值(单选/多选)
        if (opts.multiple) {
            var values = $(jq).combo("getValues");
            for (var i = 0; i < values.length; i++) {
                if (values[i] == value) {
                    return;
                }
            }
            //若指定值不在当前值中,则将指定值添加到combobox值数组中
            values.push(value);
            _setValues(jq, values);
        } else {
            _setValues(jq, [value]);
        }
        for (var i = 0; i < data.length; i++) {
            if (data[i][opts.valueField] == value) {
                opts.onSelect.call(jq, data[i]);
                return;
            }
        }
    };
    //取消选择指定值的选项
    function _unselect(jq, value) {
        var opts = $.data(jq, "combobox").options;
        var data = $.data(jq, "combobox").data;
        var values = $(jq).combo("getValues");
        for (var i = 0; i < values.length; i++) {
            if (values[i] == value) {
                values.splice(i, 1);
                _setValues(jq, values);
                break;
            }
        }
        for (var i = 0; i < data.length; i++) {
            if (data[i][opts.valueField] == value) {
                opts.onUnselect.call(jq, data[i]);
                return;
            }
        }
    };
    //设置combobox的值(数组)
    function _setValues(jq, values, single) {
        var opts = $.data(jq, "combobox").options;
        var data = $.data(jq, "combobox").data;
        var panel = $(jq).combo("panel");
        //去掉当前值选项的选中样式
        panel.find("div.combobox-item-selected").removeClass("combobox-item-selected");
        var vv = [], ss = [];
        for (var i = 0; i < values.length; i++) {
            var v = values[i];
            var s = v;
            for (var j = 0; j < data.length; j++) {
                if (data[j][opts.valueField] == v) {
                    s = data[j][opts.textField];
                    break;
                }
            }
            vv.push(v);
            ss.push(s);
            panel.find("div.combobox-item[value=\"" + v + "\"]").addClass("combobox-item-selected");
        }
        $(jq).combo("setValues", vv);
        if (!single) {
            //多选,使用分隔符
            $(jq).combo("setText", ss.join(opts.separator));
        }
    };

    function transformData(jq) {
        var options = $.data(jq, "combobox").options;
        var values = [];
        $(">option", jq).each(function () {
            var value = {};
            value[options.valueField] = $(this).attr("value") != undefined ? $(this).attr("value") : $(this).html();
            value[options.textField] = $(this).html();
            value["selected"] = $(this).attr("selected");
            values.push(value);
        });
        return values;
    };
    //加载数据
    function _loadData(jq, data, single) {
        var options = $.data(jq, "combobox").options;
        var panel = $(jq).combo("panel");
        $.data(jq, "combobox").data = data;
        var values = $(jq).combobox("getValues");
        panel.empty();
        //循环数据,给下拉面板添加选项
        for (var i = 0; i < data.length; i++) {
            var v = data[i][options.valueField];
            var s = data[i][options.textField];
            var item = $("<div class=\"combobox-item\"></div>").appendTo(panel);
            item.attr("value", v);
            if (options.formatter) {
                item.html(options.formatter.call(jq, data[i]));
            } else {
                item.html(s);
            }
            //若选项定义为默认选中
            if (data[i]["selected"]) {
                (function () {
                    for (var i = 0; i < values.length; i++) {
                        if (v == values[i]) {
                            return;
                        }
                    }
                    values.push(v);
                })();
            }
        }
        //设置默认选中值数组values(单选/多选)
        if (options.multiple) {
            _setValues(jq, values, single);
        } else {
            if (values.length) {
                _setValues(jq, [values[values.length - 1]], single);
            } else {
                _setValues(jq, [], single);
            }
        }
        //触发onLoadSuccess事件
        options.onLoadSuccess.call(jq, data);
        //给下拉面板选项注册hover、click事件
        $(".combobox-item", panel).hover(function () {
            $(this).addClass("combobox-item-hover");
        }, function () {
            $(this).removeClass("combobox-item-hover");
        }).click(function () {
            var selectItem = $(this);
            if (options.multiple) {
                if (selectItem.hasClass("combobox-item-selected")) {
                    _unselect(jq, selectItem.attr("value"));
                } else {
                    _select(jq, selectItem.attr("value"));
                }
            } else {
                _select(jq, selectItem.attr("value"));
                //单选时,选中一次就隐藏下拉面板
                $(jq).combo("hidePanel");
            }
        });
    };
    //重新加载数据
    function _reload(jq, url, paramData, single) {
        var options = $.data(jq, "combobox").options;
        if (url) {
            options.url = url;
        }
        paramData = paramData || {};
        if (options.onBeforeLoad.call(jq, paramData) == false) {
            return;
        }
        options.loader.call(jq, paramData, function (data) {
            _loadData(jq, data, single);
        }, function () {
            options.onLoadError.apply(this, arguments);
        });
    };
    // 输入值匹配
    function _query(jq, q) {
        var options = $.data(jq, "combobox").options;
        if (options.multiple && !q) {
            _setValues(jq, [], true);
        } else {
            _setValues(jq, [q], true);
        }
        if (options.mode == "remote") {
            _reload(jq, null, { q: q }, true);
        } else {
            var panel = $(jq).combo("panel");
            panel.find("div.combobox-item").hide();
            //获取combobox的数据
            var data = $.data(jq, "combobox").data;
            for (var i = 0; i < data.length; i++) {
                if (options.filter.call(jq, q, data[i])) {
                    var v = data[i][options.valueField];
                    var s = data[i][options.textField];
                    var item = panel.find("div.combobox-item[value=\"" + v + "\"]");
                    item.show();
                    if (s == q) {
                        _setValues(jq, [v], true);
                        //选项设置为选中样式
                        item.addClass("combobox-item-selected");
                    }
                }
            }
        }
    };

    function create(jq) {
        var options = $.data(jq, "combobox").options;
        $(jq).addClass("combobox-f");
        $(jq).combo($.extend({}, options, {
            onShowPanel: function () {
                $(jq).combo("panel").find("div.combobox-item").show();
                scrollTo(jq, $(jq).combobox("getValue"));
                options.onShowPanel.call(jq);
            }
        }));
    };

    //初始化下拉框
    $.fn.combobox = function (target, parm) {
        if (typeof target == "string") {
            var fn = $.fn.combobox.methods[target];
            if (fn) {
                return fn(this, parm);
            } else {
                return this.combo(target, parm);
            }
        }
        target = target || {};
        return this.each(function () {
            var data = $.data(this, "combobox");
            if (data) {
                $.extend(data.options, target);
                create(this);
            } else {
                data = $.data(this, "combobox", {
                    options: $.extend({},
                        $.fn.combobox.defaults,
                        $.fn.combobox.parseOptions(this), target)
                });
                create(this);
                _loadData(this, transformData(this));
            }
            if (data.options.data) {
                _loadData(this, data.options.data);
            }
            _reload(this);
        });
    };
    //默认方法
    $.fn.combobox.methods = {
        //返回属性对象
        options: function (jq) {
            var options = $.data(jq[0], "combobox").options;
            options.originalValue = jq.combo("options").originalValue;
            return options;
        },
        //返回加载数据
        getData: function (jq) {
            return $.data(jq[0], "combobox").data;
        },
        //设置下拉列表框值数组
        setValues: function (jq, values) {
            return jq.each(function () {
                _setValues(this, values);
            });
        },
        //设置下拉列表框值数组
        setValue: function (jq, value) {
            return jq.each(function () {
                _setValues(this, [value]);
            });
        },
        //清除下拉列表框的值
        clear: function (jq) {
            return jq.each(function () {
                $(this).combo("clear");
                var panel = $(this).combo("panel");
                panel.find("div.combobox-item-selected").removeClass("combobox-item-selected");
            });
        },
        //重置
        reset: function (jq) {
            return jq.each(function () {
                var options = $(this).combobox("options");
                if (options.multiple) {
                    $(this).combobox("setValues", options.originalValue);
                } else {
                    $(this).combobox("setValue", options.originalValue);
                }
            });
        },
        //读取本地列表数据
        loadData: function (jq, data) {
            return jq.each(function () {
                _loadData(this, data);
            });
        },
        //请求远程列表数据。通过'url'参数重写原始URL值
        reload: function (jq, url) {
            return jq.each(function () {
                _reload(this, url);
            });
        },
        //选择指定项
        select: function (jq, value) {
            return jq.each(function () {
                _select(this, value);
            });
        },
        //取消选择指定项
        unselect: function (jq, value) {
            return jq.each(function () {
                _unselect(this, value);
            });
        }
    };

    //解析器配置
    $.fn.combobox.parseOptions = function ( ) {
        var t = $(target);
        return $.extend({}, $.fn.combo.parseOptions(target),
            $.parser.parseOptions(target, ["valueField", "textField", "mode", "method", "url"]));
    };
    //默认属性和事件  继承了comb的默认属性和事件
    $.fn.combobox.defaults = $.extend({}, $.fn.combo.defaults, {
        valueField: "value",//基础数据值名称绑定到该下拉列表框
        textField: "text",//基础数据字段名称绑定到该下拉列表框
        //定义了当文本改变时如何读取列表数据。设置为'remote'时,
        //下拉列表框将会从服务器加载数据。当设置为“remote”模式时,用户输入将被发送到名为'q'的HTTP请求参数到服务器检索新数据
        mode: "local",
        method: "post",//通过URL加载远程列表数据
        url: null,//HTTP方法检索数据(POST / GET)。
        data: null,//数据列表加载

        keyHandler: {
            up: function () {
                _up(this);//小键盘向上选择
            },
            down: function () {
                _down(this);//小键盘向下选择
            },
            enter: function () {
                var values = $(this).combobox("getValues");
                $(this).combobox("setValues", values);
                $(this).combobox("hidePanel");
            },
            query: function (q) {
                _query(this, q);
            }
        },
        // 定义当'mode'设置为'local'时如何过滤本地数据,函数有2个参数:
        //q:用户输入的文本。
        //row:列表行数据。
        //返回true的时候允许行显示。
        filter: function (q, row) {
            var opts = $(this).combobox("options");
            return row[opts.textField].indexOf(q) == 0;
        },
        //定义如何渲染行。该函数接受1个参数:row
        formatter: function (row) {
            var options = $(this).combobox("options");
            return row[options.textField];
        },
        //定义了如何从远程服务器加载数据。返回false可以忽略该动作。该函数具备如下参数:
        //param:传递到远程服务器的参数对象。
        //success(data):在检索数据成功的时候调用该回调函数。
        //    error():在检索数据失败的时候调用该回调函数
        loader: function (param, success, error) {
            var options = $(this).combobox("options");
            if (!options.url) {
                return false;
            }
            $.ajax({
                type: options.method,
                url: options.url,
                data: param,
                dataType: "json",
                success: function (data) {
                    success(data);
                }, error: function () {
                    error.apply(this, arguments);
                }
            });
        },
        //在请求加载数据之前触发,返回false取消该加载动作
        onBeforeLoad: function (param) {
        },
        //在加载远程数据成功的时候触发
        onLoadSuccess: function () {
        },
        //在加载远程数据成功的时候触发
        onLoadError: function () {
        },
        //在用户选择列表项的时候触发
        onSelect: function (_5a) {
        },
        //在用户取消选择列表项的时候触发
        onUnselect: function (_5b) {
        }
    });
})(jQuery);
View Code

 

示例代码

 

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Basic ComboBox - jQuery EasyUI Demo</title>
    <link rel="stylesheet" type="text/css" href="../../themes/default/easyui.css">
    <link rel="stylesheet" type="text/css" href="../../themes/icon.css">
    <link rel="stylesheet" type="text/css" href="../demo.css">
    <script type="text/javascript" src="../../jquery-1.8.0.min.js"></script>
     <script src="../../plugins2/jquery.parser.js"></script>
    <script src="../../plugins2/jquery.validatebox.js"></script>
    <script src="../../plugins2/jquery.panel.js"></script>    
    <script src="../../plugins2/jquery.combo.js"></script>
    <script src="../../plugins2/jquery.combobox.js"></script>
</head>
<body>
    <h2>Basic ComboBox</h2>
    <div class="demo-info" style="margin-bottom:10px">
        <div class="demo-tip icon-tip"></div>
        <div>Type in ComboBox to try auto complete.</div>
    </div>
    
    <select class="easyui-combobox" name="state" style="width:200px;">
        <option value="AL">Alabama</option>
        <option value="AK">Alaska</option>
        <option value="AZ">Arizona</option>
        <option value="AR">Arkansas</option>
        <option value="CA">California</option>
        <option value="CO">Colorado</option>
        <option value="CT">Connecticut</option>
        <option value="DE">Delaware</option>
        <option value="FL">Florida</option>
        <option value="GA">Georgia</option>
        <option value="HI">Hawaii</option>
        <option value="ID">Idaho</option>
        <option value="IL">Illinois</option>
        <option value="IN">Indiana</option>
        <option value="IA">Iowa</option>
        <option value="KS">Kansas</option>
        <option value="KY">Kentucky</option>
        <option value="LA">Louisiana</option>
        <option value="ME">Maine</option>
        <option value="MD">Maryland</option>
        <option value="MA">Massachusetts</option>
        <option value="MI">Michigan</option>
        <option value="MN">Minnesota</option>
        <option value="MS">Mississippi</option>
        <option value="MO">Missouri</option>
        <option value="MT">Montana</option>
        <option value="NE">Nebraska</option>
        <option value="NV">Nevada</option>
        <option value="NH">New Hampshire</option>
        <option value="NJ">New Jersey</option>
        <option value="NM">New Mexico</option>
        <option value="NY">New York</option>
        <option value="NC">North Carolina</option>
        <option value="ND">North Dakota</option>
        <option value="OH" selected>Ohio</option>
        <option value="OK">Oklahoma</option>
        <option value="OR">Oregon</option>
        <option value="PA">Pennsylvania</option>
        <option value="RI">Rhode Island</option>
        <option value="SC">South Carolina</option>
        <option value="SD">South Dakota</option>
        <option value="TN">Tennessee</option>
        <option value="TX">Texas</option>
        <option value="UT">Utah</option>
        <option value="VT">Vermont</option>
        <option value="VA">Virginia</option>
        <option value="WA">Washington</option>
        <option value="WV">West Virginia</option>
        <option value="WI">Wisconsin</option>
        <option value="WY">Wyoming</option>
    </select>

</body>
</html>
View Code

 

插件效果

posted @ 2013-12-28 23:04  Jimmy-Lee  阅读(2139)  评论(0编辑  收藏  举报