zoukankan      html  css  js  c++  java
  • 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", {
                 (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, {
             "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="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

    插件效果

    热爱编程,热爱技术,热爱生活
  • 相关阅读:
    ContextLoaderListener作用详解
    Spring启动流程
    解决filter拦截request中body内容后,字符流关闭,无法传到controller的问题
    Spring拦截器从Request中获取Json格式的数据
    Filter和Interceptor的终归作用还是从入口修改或验证请求进来的数据
    HttpServletRequest常用获取URL的方法
    Spark1.0.0 监测方法
    nginx代理人server结合tomcat采用
    Guangsoushensou 2
    admob广告开始个人资料网址
  • 原文地址:https://www.cnblogs.com/DemoLee/p/3495904.html
Copyright © 2011-2022 走看看