easyui源码翻译1.32--Combo(自定义下拉框)

前言

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

自定义下拉框显示一个可编辑的文本框和下拉面板在html页面。这是构建其他复杂的组合部件(如:combobox,combotree,combogrid等)之前需要构建的最基本的组件

依赖关系

  • validatebox
  • panel

 

源码

/**

 * jQuery EasyUI 1.3.2

 * 

 *翻译:qq 1364386878 自定义下拉框

 */

(function ($) {

    //调整组件宽度

    function _resize(jq, width) {

        var opts = $.data(jq, "combo").options;

        var combo = $.data(jq, "combo").combo;

        var panel = $.data(jq, "combo").panel;

        if (width) {

            opts.width = width;

        }

        if (isNaN(opts.width)) {

            var c = $(jq).clone();

            c.css("visibility", "hidden");

            c.appendTo("body");

            opts.width = c.outerWidth();

            c.remove();

        }

        combo.appendTo("body");

        var combotext = combo.find("input.combo-text");

        var comboarrow = combo.find(".combo-arrow");

        var arrowWidth = opts.hasDownArrow ? comboarrow._outerWidth() : 0;//下拉箭头宽度

        combo._outerWidth(opts.width)._outerHeight(opts.height);

        combotext._outerWidth(combo.width() - arrowWidth);

        combotext.css({ height: combo.height() + "px", lineHeight: combo.height() + "px" });



        comboarrow._outerHeight(combo.height());

        panel.panel("resize", {

            width: (opts.panelWidth ? opts.panelWidth : combo.outerWidth()),

            height: opts.panelHeight

        });

        combo.insertAfter(jq);

    };

    //是否显示下拉箭头

    function setDownArrow(jq) {

        var opts = $.data(jq, "combo").options;

        var combo = $.data(jq, "combo").combo;

        if (opts.hasDownArrow) {

            combo.find(".combo-arrow").show();

        } else {

            combo.find(".combo-arrow").hide();

        }

    };

    // 渲染组件

    function renderCombo(target) {

        $(target).addClass("combo-f").hide();

        var combo = $("<span class=\"combo\"></span>").insertAfter(target);

        var text = $("<input type=\"text\" class=\"combo-text\">").appendTo(combo);//将text框添加到combo

        $("<span><span class=\"combo-arrow\"></span></span>").appendTo(combo);//将下来箭头添加到combo

        $("<input type=\"hidden\" class=\"combo-value\">").appendTo(combo);//将隐藏域添加到combo以存放combo的value

        var combpanel = $("<div class=\"combo-panel\"></div>").appendTo("body");//将下来面板添加到body

        //设置下拉面板

        combpanel.panel({

            doSize: false,

            closed: true,

            cls: "combo-p",

            style: { position: "absolute", zIndex: 10 },

            onOpen: function () {

                $(this).panel("resize");

            }

        });

        var name = $(target).attr("name");

        if (name) {

            combo.find("input.combo-value").attr("name", name);

            $(target).removeAttr("name").attr("comboName", name);

        }

        text.attr("autocomplete", "off");//关闭自动完成

        return { combo: combo, panel: combpanel };

    };

    //销毁Combo

    function _destroy(jq) {

        var textBox = $.data(jq, "combo").combo.find("input.combo-text");

        textBox.validatebox("destroy");

        $.data(jq, "combo").panel.panel("destroy");

        $.data(jq, "combo").combo.remove();

        $(jq).remove();

    };

    //绑定事件

    function bindEvents(jq) {

        var combo = $.data(jq, "combo");

        var opts = combo.options;

        var combo2 = $.data(jq, "combo").combo;

        var panel = $.data(jq, "combo").panel;

        var combotext = combo2.find(".combo-text");

        var comboarrow = combo2.find(".combo-arrow");//下拉箭头

        $(document).unbind(".combo").bind("mousedown.combo", function (e) {

            //鼠标点击combo外,关闭选择面板

            var p = $(e.target).closest("span.combo,div.combo-panel");

            if (p.length) {

                return;

            }

            var combopanel = $("body>div.combo-p>div.combo-panel");

            combopanel.panel("close");

        });

        //移除事件处理器

        combo2.unbind(".combo");

        panel.unbind(".combo");

        combotext.unbind(".combo");

        comboarrow.unbind(".combo");

        //若组件未禁用,添加以下事件处理器

        if (!opts.disabled) {

            combotext.bind("mousedown.combo", function (e) {

                $("div.combo-panel").not(panel).panel("close");

                ////该方法将停止事件的传播,阻止它被分派到其他 Document节点,

                e.stopPropagation();

            }).bind("keydown.combo", function (e) {

                switch (e.keyCode) {

                    case 38://小键盘上箭头

                        opts.keyHandler.up.call(jq);

                        break;

                    case 40://小键盘下箭头

                        opts.keyHandler.down.call(jq);

                        break;

                    case 13://Enter键

                        e.preventDefault();

                        opts.keyHandler.enter.call(jq);

                        return false;

                    case 9://Tab键

                    case 27://Esc键

                        hidePanel(jq);

                        break;

                    default:

                        if (opts.editable) {

                            if (combo.timer) {

                                clearTimeout(combo.timer);

                            }

                            combo.timer = setTimeout(function () {

                                var q = combotext.val();

                                if (combo.previousValue != q) {

                                    combo.previousValue = q;

                                    $(jq).combo("showPanel");

                                    opts.keyHandler.query.call(jq, combotext.val());

                                    _validate(jq, true);

                                }

                            }, opts.delay);

                        }

                }

            });

            //下拉箭头绑定事件

            comboarrow.bind("click.combo", function () {

                if (panel.is(":visible")) {

                    hidePanel(jq);

                } else {

                    $("div.combo-panel").panel("close");

                    $(jq).combo("showPanel");

                }

                combotext.focus();

            }).bind("mouseenter.combo", function () {

                $(this).addClass("combo-arrow-hover");

            }).bind("mouseleave.combo", function () {

                $(this).removeClass("combo-arrow-hover");

            }).bind("mousedown.combo", function () {

            });

        }

    };

    //showPanel

    function _showPanel(jq) {

        var opts = $.data(jq, "combo").options;

        var combo = $.data(jq, "combo").combo;

        var panel = $.data(jq, "combo").panel;

        if ($.fn.window) {

            //若放在窗口里面,则显示在窗口之上

            panel.panel("panel").css("z-index", $.fn.window.defaults.zIndex++);

        }

        panel.panel("move", {

            left: combo.offset().left,

            top: getOffsetTop()

        });

        if (panel.panel("options").closed) {

            panel.panel("open");

            opts.onShowPanel.call(jq);

        }

        (function () {

            if (panel.is(":visible")) {

                panel.panel("move", {

                    left: getOffsetLeft(),

                    top: getOffsetTop()

                });

                setTimeout(arguments.callee, 200);

            }

        })();

        //* 获取Left位置

        function getOffsetLeft() {

            var left = combo.offset().left;

            if (left + panel._outerWidth() > $(window)._outerWidth() + $(document).scrollLeft()) {

                left = $(window)._outerWidth() + $(document).scrollLeft() - panel._outerWidth();

            }

            if (left < 0) {

                left = 0;

            }

            return left;

        };

        // 获取TOP位置

        function getOffsetTop() {

            var top = combo.offset().top + combo._outerHeight();

            if (top + panel._outerHeight() > $(window)._outerHeight() + $(document).scrollTop()) {

                top = combo.offset().top - panel._outerHeight();

            }

            if (top < $(document).scrollTop()) {

                top = combo.offset().top + combo._outerHeight();

            }

            return top;

        };

    };

    //  隐藏下拉选择面板

    function hidePanel(jq) {

        var opts = $.data(jq, "combo").options;

        var panel = $.data(jq, "combo").panel;

        panel.panel("close");

        opts.onHidePanel.call(jq);

    };

    //校验值

    function _validate(jq, tag) {

        var opts = $.data(jq, "combo").options;

        var textBox = $.data(jq, "combo").combo.find("input.combo-text");

        textBox.validatebox(opts);

        if (tag) {

            textBox.validatebox("validate");

        }

    };

    // 设置禁用/启用组件样式

    function _disable(jq, disabled) {

        var opts = $.data(jq, "combo").options;

        var combo = $.data(jq, "combo").combo;

        if (disabled) {

            opts.disabled = true;

            $(jq).attr("disabled", true);

            combo.find(".combo-value").attr("disabled", true);

            combo.find(".combo-text").attr("disabled", true);

        } else {

            opts.disabled = false;

            $(jq).removeAttr("disabled");

            combo.find(".combo-value").removeAttr("disabled");

            combo.find(".combo-text").removeAttr("disabled");

        }

    };

    // 清空combo值

    function _clear(jq) {

        var opts = $.data(jq, "combo").options;

        var combo = $.data(jq, "combo").combo;

        if (opts.multiple) {

            combo.find("input.combo-value").remove();

        } else {

            combo.find("input.combo-value").val("");

        }

        combo.find("input.combo-text").val("");

    };

    //获取text值

    function _getText(jq) {

        var combo = $.data(jq, "combo").combo;

        return combo.find("input.combo-text").val();

    };

    //设置text值

    function _setText(jq, text) {

        var combo = $.data(jq, "combo").combo;

        combo.find("input.combo-text").val(text);

        _validate(jq, true);

        $.data(jq, "combo").previousValue = text;

    };

    //获取值(多选)

    function _getValues(jq) {

        var values = [];

        var combo = $.data(jq, "combo").combo;

        combo.find("input.combo-value").each(function () {

            values.push($(this).val());

        });

        return values;

    };

    //设置值(多选)

    function _setValues(jq, values) {

        var opts = $.data(jq, "combo").options;

        var nowValues = _getValues(jq);//获取当前值数组

        var combo = $.data(jq, "combo").combo;

        combo.find("input.combo-value").remove();//清空原来的值

        var name = $(jq).attr("comboName");

        for (var i = 0; i < values.length; i++) {

            var _4c = $("<input type=\"hidden\" class=\"combo-value\">").appendTo(combo);

            if (name) {

                _4c.attr("name", name);

            }

            _4c.val(values[i]);

        }

        var tmp = [];

        for (var i = 0; i < nowValues.length; i++) {

            tmp[i] = nowValues[i];

        }

        var aa = [];

        for (var i = 0; i < values.length; i++) {

            for (var j = 0; j < tmp.length; j++) {

                if (values[i] == tmp[j]) {

                    aa.push(values[i]);

                    //splice()方法用于插入、删除或替换数组的元素,详细参考http://www.w3school.com.cn/js/jsref_splice.asp

                    tmp.splice(j, 1);

                    break;

                }

            }

        }

        ////若设置值数组与原值数组不相等,则将设置值数组、原值数组返回给onChange事件作为参数,并响应事件

        if (aa.length != values.length || values.length != nowValues.length) {

            if (opts.multiple) {

                opts.onChange.call(jq, values, nowValues);

            } else {

                opts.onChange.call(jq, values[0], nowValues[0]);

            }

        }

    };

    //获取值(单选)

    function _getValue(jq) {

        var values = _getValues(jq);

        return values[0];

    };

    //设置值(单选)

    function _setValue(jq, value) {

        _setValues(jq, [value]);

    };

    //初始化combo值

    function initValue(jq) {

        var opts = $.data(jq, "combo").options;

        var fn = opts.onChange;

        opts.onChange = function () { };

        //如果设置多选

        if (opts.multiple) {

            if (opts.value) {

                if (typeof opts.value == "object") {

                    _setValues(jq, opts.value);

                } else {

                    _setValue(jq, opts.value);

                }

            } else {

                _setValues(jq, []);

            }

            opts.originalValue = _getValues(jq);

        } else {

            _setValue(jq, opts.value);

            opts.originalValue = opts.value;

        }

        opts.onChange = fn;

    };

    //实例化下拉框

    $.fn.combo = function (target, parm) {

        if (typeof target == "string") {

            return $.fn.combo.methods[target](this, parm);

        }

        target = target || {};

        return this.each(function () {

            var combo = $.data(this, "combo");

            if (combo) {

                $.extend(combo.options, target);

            } else {

                var r = renderCombo(this);

                combo = $.data(this, "combo", {

                    options: $.extend({},

                        $.fn.combo.defaults,

                        $.fn.combo.parseOptions(this),

                        target),

                    combo: r.combo,

                    panel: r.panel,

                    previousValue: null

                });

                $(this).removeAttr("disabled");

            }

            $("input.combo-text", combo.combo).attr("readonly", !combo.options.editable);

            setDownArrow(this);//设置是否显示下拉箭头

            _disable(this, combo.options.disabled);//设置是否禁用

            _resize(this);

            bindEvents(this);

            _validate(this);

            initValue(this);//初始化combo值

        });

    };

    //默认方法

    $.fn.combo.methods = {

        //返回属性对象

        options: function (jq) {

            return $.data(jq[0], "combo").options;

        },

        //返回下拉面板对象

        panel: function (jq) {

            return $.data(jq[0], "combo").panel;

        },

        //返回文本框对象

        textbox: function (jq) {

            return $.data(jq[0], "combo").combo.find("input.combo-text");

        },

        //销毁该组件

        destroy: function (jq) {

            return jq.each(function () {

                _destroy(this);

            });

        },

        //  调整组件宽度

        resize: function (jq, width) {

            return jq.each(function () {

                _resize(this, width);

            });

        },

        //显示下拉面板

        showPanel: function (jq) {

            return jq.each(function () {

                _showPanel(this);

            });

        },

        //隐藏下拉面板

        hidePanel: function (jq) {

            return jq.each(function () {

                hidePanel(this);

            });

        },

        //禁用组件

        disable: function (jq) {

            return jq.each(function () {

                _disable(this, true);

                bindEvents(this);

            });

        },

        //启用组件

        enable: function (jq) {

            return jq.each(function () {

                _disable(this, false);

                bindEvents(this);

            });

        },

        //验证输入的值

        validate: function (jq) {

            return jq.each(function () {

                _validate(this, true);

            });

        },

        //返回验证结果

        isValid: function (jq) {

            var combo = $.data(jq[0], "combo").combo.find("input.combo-text");

            return combo.validatebox("isValid");

        },

        //清除控件的值

        clear: function (jq) {

            return jq.each(function () {

                _clear(this);

            });

        },

        //重置控件的值

        reset: function (jq) {

            return jq.each(function () {

                var opts = $.data(this, "combo").options;

                if (opts.multiple) {

                    $(this).combo("setValues", opts.originalValue);

                } else {

                    $(this).combo("setValue", opts.originalValue);

                }

            });

        },

        //获取输入的文本

        getText: function (jq) {

            return _getText(jq[0]);

        },

        //设置输入的文本

        setText: function (jq, text) {

            return jq.each(function () {

                _setText(this, text);

            });

        },

        //获取组件值的数组

        getValues: function (jq) {

            return _getValues(jq[0]);

        },

        //设置组件值的数组

        setValues: function (jq, values) {

            return jq.each(function () {

                _setValues(this, values);

            });

        },

        //获取组件的值

        getValue: function (jq) {

            return _getValue(jq[0]);

        },

        //设置组件的值

        setValue: function (jq, value) {

            return jq.each(function () {

                _setValue(this, value);

            });

        }

    };

    //解析器 定义属性转化为options

    $.fn.combo.parseOptions = function (target) {

        var t = $(target);

        return $.extend({}, $.fn.validatebox.parseOptions(target),

            $.parser.parseOptions(target, ["width", "height", "separator",

                { panelWidth: "number", editable: "boolean", hasDownArrow: "boolean", delay: "number" }]),

                {

                    panelHeight: (t.attr("panelHeight") == "auto" ? "auto" : parseInt(t.attr("panelHeight")) || undefined),

                    multiple: (t.attr("multiple") ? true : undefined),

                    disabled: (t.attr("disabled") ? true : undefined),

                    value: (t.val() || undefined)

                });

    };

    //默认属性和事件 

    $.fn.combo.defaults = $.extend({}, $.fn.validatebox.defaults, {

        width: "auto",//组件的宽度

        height: 22,//组件的高度

        panelWidth: null,//下拉面板宽度

        panelHeight: 200,//下拉面板高度

        multiple: false,//定义是否支持多选

        separator: ",",//在多选的时候使用何种分隔符进行分割

        editable: true,//定义用户是否可以直接输入文本到字段中

        disabled: false,//定义是否禁用字段

        hasDownArrow: true,//定义是否显示向下箭头按钮。

        value: "",//字段的默认值

        delay: 200,//最后一次输入事件与执行搜索之间的延迟间隔(执行自动完成功能的延迟间隔)

        //在用户按下键的时候调用一个函数

        keyHandler: {

            up: function () {},

            down: function () {},

            enter: function () {},

            query: function (q) {}

        },

        //当下拉面板显示的时候触发

        onShowPanel: function () {},

        //当下拉面板隐藏的时候触发

        onHidePanel: function () {},

        //当字段值改变的时候触发

        onChange: function (newValue, oldValue) {}

    });

})(jQuery);
View Code

示例代码

<!DOCTYPE html>

<html>

<head>

    <meta charset="UTF-8">

    <title>Basic Combo - 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>

</head>

<body>

    <h2>Basic Combo</h2>

    <div class="demo-info" style="margin-bottom:10px">

        <div class="demo-tip icon-tip"></div>

        <div>Click the right arrow button to show drop down panel that can be filled with any content.</div>

    </div>

    <select id="cc" style="width:150px"></select>

    <div id="sp">

        <div style="color:#99BBE8;background:#fafafa;padding:5px;">Select a language</div>

        <input type="radio" name="lang" value="01"><span>Java</span><br/>

        <input type="radio" name="lang" value="02"><span>C#</span><br/>

        <input type="radio" name="lang" value="03"><span>Ruby</span><br/>

        <input type="radio" name="lang" value="04"><span>Basic</span><br/>

        <input type="radio" name="lang" value="05"><span>Fortran</span>

    </div>

    <script type="text/javascript">

        $(function(){

            $('#cc').combo({

                required:true,

                editable:false

            });

            $('#sp').appendTo($('#cc').combo('panel'));

            $('#sp input').click(function(){

                var v = $(this).val();

                var s = $(this).next('span').text();

                $('#cc').combo('setValue', v).combo('setText', s).combo('hidePanel');

            });

        });

    </script>

</body>

</html>
View Code

插件效果

easyui源码翻译1.32--Combo(自定义下拉框)

 

你可能感兴趣的:(easyui)