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

插件效果

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM