• 修改jquery.automeplete,使其支持value匹配


    原生只会去匹配label,可在实际使用中,可能需要匹配的值并不需要显示在label中,经过添加一个matchType属性解决

    1、加入matchType选项,并默认为原生匹配

            $.widget("ui.autocomplete", {
                version: "1.11.0",
                defaultElement: "<input>",
                options: {
                    appendTo: null,
                    autoFocus: false,
                    delay: 300,
                    minLength: 1,
                    position: {
                        my: "left top",
                        at: "left bottom",
                        collision: "none"
                    },
                    source: null,
    
                    // callbacks
                    change: null,
                    close: null,
                    focus: null,
                    open: null,
                    response: null,
                    search: null,
                    select: null,
                    //all,label,value
                    matchType: 'all'
                },

    2、在_initSource中给filter传入type参数

                _initSource: function() {
                    var array, url, type
                    that = this;
                    if ($.isArray(this.options.source)) {
                        array = this.options.source;
                        type = this.options.matchType;
                        this.source = function(request, response) {
                        response($.ui.autocomplete.filter(array, request.term, type));
                        };
                    } else if (typeof this.options.source === "string") {
                        url = this.options.source;
                        this.source = function(request, response) {
                            if (that.xhr) {
                                that.xhr.abort();
                            }
                            that.xhr = $.ajax({
                                url: url,
                                data: request,
                                dataType: "json",
                                success: function(data) {
                                    response(data);
                                },
                                error: function() {
                                    response([]);
                                }
                            });
                        };
                    } else {
                        this.source = this.options.source;
                    }
                },

    3、修改filter

            $.extend($.ui.autocomplete, {
                escapeRegex: function(value) {
                    return value.replace(/[-[]{}()*+?.,\^$|#s]/g, "\$&");
                },
                filter: function(array, term,type) {
                    var matcher = new RegExp($.ui.autocomplete.escapeRegex(term), "i");
    
                    return $.grep(array, function(value) {
                        if (type == "label") {
                            return matcher.test(value.value);
                        } else if (type == "value") {
                            return matcher.test(value.value);
    
                        } else {
                            return matcher.test(value.label || value.value || value);
                        }
                    });
                }
            });

    最终代码:

    /*! jQuery UI - v1.11.0 - 2014-07-06
    * http://jqueryui.com
    * Includes: core.js, widget.js, position.js, autocomplete.js, menu.js
    * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
    
    (function(factory) {
        if (typeof define === "function" && define.amd) {
    
            // AMD. Register as an anonymous module.
            define(["jquery"], factory);
        } else {
    
            // Browser globals
            factory(jQuery);
        }
    } (function($) {
        /*!
        * jQuery UI Core 1.11.0
        * http://jqueryui.com
        *
        * Copyright 2014 jQuery Foundation and other contributors
        * Released under the MIT license.
        * http://jquery.org/license
        *
        * http://api.jqueryui.com/category/ui-core/
        */
    
    
        // $.ui might exist from components with no dependencies, e.g., $.ui.position
        $.ui = $.ui || {};
    
        $.extend($.ui, {
            version: "1.11.0",
    
            keyCode: {
                BACKSPACE: 8,
                COMMA: 188,
                DELETE: 46,
                DOWN: 40,
                END: 35,
                ENTER: 13,
                ESCAPE: 27,
                HOME: 36,
                LEFT: 37,
                PAGE_DOWN: 34,
                PAGE_UP: 33,
                PERIOD: 190,
                RIGHT: 39,
                SPACE: 32,
                TAB: 9,
                UP: 38
            }
        });
    
        // plugins
        $.fn.extend({
            scrollParent: function() {
                var position = this.css("position"),
                excludeStaticParent = position === "absolute",
                scrollParent = this.parents().filter(function() {
                    var parent = $(this);
                    if (excludeStaticParent && parent.css("position") === "static") {
                        return false;
                    }
                    return (/(auto|scroll)/).test(parent.css("overflow") + parent.css("overflow-y") + parent.css("overflow-x"));
                }).eq(0);
    
                return position === "fixed" || !scrollParent.length ? $(this[0].ownerDocument || document) : scrollParent;
            },
    
            uniqueId: (function() {
                var uuid = 0;
    
                return function() {
                    return this.each(function() {
                        if (!this.id) {
                            this.id = "ui-id-" + (++uuid);
                        }
                    });
                };
            })(),
    
            removeUniqueId: function() {
                return this.each(function() {
                    if (/^ui-id-d+$/.test(this.id)) {
                        $(this).removeAttr("id");
                    }
                });
            }
        });
    
        // selectors
        function focusable(element, isTabIndexNotNaN) {
            var map, mapName, img,
            nodeName = element.nodeName.toLowerCase();
            if ("area" === nodeName) {
                map = element.parentNode;
                mapName = map.name;
                if (!element.href || !mapName || map.nodeName.toLowerCase() !== "map") {
                    return false;
                }
                img = $("img[usemap=#" + mapName + "]")[0];
                return !!img && visible(img);
            }
            return (/input|select|textarea|button|object/.test(nodeName) ?
            !element.disabled :
            "a" === nodeName ?
                element.href || isTabIndexNotNaN :
                isTabIndexNotNaN) &&
            // the element and all of its ancestors must be visible
            visible(element);
        }
    
        function visible(element) {
            return $.expr.filters.visible(element) &&
            !$(element).parents().addBack().filter(function() {
                return $.css(this, "visibility") === "hidden";
            }).length;
        }
    
        $.extend($.expr[":"], {
            data: $.expr.createPseudo ?
            $.expr.createPseudo(function(dataName) {
                return function(elem) {
                    return !!$.data(elem, dataName);
                };
            }) :
            // support: jQuery <1.8
            function(elem, i, match) {
                return !!$.data(elem, match[3]);
            },
    
            focusable: function(element) {
                return focusable(element, !isNaN($.attr(element, "tabindex")));
            },
    
            tabbable: function(element) {
                var tabIndex = $.attr(element, "tabindex"),
                isTabIndexNaN = isNaN(tabIndex);
                return (isTabIndexNaN || tabIndex >= 0) && focusable(element, !isTabIndexNaN);
            }
        });
    
        // support: jQuery <1.8
        if (!$("<a>").outerWidth(1).jquery) {
            $.each(["Width", "Height"], function(i, name) {
                var side = name === "Width" ? ["Left", "Right"] : ["Top", "Bottom"],
                type = name.toLowerCase(),
                orig = {
                    innerWidth: $.fn.innerWidth,
                    innerHeight: $.fn.innerHeight,
                    outerWidth: $.fn.outerWidth,
                    outerHeight: $.fn.outerHeight
                };
    
                function reduce(elem, size, border, margin) {
                    $.each(side, function() {
                        size -= parseFloat($.css(elem, "padding" + this)) || 0;
                        if (border) {
                            size -= parseFloat($.css(elem, "border" + this + "Width")) || 0;
                        }
                        if (margin) {
                            size -= parseFloat($.css(elem, "margin" + this)) || 0;
                        }
                    });
                    return size;
                }
    
                $.fn["inner" + name] = function(size) {
                    if (size === undefined) {
                        return orig["inner" + name].call(this);
                    }
    
                    return this.each(function() {
                        $(this).css(type, reduce(this, size) + "px");
                    });
                };
    
                $.fn["outer" + name] = function(size, margin) {
                    if (typeof size !== "number") {
                        return orig["outer" + name].call(this, size);
                    }
    
                    return this.each(function() {
                        $(this).css(type, reduce(this, size, true, margin) + "px");
                    });
                };
            });
        }
    
        // support: jQuery <1.8
        if (!$.fn.addBack) {
            $.fn.addBack = function(selector) {
                return this.add(selector == null ?
                this.prevObject : this.prevObject.filter(selector)
            );
            };
        }
    
        // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
        if ($("<a>").data("a-b", "a").removeData("a-b").data("a-b")) {
            $.fn.removeData = (function(removeData) {
                return function(key) {
                    if (arguments.length) {
                        return removeData.call(this, $.camelCase(key));
                    } else {
                        return removeData.call(this);
                    }
                };
            })($.fn.removeData);
        }
    
        // deprecated
        $.ui.ie = !!/msie [w.]+/.exec(navigator.userAgent.toLowerCase());
    
        $.fn.extend({
            focus: (function(orig) {
                return function(delay, fn) {
                    return typeof delay === "number" ?
                    this.each(function() {
                        var elem = this;
                        setTimeout(function() {
                            $(elem).focus();
                            if (fn) {
                                fn.call(elem);
                            }
                        }, delay);
                    }) :
                    orig.apply(this, arguments);
                };
            })($.fn.focus),
    
            disableSelection: (function() {
                var eventType = "onselectstart" in document.createElement("div") ?
                "selectstart" :
                "mousedown";
    
                return function() {
                    return this.bind(eventType + ".ui-disableSelection", function(event) {
                        event.preventDefault();
                    });
                };
            })(),
    
            enableSelection: function() {
                return this.unbind(".ui-disableSelection");
            },
    
            zIndex: function(zIndex) {
                if (zIndex !== undefined) {
                    return this.css("zIndex", zIndex);
                }
    
                if (this.length) {
                    var elem = $(this[0]), position, value;
                    while (elem.length && elem[0] !== document) {
                        // Ignore z-index if position is set to a value where z-index is ignored by the browser
                        // This makes behavior of this function consistent across browsers
                        // WebKit always returns auto if the element is positioned
                        position = elem.css("position");
                        if (position === "absolute" || position === "relative" || position === "fixed") {
                            // IE returns 0 when zIndex is not specified
                            // other browsers return a string
                            // we ignore the case of nested elements with an explicit value of 0
                            // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
                            value = parseInt(elem.css("zIndex"), 10);
                            if (!isNaN(value) && value !== 0) {
                                return value;
                            }
                        }
                        elem = elem.parent();
                    }
                }
    
                return 0;
            }
        });
    
        // $.ui.plugin is deprecated. Use $.widget() extensions instead.
        $.ui.plugin = {
            add: function(module, option, set) {
                var i,
                proto = $.ui[module].prototype;
                for (i in set) {
                    proto.plugins[i] = proto.plugins[i] || [];
                    proto.plugins[i].push([option, set[i]]);
                }
            },
            call: function(instance, name, args, allowDisconnected) {
                var i,
                set = instance.plugins[name];
    
                if (!set) {
                    return;
                }
    
                if (!allowDisconnected && (!instance.element[0].parentNode || instance.element[0].parentNode.nodeType === 11)) {
                    return;
                }
    
                for (i = 0; i < set.length; i++) {
                    if (instance.options[set[i][0]]) {
                        set[i][1].apply(instance.element, args);
                    }
                }
            }
        };
    
    
        /*!
        * jQuery UI Widget 1.11.0
        * http://jqueryui.com
        *
        * Copyright 2014 jQuery Foundation and other contributors
        * Released under the MIT license.
        * http://jquery.org/license
        *
        * http://api.jqueryui.com/jQuery.widget/
        */
    
    
        var widget_uuid = 0,
        widget_slice = Array.prototype.slice;
    
        $.cleanData = (function(orig) {
            return function(elems) {
                for (var i = 0, elem; (elem = elems[i]) != null; i++) {
                    try {
                        $(elem).triggerHandler("remove");
                        // http://bugs.jquery.com/ticket/8235
                    } catch (e) { }
                }
                orig(elems);
            };
        })($.cleanData);
    
        $.widget = function(name, base, prototype) {
            var fullName, existingConstructor, constructor, basePrototype,
            // proxiedPrototype allows the provided prototype to remain unmodified
            // so that it can be used as a mixin for multiple widgets (#8876)
            proxiedPrototype = {},
            namespace = name.split(".")[0];
    
            name = name.split(".")[1];
            fullName = namespace + "-" + name;
    
            if (!prototype) {
                prototype = base;
                base = $.Widget;
            }
    
            // create selector for plugin
            $.expr[":"][fullName.toLowerCase()] = function(elem) {
                return !!$.data(elem, fullName);
            };
    
            $[namespace] = $[namespace] || {};
            existingConstructor = $[namespace][name];
            constructor = $[namespace][name] = function(options, element) {
                // allow instantiation without "new" keyword
                if (!this._createWidget) {
                    return new constructor(options, element);
                }
    
                // allow instantiation without initializing for simple inheritance
                // must use "new" keyword (the code above always passes args)
                if (arguments.length) {
                    this._createWidget(options, element);
                }
            };
            // extend with the existing constructor to carry over any static properties
            $.extend(constructor, existingConstructor, {
                version: prototype.version,
                // copy the object used to create the prototype in case we need to
                // redefine the widget later
                _proto: $.extend({}, prototype),
                // track widgets that inherit from this widget in case this widget is
                // redefined after a widget inherits from it
                _childConstructors: []
            });
    
            basePrototype = new base();
            // we need to make the options hash a property directly on the new instance
            // otherwise we'll modify the options hash on the prototype that we're
            // inheriting from
            basePrototype.options = $.widget.extend({}, basePrototype.options);
            $.each(prototype, function(prop, value) {
                if (!$.isFunction(value)) {
                    proxiedPrototype[prop] = value;
                    return;
                }
                proxiedPrototype[prop] = (function() {
                    var _super = function() {
                        return base.prototype[prop].apply(this, arguments);
                    },
                    _superApply = function(args) {
                        return base.prototype[prop].apply(this, args);
                    };
                    return function() {
                        var __super = this._super,
                        __superApply = this._superApply,
                        returnValue;
    
                        this._super = _super;
                        this._superApply = _superApply;
    
                        returnValue = value.apply(this, arguments);
    
                        this._super = __super;
                        this._superApply = __superApply;
    
                        return returnValue;
                    };
                })();
            });
            constructor.prototype = $.widget.extend(basePrototype, {
                // TODO: remove support for widgetEventPrefix
                // always use the name + a colon as the prefix, e.g., draggable:start
                // don't prefix for widgets that aren't DOM-based
                widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
            }, proxiedPrototype, {
                constructor: constructor,
                namespace: namespace,
                widgetName: name,
                widgetFullName: fullName
            });
    
            // If this widget is being redefined then we need to find all widgets that
            // are inheriting from it and redefine all of them so that they inherit from
            // the new version of this widget. We're essentially trying to replace one
            // level in the prototype chain.
            if (existingConstructor) {
                $.each(existingConstructor._childConstructors, function(i, child) {
                    var childPrototype = child.prototype;
    
                    // redefine the child widget using the same prototype that was
                    // originally used, but inherit from the new version of the base
                    $.widget(childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto);
                });
                // remove the list of existing child constructors from the old constructor
                // so the old child constructors can be garbage collected
                delete existingConstructor._childConstructors;
            } else {
                base._childConstructors.push(constructor);
            }
    
            $.widget.bridge(name, constructor);
    
            return constructor;
        };
    
        $.widget.extend = function(target) {
            var input = widget_slice.call(arguments, 1),
            inputIndex = 0,
            inputLength = input.length,
            key,
            value;
            for (; inputIndex < inputLength; inputIndex++) {
                for (key in input[inputIndex]) {
                    value = input[inputIndex][key];
                    if (input[inputIndex].hasOwnProperty(key) && value !== undefined) {
                        // Clone objects
                        if ($.isPlainObject(value)) {
                            target[key] = $.isPlainObject(target[key]) ?
                            $.widget.extend({}, target[key], value) :
                            // Don't extend strings, arrays, etc. with objects
                            $.widget.extend({}, value);
                            // Copy everything else by reference
                        } else {
                            target[key] = value;
                        }
                    }
                }
            }
            return target;
        };
    
        $.widget.bridge = function(name, object) {
            var fullName = object.prototype.widgetFullName || name;
            $.fn[name] = function(options) {
                var isMethodCall = typeof options === "string",
                args = widget_slice.call(arguments, 1),
                returnValue = this;
    
                // allow multiple hashes to be passed on init
                options = !isMethodCall && args.length ?
                $.widget.extend.apply(null, [options].concat(args)) :
                options;
    
                if (isMethodCall) {
                    this.each(function() {
                        var methodValue,
                        instance = $.data(this, fullName);
                        if (options === "instance") {
                            returnValue = instance;
                            return false;
                        }
                        if (!instance) {
                            return $.error("cannot call methods on " + name + " prior to initialization; " +
                            "attempted to call method '" + options + "'");
                        }
                        if (!$.isFunction(instance[options]) || options.charAt(0) === "_") {
                            return $.error("no such method '" + options + "' for " + name + " widget instance");
                        }
                        methodValue = instance[options].apply(instance, args);
                        if (methodValue !== instance && methodValue !== undefined) {
                            returnValue = methodValue && methodValue.jquery ?
                            returnValue.pushStack(methodValue.get()) :
                            methodValue;
                            return false;
                        }
                    });
                } else {
                    this.each(function() {
                        var instance = $.data(this, fullName);
                        if (instance) {
                            instance.option(options || {});
                            if (instance._init) {
                                instance._init();
                            }
                        } else {
                            $.data(this, fullName, new object(options, this));
                        }
                    });
                }
    
                return returnValue;
            };
        };
    
        $.Widget = function( /* options, element */) { };
        $.Widget._childConstructors = [];
    
        $.Widget.prototype = {
            widgetName: "widget",
            widgetEventPrefix: "",
            defaultElement: "<div>",
            options: {
                disabled: false,
    
                // callbacks
                create: null
            },
            _createWidget: function(options, element) {
                element = $(element || this.defaultElement || this)[0];
                this.element = $(element);
                this.uuid = widget_uuid++;
                this.eventNamespace = "." + this.widgetName + this.uuid;
                this.options = $.widget.extend({},
                this.options,
                this._getCreateOptions(),
                options);
    
                this.bindings = $();
                this.hoverable = $();
                this.focusable = $();
    
                if (element !== this) {
                    $.data(element, this.widgetFullName, this);
                    this._on(true, this.element, {
                        remove: function(event) {
                            if (event.target === element) {
                                this.destroy();
                            }
                        }
                    });
                    this.document = $(element.style ?
                    // element within the document
                    element.ownerDocument :
                    // element is window or document
                    element.document || element);
                    this.window = $(this.document[0].defaultView || this.document[0].parentWindow);
                }
    
                this._create();
                this._trigger("create", null, this._getCreateEventData());
                this._init();
            },
            _getCreateOptions: $.noop,
            _getCreateEventData: $.noop,
            _create: $.noop,
            _init: $.noop,
    
            destroy: function() {
                this._destroy();
                // we can probably remove the unbind calls in 2.0
                // all event bindings should go through this._on()
                this.element
                .unbind(this.eventNamespace)
                .removeData(this.widgetFullName)
                // support: jquery <1.6.3
                // http://bugs.jquery.com/ticket/9413
                .removeData($.camelCase(this.widgetFullName));
                this.widget()
                .unbind(this.eventNamespace)
                .removeAttr("aria-disabled")
                .removeClass(
                    this.widgetFullName + "-disabled " +
                    "ui-state-disabled");
    
                // clean up events and states
                this.bindings.unbind(this.eventNamespace);
                this.hoverable.removeClass("ui-state-hover");
                this.focusable.removeClass("ui-state-focus");
            },
            _destroy: $.noop,
    
            widget: function() {
                return this.element;
            },
    
            option: function(key, value) {
                var options = key,
                parts,
                curOption,
                i;
    
                if (arguments.length === 0) {
                    // don't return a reference to the internal hash
                    return $.widget.extend({}, this.options);
                }
    
                if (typeof key === "string") {
                    // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
                    options = {};
                    parts = key.split(".");
                    key = parts.shift();
                    if (parts.length) {
                        curOption = options[key] = $.widget.extend({}, this.options[key]);
                        for (i = 0; i < parts.length - 1; i++) {
                            curOption[parts[i]] = curOption[parts[i]] || {};
                            curOption = curOption[parts[i]];
                        }
                        key = parts.pop();
                        if (arguments.length === 1) {
                            return curOption[key] === undefined ? null : curOption[key];
                        }
                        curOption[key] = value;
                    } else {
                        if (arguments.length === 1) {
                            return this.options[key] === undefined ? null : this.options[key];
                        }
                        options[key] = value;
                    }
                }
    
                this._setOptions(options);
    
                return this;
            },
            _setOptions: function(options) {
                var key;
    
                for (key in options) {
                    this._setOption(key, options[key]);
                }
    
                return this;
            },
            _setOption: function(key, value) {
                this.options[key] = value;
    
                if (key === "disabled") {
                    this.widget()
                    .toggleClass(this.widgetFullName + "-disabled", !!value);
    
                    // If the widget is becoming disabled, then nothing is interactive
                    if (value) {
                        this.hoverable.removeClass("ui-state-hover");
                        this.focusable.removeClass("ui-state-focus");
                    }
                }
    
                return this;
            },
    
            enable: function() {
                return this._setOptions({ disabled: false });
            },
            disable: function() {
                return this._setOptions({ disabled: true });
            },
    
            _on: function(suppressDisabledCheck, element, handlers) {
                var delegateElement,
                instance = this;
    
                // no suppressDisabledCheck flag, shuffle arguments
                if (typeof suppressDisabledCheck !== "boolean") {
                    handlers = element;
                    element = suppressDisabledCheck;
                    suppressDisabledCheck = false;
                }
    
                // no element argument, shuffle and use this.element
                if (!handlers) {
                    handlers = element;
                    element = this.element;
                    delegateElement = this.widget();
                } else {
                    element = delegateElement = $(element);
                    this.bindings = this.bindings.add(element);
                }
    
                $.each(handlers, function(event, handler) {
                    function handlerProxy() {
                        // allow widgets to customize the disabled handling
                        // - disabled as an array instead of boolean
                        // - disabled class as method for disabling individual parts
                        if (!suppressDisabledCheck &&
                            (instance.options.disabled === true ||
                                $(this).hasClass("ui-state-disabled"))) {
                            return;
                        }
                        return (typeof handler === "string" ? instance[handler] : handler)
                        .apply(instance, arguments);
                    }
    
                    // copy the guid so direct unbinding works
                    if (typeof handler !== "string") {
                        handlerProxy.guid = handler.guid =
                        handler.guid || handlerProxy.guid || $.guid++;
                    }
    
                    var match = event.match(/^([w:-]*)s*(.*)$/),
                    eventName = match[1] + instance.eventNamespace,
                    selector = match[2];
                    if (selector) {
                        delegateElement.delegate(selector, eventName, handlerProxy);
                    } else {
                        element.bind(eventName, handlerProxy);
                    }
                });
            },
    
            _off: function(element, eventName) {
                eventName = (eventName || "").split(" ").join(this.eventNamespace + " ") + this.eventNamespace;
                element.unbind(eventName).undelegate(eventName);
            },
    
            _delay: function(handler, delay) {
                function handlerProxy() {
                    return (typeof handler === "string" ? instance[handler] : handler)
                    .apply(instance, arguments);
                }
                var instance = this;
                return setTimeout(handlerProxy, delay || 0);
            },
    
            _hoverable: function(element) {
                this.hoverable = this.hoverable.add(element);
                this._on(element, {
                    mouseenter: function(event) {
                        $(event.currentTarget).addClass("ui-state-hover");
                    },
                    mouseleave: function(event) {
                        $(event.currentTarget).removeClass("ui-state-hover");
                    }
                });
            },
    
            _focusable: function(element) {
                this.focusable = this.focusable.add(element);
                this._on(element, {
                    focusin: function(event) {
                        $(event.currentTarget).addClass("ui-state-focus");
                    },
                    focusout: function(event) {
                        $(event.currentTarget).removeClass("ui-state-focus");
                    }
                });
            },
    
            _trigger: function(type, event, data) {
                var prop, orig,
                callback = this.options[type];
    
                data = data || {};
                event = $.Event(event);
                event.type = (type === this.widgetEventPrefix ?
                type :
                this.widgetEventPrefix + type).toLowerCase();
                // the original event may come from any element
                // so we need to reset the target on the new event
                event.target = this.element[0];
    
                // copy original event properties over to the new event
                orig = event.originalEvent;
                if (orig) {
                    for (prop in orig) {
                        if (!(prop in event)) {
                            event[prop] = orig[prop];
                        }
                    }
                }
    
                this.element.trigger(event, data);
                return !($.isFunction(callback) &&
                callback.apply(this.element[0], [event].concat(data)) === false ||
                event.isDefaultPrevented());
            }
        };
    
        $.each({ show: "fadeIn", hide: "fadeOut" }, function(method, defaultEffect) {
            $.Widget.prototype["_" + method] = function(element, options, callback) {
                if (typeof options === "string") {
                    options = { effect: options };
                }
                var hasOptions,
                effectName = !options ?
                    method :
                    options === true || typeof options === "number" ?
                        defaultEffect :
                        options.effect || defaultEffect;
                options = options || {};
                if (typeof options === "number") {
                    options = { duration: options };
                }
                hasOptions = !$.isEmptyObject(options);
                options.complete = callback;
                if (options.delay) {
                    element.delay(options.delay);
                }
                if (hasOptions && $.effects && $.effects.effect[effectName]) {
                    element[method](options);
                } else if (effectName !== method && element[effectName]) {
                    element[effectName](options.duration, options.easing, callback);
                } else {
                    element.queue(function(next) {
                        $(this)[method]();
                        if (callback) {
                            callback.call(element[0]);
                        }
                        next();
                    });
                }
            };
        });
    
        var widget = $.widget;
    
    
        /*!
        * jQuery UI Position 1.11.0
        * http://jqueryui.com
        *
        * Copyright 2014 jQuery Foundation and other contributors
        * Released under the MIT license.
        * http://jquery.org/license
        *
        * http://api.jqueryui.com/position/
        */
    
        (function() {
    
            $.ui = $.ui || {};
    
            var cachedScrollbarWidth, supportsOffsetFractions,
        max = Math.max,
        abs = Math.abs,
        round = Math.round,
        rhorizontal = /left|center|right/,
        rvertical = /top|center|bottom/,
        roffset = /[+-]d+(.[d]+)?%?/,
        rposition = /^w+/,
        rpercent = /%$/,
        _position = $.fn.position;
    
            function getOffsets(offsets, width, height) {
                return [
            parseFloat(offsets[0]) * (rpercent.test(offsets[0]) ? width / 100 : 1),
            parseFloat(offsets[1]) * (rpercent.test(offsets[1]) ? height / 100 : 1)
        ];
            }
    
            function parseCss(element, property) {
                return parseInt($.css(element, property), 10) || 0;
            }
    
            function getDimensions(elem) {
                var raw = elem[0];
                if (raw.nodeType === 9) {
                    return {
                         elem.width(),
                        height: elem.height(),
                        offset: { top: 0, left: 0 }
                    };
                }
                if ($.isWindow(raw)) {
                    return {
                         elem.width(),
                        height: elem.height(),
                        offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
                    };
                }
                if (raw.preventDefault) {
                    return {
                         0,
                        height: 0,
                        offset: { top: raw.pageY, left: raw.pageX }
                    };
                }
                return {
                     elem.outerWidth(),
                    height: elem.outerHeight(),
                    offset: elem.offset()
                };
            }
    
            $.position = {
                scrollbarWidth: function() {
                    if (cachedScrollbarWidth !== undefined) {
                        return cachedScrollbarWidth;
                    }
                    var w1, w2,
                div = $("<div style='display:block;position:absolute;50px;height:50px;overflow:hidden;'><div style='height:100px;auto;'></div></div>"),
                innerDiv = div.children()[0];
    
                    $("body").append(div);
                    w1 = innerDiv.offsetWidth;
                    div.css("overflow", "scroll");
    
                    w2 = innerDiv.offsetWidth;
    
                    if (w1 === w2) {
                        w2 = div[0].clientWidth;
                    }
    
                    div.remove();
    
                    return (cachedScrollbarWidth = w1 - w2);
                },
                getScrollInfo: function(within) {
                    var overflowX = within.isWindow || within.isDocument ? "" :
                    within.element.css("overflow-x"),
                overflowY = within.isWindow || within.isDocument ? "" :
                    within.element.css("overflow-y"),
                hasOverflowX = overflowX === "scroll" ||
                    (overflowX === "auto" && within.width < within.element[0].scrollWidth),
                hasOverflowY = overflowY === "scroll" ||
                    (overflowY === "auto" && within.height < within.element[0].scrollHeight);
                    return {
                         hasOverflowY ? $.position.scrollbarWidth() : 0,
                        height: hasOverflowX ? $.position.scrollbarWidth() : 0
                    };
                },
                getWithinInfo: function(element) {
                    var withinElement = $(element || window),
                isWindow = $.isWindow(withinElement[0]),
                isDocument = !!withinElement[0] && withinElement[0].nodeType === 9;
                    return {
                        element: withinElement,
                        isWindow: isWindow,
                        isDocument: isDocument,
                        offset: withinElement.offset() || { left: 0, top: 0 },
                        scrollLeft: withinElement.scrollLeft(),
                        scrollTop: withinElement.scrollTop(),
                         isWindow ? withinElement.width() : withinElement.outerWidth(),
                        height: isWindow ? withinElement.height() : withinElement.outerHeight()
                    };
                }
            };
    
            $.fn.position = function(options) {
                if (!options || !options.of) {
                    return _position.apply(this, arguments);
                }
    
                // make a copy, we don't want to modify arguments
                options = $.extend({}, options);
    
                var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
            target = $(options.of),
            within = $.position.getWithinInfo(options.within),
            scrollInfo = $.position.getScrollInfo(within),
            collision = (options.collision || "flip").split(" "),
            offsets = {};
    
                dimensions = getDimensions(target);
                if (target[0].preventDefault) {
                    // force left top to allow flipping
                    options.at = "left top";
                }
                targetWidth = dimensions.width;
                targetHeight = dimensions.height;
                targetOffset = dimensions.offset;
                // clone to reuse original targetOffset later
                basePosition = $.extend({}, targetOffset);
    
                // force my and at to have valid horizontal and vertical positions
                // if a value is missing or invalid, it will be converted to center
                $.each(["my", "at"], function() {
                    var pos = (options[this] || "").split(" "),
                horizontalOffset,
                verticalOffset;
    
                    if (pos.length === 1) {
                        pos = rhorizontal.test(pos[0]) ?
                    pos.concat(["center"]) :
                    rvertical.test(pos[0]) ?
                        ["center"].concat(pos) :
                        ["center", "center"];
                    }
                    pos[0] = rhorizontal.test(pos[0]) ? pos[0] : "center";
                    pos[1] = rvertical.test(pos[1]) ? pos[1] : "center";
    
                    // calculate offsets
                    horizontalOffset = roffset.exec(pos[0]);
                    verticalOffset = roffset.exec(pos[1]);
                    offsets[this] = [
                horizontalOffset ? horizontalOffset[0] : 0,
                verticalOffset ? verticalOffset[0] : 0
            ];
    
                    // reduce to just the positions without the offsets
                    options[this] = [
                rposition.exec(pos[0])[0],
                rposition.exec(pos[1])[0]
            ];
                });
    
                // normalize collision option
                if (collision.length === 1) {
                    collision[1] = collision[0];
                }
    
                if (options.at[0] === "right") {
                    basePosition.left += targetWidth;
                } else if (options.at[0] === "center") {
                    basePosition.left += targetWidth / 2;
                }
    
                if (options.at[1] === "bottom") {
                    basePosition.top += targetHeight;
                } else if (options.at[1] === "center") {
                    basePosition.top += targetHeight / 2;
                }
    
                atOffset = getOffsets(offsets.at, targetWidth, targetHeight);
                basePosition.left += atOffset[0];
                basePosition.top += atOffset[1];
    
                return this.each(function() {
                    var collisionPosition, using,
                elem = $(this),
                elemWidth = elem.outerWidth(),
                elemHeight = elem.outerHeight(),
                marginLeft = parseCss(this, "marginLeft"),
                marginTop = parseCss(this, "marginTop"),
                collisionWidth = elemWidth + marginLeft + parseCss(this, "marginRight") + scrollInfo.width,
                collisionHeight = elemHeight + marginTop + parseCss(this, "marginBottom") + scrollInfo.height,
                position = $.extend({}, basePosition),
                myOffset = getOffsets(offsets.my, elem.outerWidth(), elem.outerHeight());
    
                    if (options.my[0] === "right") {
                        position.left -= elemWidth;
                    } else if (options.my[0] === "center") {
                        position.left -= elemWidth / 2;
                    }
    
                    if (options.my[1] === "bottom") {
                        position.top -= elemHeight;
                    } else if (options.my[1] === "center") {
                        position.top -= elemHeight / 2;
                    }
    
                    position.left += myOffset[0];
                    position.top += myOffset[1];
    
                    // if the browser doesn't support fractions, then round for consistent results
                    if (!supportsOffsetFractions) {
                        position.left = round(position.left);
                        position.top = round(position.top);
                    }
    
                    collisionPosition = {
                        marginLeft: marginLeft,
                        marginTop: marginTop
                    };
    
                    $.each(["left", "top"], function(i, dir) {
                        if ($.ui.position[collision[i]]) {
                            $.ui.position[collision[i]][dir](position, {
                                targetWidth: targetWidth,
                                targetHeight: targetHeight,
                                elemWidth: elemWidth,
                                elemHeight: elemHeight,
                                collisionPosition: collisionPosition,
                                collisionWidth: collisionWidth,
                                collisionHeight: collisionHeight,
                                offset: [atOffset[0] + myOffset[0], atOffset[1] + myOffset[1]],
                                my: options.my,
                                at: options.at,
                                within: within,
                                elem: elem
                            });
                        }
                    });
    
                    if (options.using) {
                        // adds feedback as second argument to using callback, if present
                        using = function(props) {
                            var left = targetOffset.left - position.left,
                        right = left + targetWidth - elemWidth,
                        top = targetOffset.top - position.top,
                        bottom = top + targetHeight - elemHeight,
                        feedback = {
                            target: {
                                element: target,
                                left: targetOffset.left,
                                top: targetOffset.top,
                                 targetWidth,
                                height: targetHeight
                            },
                            element: {
                                element: elem,
                                left: position.left,
                                top: position.top,
                                 elemWidth,
                                height: elemHeight
                            },
                            horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
                            vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
                        };
                            if (targetWidth < elemWidth && abs(left + right) < targetWidth) {
                                feedback.horizontal = "center";
                            }
                            if (targetHeight < elemHeight && abs(top + bottom) < targetHeight) {
                                feedback.vertical = "middle";
                            }
                            if (max(abs(left), abs(right)) > max(abs(top), abs(bottom))) {
                                feedback.important = "horizontal";
                            } else {
                                feedback.important = "vertical";
                            }
                            options.using.call(this, props, feedback);
                        };
                    }
    
                    elem.offset($.extend(position, { using: using }));
                });
            };
    
            $.ui.position = {
                fit: {
                    left: function(position, data) {
                        var within = data.within,
                    withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
                    outerWidth = within.width,
                    collisionPosLeft = position.left - data.collisionPosition.marginLeft,
                    overLeft = withinOffset - collisionPosLeft,
                    overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
                    newOverRight;
    
                        // element is wider than within
                        if (data.collisionWidth > outerWidth) {
                            // element is initially over the left side of within
                            if (overLeft > 0 && overRight <= 0) {
                                newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
                                position.left += overLeft - newOverRight;
                                // element is initially over right side of within
                            } else if (overRight > 0 && overLeft <= 0) {
                                position.left = withinOffset;
                                // element is initially over both left and right sides of within
                            } else {
                                if (overLeft > overRight) {
                                    position.left = withinOffset + outerWidth - data.collisionWidth;
                                } else {
                                    position.left = withinOffset;
                                }
                            }
                            // too far left -> align with left edge
                        } else if (overLeft > 0) {
                            position.left += overLeft;
                            // too far right -> align with right edge
                        } else if (overRight > 0) {
                            position.left -= overRight;
                            // adjust based on position and margin
                        } else {
                            position.left = max(position.left - collisionPosLeft, position.left);
                        }
                    },
                    top: function(position, data) {
                        var within = data.within,
                    withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
                    outerHeight = data.within.height,
                    collisionPosTop = position.top - data.collisionPosition.marginTop,
                    overTop = withinOffset - collisionPosTop,
                    overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
                    newOverBottom;
    
                        // element is taller than within
                        if (data.collisionHeight > outerHeight) {
                            // element is initially over the top of within
                            if (overTop > 0 && overBottom <= 0) {
                                newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
                                position.top += overTop - newOverBottom;
                                // element is initially over bottom of within
                            } else if (overBottom > 0 && overTop <= 0) {
                                position.top = withinOffset;
                                // element is initially over both top and bottom of within
                            } else {
                                if (overTop > overBottom) {
                                    position.top = withinOffset + outerHeight - data.collisionHeight;
                                } else {
                                    position.top = withinOffset;
                                }
                            }
                            // too far up -> align with top
                        } else if (overTop > 0) {
                            position.top += overTop;
                            // too far down -> align with bottom edge
                        } else if (overBottom > 0) {
                            position.top -= overBottom;
                            // adjust based on position and margin
                        } else {
                            position.top = max(position.top - collisionPosTop, position.top);
                        }
                    }
                },
                flip: {
                    left: function(position, data) {
                        var within = data.within,
                    withinOffset = within.offset.left + within.scrollLeft,
                    outerWidth = within.width,
                    offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
                    collisionPosLeft = position.left - data.collisionPosition.marginLeft,
                    overLeft = collisionPosLeft - offsetLeft,
                    overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
                    myOffset = data.my[0] === "left" ?
                        -data.elemWidth :
                        data.my[0] === "right" ?
                            data.elemWidth :
                            0,
                    atOffset = data.at[0] === "left" ?
                        data.targetWidth :
                        data.at[0] === "right" ?
                            -data.targetWidth :
                            0,
                    offset = -2 * data.offset[0],
                    newOverRight,
                    newOverLeft;
    
                        if (overLeft < 0) {
                            newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
                            if (newOverRight < 0 || newOverRight < abs(overLeft)) {
                                position.left += myOffset + atOffset + offset;
                            }
                        } else if (overRight > 0) {
                            newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
                            if (newOverLeft > 0 || abs(newOverLeft) < overRight) {
                                position.left += myOffset + atOffset + offset;
                            }
                        }
                    },
                    top: function(position, data) {
                        var within = data.within,
                    withinOffset = within.offset.top + within.scrollTop,
                    outerHeight = within.height,
                    offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
                    collisionPosTop = position.top - data.collisionPosition.marginTop,
                    overTop = collisionPosTop - offsetTop,
                    overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
                    top = data.my[1] === "top",
                    myOffset = top ?
                        -data.elemHeight :
                        data.my[1] === "bottom" ?
                            data.elemHeight :
                            0,
                    atOffset = data.at[1] === "top" ?
                        data.targetHeight :
                        data.at[1] === "bottom" ?
                            -data.targetHeight :
                            0,
                    offset = -2 * data.offset[1],
                    newOverTop,
                    newOverBottom;
                        if (overTop < 0) {
                            newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
                            if ((position.top + myOffset + atOffset + offset) > overTop && (newOverBottom < 0 || newOverBottom < abs(overTop))) {
                                position.top += myOffset + atOffset + offset;
                            }
                        } else if (overBottom > 0) {
                            newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
                            if ((position.top + myOffset + atOffset + offset) > overBottom && (newOverTop > 0 || abs(newOverTop) < overBottom)) {
                                position.top += myOffset + atOffset + offset;
                            }
                        }
                    }
                },
                flipfit: {
                    left: function() {
                        $.ui.position.flip.left.apply(this, arguments);
                        $.ui.position.fit.left.apply(this, arguments);
                    },
                    top: function() {
                        $.ui.position.flip.top.apply(this, arguments);
                        $.ui.position.fit.top.apply(this, arguments);
                    }
                }
            };
    
            // fraction support test
            (function() {
                var testElement, testElementParent, testElementStyle, offsetLeft, i,
            body = document.getElementsByTagName("body")[0],
            div = document.createElement("div");
    
                //Create a "fake body" for testing based on method used in jQuery.support
                testElement = document.createElement(body ? "div" : "body");
                testElementStyle = {
                    visibility: "hidden",
                     0,
                    height: 0,
                    border: 0,
                    margin: 0,
                    background: "none"
                };
                if (body) {
                    $.extend(testElementStyle, {
                        position: "absolute",
                        left: "-1000px",
                        top: "-1000px"
                    });
                }
                for (i in testElementStyle) {
                    testElement.style[i] = testElementStyle[i];
                }
                testElement.appendChild(div);
                testElementParent = body || document.documentElement;
                testElementParent.insertBefore(testElement, testElementParent.firstChild);
    
                div.style.cssText = "position: absolute; left: 10.7432222px;";
    
                offsetLeft = $(div).offset().left;
                supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
    
                testElement.innerHTML = "";
                testElementParent.removeChild(testElement);
            })();
    
        })();
    
        var position = $.ui.position;
    
    
        /*!
        * jQuery UI Menu 1.11.0
        * http://jqueryui.com
        *
        * Copyright 2014 jQuery Foundation and other contributors
        * Released under the MIT license.
        * http://jquery.org/license
        *
        * http://api.jqueryui.com/menu/
        */
    
    
        var menu = $.widget("ui.menu", {
            version: "1.11.0",
            defaultElement: "<ul>",
            delay: 300,
            options: {
                icons: {
                    submenu: "ui-icon-carat-1-e"
                },
                items: "> *",
                menus: "ul",
                position: {
                    my: "left-1 top",
                    at: "right top"
                },
                role: "menu",
    
                // callbacks
                blur: null,
                focus: null,
                select: null
            },
    
            _create: function() {
                this.activeMenu = this.element;
    
                // Flag used to prevent firing of the click handler
                // as the event bubbles up through nested menus
                this.mouseHandled = false;
                this.element
                .uniqueId()
                .addClass("ui-menu ui-widget ui-widget-content")
                .toggleClass("ui-menu-icons", !!this.element.find(".ui-icon").length)
                .attr({
                    role: this.options.role,
                    tabIndex: 0
                });
    
                if (this.options.disabled) {
                    this.element
                    .addClass("ui-state-disabled")
                    .attr("aria-disabled", "true");
                }
    
                this._on({
                    // Prevent focus from sticking to links inside menu after clicking
                    // them (focus should always stay on UL during navigation).
                    "mousedown .ui-menu-item": function(event) {
                        event.preventDefault();
                    },
                    "click .ui-menu-item": function(event) {
                        var target = $(event.target);
                        if (!this.mouseHandled && target.not(".ui-state-disabled").length) {
                            this.select(event);
    
                            // Only set the mouseHandled flag if the event will bubble, see #9469.
                            if (!event.isPropagationStopped()) {
                                this.mouseHandled = true;
                            }
    
                            // Open submenu on click
                            if (target.has(".ui-menu").length) {
                                this.expand(event);
                            } else if (!this.element.is(":focus") && $(this.document[0].activeElement).closest(".ui-menu").length) {
    
                                // Redirect focus to the menu
                                this.element.trigger("focus", [true]);
    
                                // If the active item is on the top level, let it stay active.
                                // Otherwise, blur the active item since it is no longer visible.
                                if (this.active && this.active.parents(".ui-menu").length === 1) {
                                    clearTimeout(this.timer);
                                }
                            }
                        }
                    },
                    "mouseenter .ui-menu-item": function(event) {
                        var target = $(event.currentTarget);
                        // Remove ui-state-active class from siblings of the newly focused menu item
                        // to avoid a jump caused by adjacent elements both having a class with a border
                        target.siblings(".ui-state-active").removeClass("ui-state-active");
                        this.focus(event, target);
                    },
                    mouseleave: "collapseAll",
                    "mouseleave .ui-menu": "collapseAll",
                    focus: function(event, keepActiveItem) {
                        // If there's already an active item, keep it active
                        // If not, activate the first item
                        var item = this.active || this.element.find(this.options.items).eq(0);
    
                        if (!keepActiveItem) {
                            this.focus(event, item);
                        }
                    },
                    blur: function(event) {
                        this._delay(function() {
                            if (!$.contains(this.element[0], this.document[0].activeElement)) {
                                this.collapseAll(event);
                            }
                        });
                    },
                    keydown: "_keydown"
                });
    
                this.refresh();
    
                // Clicks outside of a menu collapse any open menus
                this._on(this.document, {
                    click: function(event) {
                        if (this._closeOnDocumentClick(event)) {
                            this.collapseAll(event);
                        }
    
                        // Reset the mouseHandled flag
                        this.mouseHandled = false;
                    }
                });
            },
    
            _destroy: function() {
                // Destroy (sub)menus
                this.element
                .removeAttr("aria-activedescendant")
                .find(".ui-menu").addBack()
                    .removeClass("ui-menu ui-widget ui-widget-content ui-menu-icons ui-front")
                    .removeAttr("role")
                    .removeAttr("tabIndex")
                    .removeAttr("aria-labelledby")
                    .removeAttr("aria-expanded")
                    .removeAttr("aria-hidden")
                    .removeAttr("aria-disabled")
                    .removeUniqueId()
                    .show();
    
                // Destroy menu items
                this.element.find(".ui-menu-item")
                .removeClass("ui-menu-item")
                .removeAttr("role")
                .removeAttr("aria-disabled")
                .removeUniqueId()
                .removeClass("ui-state-hover")
                .removeAttr("tabIndex")
                .removeAttr("role")
                .removeAttr("aria-haspopup")
                .children().each(function() {
                    var elem = $(this);
                    if (elem.data("ui-menu-submenu-carat")) {
                        elem.remove();
                    }
                });
    
                // Destroy menu dividers
                this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content");
            },
    
            _keydown: function(event) {
                var match, prev, character, skip, regex,
                preventDefault = true;
    
                function escape(value) {
                    return value.replace(/[-[]{}()*+?.,\^$|#s]/g, "\$&");
                }
    
                switch (event.keyCode) {
                    case $.ui.keyCode.PAGE_UP:
                        this.previousPage(event);
                        break;
                    case $.ui.keyCode.PAGE_DOWN:
                        this.nextPage(event);
                        break;
                    case $.ui.keyCode.HOME:
                        this._move("first", "first", event);
                        break;
                    case $.ui.keyCode.END:
                        this._move("last", "last", event);
                        break;
                    case $.ui.keyCode.UP:
                        this.previous(event);
                        break;
                    case $.ui.keyCode.DOWN:
                        this.next(event);
                        break;
                    case $.ui.keyCode.LEFT:
                        this.collapse(event);
                        break;
                    case $.ui.keyCode.RIGHT:
                        if (this.active && !this.active.is(".ui-state-disabled")) {
                            this.expand(event);
                        }
                        break;
                    case $.ui.keyCode.ENTER:
                    case $.ui.keyCode.SPACE:
                        this._activate(event);
                        break;
                    case $.ui.keyCode.ESCAPE:
                        this.collapse(event);
                        break;
                    default:
                        preventDefault = false;
                        prev = this.previousFilter || "";
                        character = String.fromCharCode(event.keyCode);
                        skip = false;
    
                        clearTimeout(this.filterTimer);
    
                        if (character === prev) {
                            skip = true;
                        } else {
                            character = prev + character;
                        }
    
                        regex = new RegExp("^" + escape(character), "i");
                        match = this.activeMenu.find(this.options.items).filter(function() {
                            return regex.test($(this).text());
                        });
                        match = skip && match.index(this.active.next()) !== -1 ?
                    this.active.nextAll(".ui-menu-item") :
                    match;
    
                        // If no matches on the current filter, reset to the last character pressed
                        // to move down the menu to the first item that starts with that character
                        if (!match.length) {
                            character = String.fromCharCode(event.keyCode);
                            regex = new RegExp("^" + escape(character), "i");
                            match = this.activeMenu.find(this.options.items).filter(function() {
                                return regex.test($(this).text());
                            });
                        }
    
                        if (match.length) {
                            this.focus(event, match);
                            if (match.length > 1) {
                                this.previousFilter = character;
                                this.filterTimer = this._delay(function() {
                                    delete this.previousFilter;
                                }, 1000);
                            } else {
                                delete this.previousFilter;
                            }
                        } else {
                            delete this.previousFilter;
                        }
                }
    
                if (preventDefault) {
                    event.preventDefault();
                }
            },
    
            _activate: function(event) {
                if (!this.active.is(".ui-state-disabled")) {
                    if (this.active.is("[aria-haspopup='true']")) {
                        this.expand(event);
                    } else {
                        this.select(event);
                    }
                }
            },
    
            refresh: function() {
                var menus, items,
                that = this,
                icon = this.options.icons.submenu,
                submenus = this.element.find(this.options.menus);
    
                this.element.toggleClass("ui-menu-icons", !!this.element.find(".ui-icon").length);
    
                // Initialize nested menus
                submenus.filter(":not(.ui-menu)")
                .addClass("ui-menu ui-widget ui-widget-content ui-front")
                .hide()
                .attr({
                    role: this.options.role,
                    "aria-hidden": "true",
                    "aria-expanded": "false"
                })
                .each(function() {
                    var menu = $(this),
                        item = menu.parent(),
                        submenuCarat = $("<span>")
                            .addClass("ui-menu-icon ui-icon " + icon)
                            .data("ui-menu-submenu-carat", true);
    
                    item
                        .attr("aria-haspopup", "true")
                        .prepend(submenuCarat);
                    menu.attr("aria-labelledby", item.attr("id"));
                });
    
                menus = submenus.add(this.element);
                items = menus.find(this.options.items);
    
                // Initialize menu-items containing spaces and/or dashes only as dividers
                items.not(".ui-menu-item").each(function() {
                    var item = $(this);
                    if (that._isDivider(item)) {
                        item.addClass("ui-widget-content ui-menu-divider");
                    }
                });
    
                // Don't refresh list items that are already adapted
                items.not(".ui-menu-item, .ui-menu-divider")
                .addClass("ui-menu-item")
                .uniqueId()
                .attr({
                    tabIndex: -1,
                    role: this._itemRole()
                });
    
                // Add aria-disabled attribute to any disabled menu item
                items.filter(".ui-state-disabled").attr("aria-disabled", "true");
    
                // If the active item has been removed, blur the menu
                if (this.active && !$.contains(this.element[0], this.active[0])) {
                    this.blur();
                }
            },
    
            _itemRole: function() {
                return {
                    menu: "menuitem",
                    listbox: "option"
    }[this.options.role];
                },
    
                _setOption: function(key, value) {
                    if (key === "icons") {
                        this.element.find(".ui-menu-icon")
                    .removeClass(this.options.icons.submenu)
                    .addClass(value.submenu);
                    }
                    if (key === "disabled") {
                        this.element
                    .toggleClass("ui-state-disabled", !!value)
                    .attr("aria-disabled", value);
                    }
                    this._super(key, value);
                },
    
                focus: function(event, item) {
                    var nested, focused;
                    this.blur(event, event && event.type === "focus");
    
                    this._scrollIntoView(item);
    
                    this.active = item.first();
                    focused = this.active.addClass("ui-state-focus").removeClass("ui-state-active");
                    // Only update aria-activedescendant if there's a role
                    // otherwise we assume focus is managed elsewhere
                    if (this.options.role) {
                        this.element.attr("aria-activedescendant", focused.attr("id"));
                    }
    
                    // Highlight active parent menu item, if any
                    this.active
                .parent()
                .closest(".ui-menu-item")
                .addClass("ui-state-active");
    
                    if (event && event.type === "keydown") {
                        this._close();
                    } else {
                        this.timer = this._delay(function() {
                            this._close();
                        }, this.delay);
                    }
    
                    nested = item.children(".ui-menu");
                    if (nested.length && event && (/^mouse/.test(event.type))) {
                        this._startOpening(nested);
                    }
                    this.activeMenu = item.parent();
    
                    this._trigger("focus", event, { item: item });
                },
    
                _scrollIntoView: function(item) {
                    var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
                    if (this._hasScroll()) {
                        borderTop = parseFloat($.css(this.activeMenu[0], "borderTopWidth")) || 0;
                        paddingTop = parseFloat($.css(this.activeMenu[0], "paddingTop")) || 0;
                        offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
                        scroll = this.activeMenu.scrollTop();
                        elementHeight = this.activeMenu.height();
                        itemHeight = item.outerHeight();
    
                        if (offset < 0) {
                            this.activeMenu.scrollTop(scroll + offset);
                        } else if (offset + itemHeight > elementHeight) {
                            this.activeMenu.scrollTop(scroll + offset - elementHeight + itemHeight);
                        }
                    }
                },
    
                blur: function(event, fromFocus) {
                    if (!fromFocus) {
                        clearTimeout(this.timer);
                    }
    
                    if (!this.active) {
                        return;
                    }
    
                    this.active.removeClass("ui-state-focus");
                    this.active = null;
    
                    this._trigger("blur", event, { item: this.active });
                },
    
                _startOpening: function(submenu) {
                    clearTimeout(this.timer);
    
                    // Don't open if already open fixes a Firefox bug that caused a .5 pixel
                    // shift in the submenu position when mousing over the carat icon
                    if (submenu.attr("aria-hidden") !== "true") {
                        return;
                    }
    
                    this.timer = this._delay(function() {
                        this._close();
                        this._open(submenu);
                    }, this.delay);
                },
    
                _open: function(submenu) {
                    var position = $.extend({
                        of: this.active
                    }, this.options.position);
    
                    clearTimeout(this.timer);
                    this.element.find(".ui-menu").not(submenu.parents(".ui-menu"))
                .hide()
                .attr("aria-hidden", "true");
    
                    submenu
                .show()
                .removeAttr("aria-hidden")
                .attr("aria-expanded", "true")
                .position(position);
                },
    
                collapseAll: function(event, all) {
                    clearTimeout(this.timer);
                    this.timer = this._delay(function() {
                        // If we were passed an event, look for the submenu that contains the event
                        var currentMenu = all ? this.element :
                    $(event && event.target).closest(this.element.find(".ui-menu"));
    
                        // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
                        if (!currentMenu.length) {
                            currentMenu = this.element;
                        }
    
                        this._close(currentMenu);
    
                        this.blur(event);
                        this.activeMenu = currentMenu;
                    }, this.delay);
                },
    
                // With no arguments, closes the currently active menu - if nothing is active
                // it closes all menus.  If passed an argument, it will search for menus BELOW
                _close: function(startMenu) {
                    if (!startMenu) {
                        startMenu = this.active ? this.active.parent() : this.element;
                    }
    
                    startMenu
                .find(".ui-menu")
                    .hide()
                    .attr("aria-hidden", "true")
                    .attr("aria-expanded", "false")
                .end()
                .find(".ui-state-active").not(".ui-state-focus")
                    .removeClass("ui-state-active");
                },
    
                _closeOnDocumentClick: function(event) {
                    return !$(event.target).closest(".ui-menu").length;
                },
    
                _isDivider: function(item) {
    
                    // Match hyphen, em dash, en dash
                    return !/[^-u2014u2013s]/.test(item.text());
                },
    
                collapse: function(event) {
                    var newItem = this.active &&
                this.active.parent().closest(".ui-menu-item", this.element);
                    if (newItem && newItem.length) {
                        this._close();
                        this.focus(event, newItem);
                    }
                },
    
                expand: function(event) {
                    var newItem = this.active &&
                this.active
                    .children(".ui-menu ")
                    .find(this.options.items)
                    .first();
    
                    if (newItem && newItem.length) {
                        this._open(newItem.parent());
    
                        // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
                        this._delay(function() {
                            this.focus(event, newItem);
                        });
                    }
                },
    
                next: function(event) {
                    this._move("next", "first", event);
                },
    
                previous: function(event) {
                    this._move("prev", "last", event);
                },
    
                isFirstItem: function() {
                    return this.active && !this.active.prevAll(".ui-menu-item").length;
                },
    
                isLastItem: function() {
                    return this.active && !this.active.nextAll(".ui-menu-item").length;
                },
    
                _move: function(direction, filter, event) {
                    var next;
                    if (this.active) {
                        if (direction === "first" || direction === "last") {
                            next = this.active
                        [direction === "first" ? "prevAll" : "nextAll"](".ui-menu-item")
                        .eq(-1);
                        } else {
                            next = this.active
                        [direction + "All"](".ui-menu-item")
                        .eq(0);
                        }
                    }
                    if (!next || !next.length || !this.active) {
                        next = this.activeMenu.find(this.options.items)[filter]();
                    }
    
                    this.focus(event, next);
                },
    
                nextPage: function(event) {
                    var item, base, height;
    
                    if (!this.active) {
                        this.next(event);
                        return;
                    }
                    if (this.isLastItem()) {
                        return;
                    }
                    if (this._hasScroll()) {
                        base = this.active.offset().top;
                        height = this.element.height();
                        this.active.nextAll(".ui-menu-item").each(function() {
                            item = $(this);
                            return item.offset().top - base - height < 0;
                        });
    
                        this.focus(event, item);
                    } else {
                        this.focus(event, this.activeMenu.find(this.options.items)
                    [!this.active ? "first" : "last"]());
                    }
                },
    
                previousPage: function(event) {
                    var item, base, height;
                    if (!this.active) {
                        this.next(event);
                        return;
                    }
                    if (this.isFirstItem()) {
                        return;
                    }
                    if (this._hasScroll()) {
                        base = this.active.offset().top;
                        height = this.element.height();
                        this.active.prevAll(".ui-menu-item").each(function() {
                            item = $(this);
                            return item.offset().top - base + height > 0;
                        });
    
                        this.focus(event, item);
                    } else {
                        this.focus(event, this.activeMenu.find(this.options.items).first());
                    }
                },
    
                _hasScroll: function() {
                    return this.element.outerHeight() < this.element.prop("scrollHeight");
                },
    
                select: function(event) {
                    // TODO: It should never be possible to not have an active item at this
                    // point, but the tests don't trigger mouseenter before click.
                    this.active = this.active || $(event.target).closest(".ui-menu-item");
                    var ui = { item: this.active };
                    if (!this.active.has(".ui-menu").length) {
                        this.collapseAll(event, true);
                    }
                    this._trigger("select", event, ui);
                }
            });
    
    
            /*!
            * jQuery UI Autocomplete 1.11.0
            * http://jqueryui.com
            *
            * Copyright 2014 jQuery Foundation and other contributors
            * Released under the MIT license.
            * http://jquery.org/license
            *
            * http://api.jqueryui.com/autocomplete/
            */
    
    
            $.widget("ui.autocomplete", {
                version: "1.11.0",
                defaultElement: "<input>",
                options: {
                    appendTo: null,
                    autoFocus: false,
                    delay: 300,
                    minLength: 1,
                    position: {
                        my: "left top",
                        at: "left bottom",
                        collision: "none"
                    },
                    source: null,
    
                    // callbacks
                    change: null,
                    close: null,
                    focus: null,
                    open: null,
                    response: null,
                    search: null,
                    select: null,
                    //all,label,value
                    matchType: 'all'
                },
    
                requestIndex: 0,
                pending: 0,
    
                _create: function() {
                    // Some browsers only repeat keydown events, not keypress events,
                    // so we use the suppressKeyPress flag to determine if we've already
                    // handled the keydown event. #7269
                    // Unfortunately the code for & in keypress is the same as the up arrow,
                    // so we use the suppressKeyPressRepeat flag to avoid handling keypress
                    // events when we know the keydown event was used to modify the
                    // search term. #7799
                    var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
                nodeName = this.element[0].nodeName.toLowerCase(),
                isTextarea = nodeName === "textarea",
                isInput = nodeName === "input";
    
                    this.isMultiLine =
                    // Textareas are always multi-line
                isTextarea ? true :
                    // Inputs are always single-line, even if inside a contentEditable element
                    // IE also treats inputs as contentEditable
                isInput ? false :
                    // All other element types are determined by whether or not they're contentEditable
                this.element.prop("isContentEditable");
    
                    this.valueMethod = this.element[isTextarea || isInput ? "val" : "text"];
                    this.isNewMenu = true;
    
                    this.element
                .addClass("ui-autocomplete-input")
                .attr("autocomplete", "off");
    
                    this._on(this.element, {
                        keydown: function(event) {
                            if (this.element.prop("readOnly")) {
                                suppressKeyPress = true;
                                suppressInput = true;
                                suppressKeyPressRepeat = true;
                                return;
                            }
    
                            suppressKeyPress = false;
                            suppressInput = false;
                            suppressKeyPressRepeat = false;
                            var keyCode = $.ui.keyCode;
                            switch (event.keyCode) {
                                case keyCode.PAGE_UP:
                                    suppressKeyPress = true;
                                    this._move("previousPage", event);
                                    break;
                                case keyCode.PAGE_DOWN:
                                    suppressKeyPress = true;
                                    this._move("nextPage", event);
                                    break;
                                case keyCode.UP:
                                    suppressKeyPress = true;
                                    this._keyEvent("previous", event);
                                    break;
                                case keyCode.DOWN:
                                    suppressKeyPress = true;
                                    this._keyEvent("next", event);
                                    break;
                                case keyCode.ENTER:
                                    // when menu is open and has focus
                                    if (this.menu.active) {
                                        // #6055 - Opera still allows the keypress to occur
                                        // which causes forms to submit
                                        suppressKeyPress = true;
                                        event.preventDefault();
                                        this.menu.select(event);
                                    }
                                    break;
                                case keyCode.TAB:
                                    if (this.menu.active) {
                                        this.menu.select(event);
                                    }
                                    break;
                                case keyCode.ESCAPE:
                                    if (this.menu.element.is(":visible")) {
                                        this._value(this.term);
                                        this.close(event);
                                        // Different browsers have different default behavior for escape
                                        // Single press can mean undo or clear
                                        // Double press in IE means clear the whole form
                                        event.preventDefault();
                                    }
                                    break;
                                default:
                                    suppressKeyPressRepeat = true;
                                    // search timeout should be triggered before the input value is changed
                                    this._searchTimeout(event);
                                    break;
                            }
                        },
                        keypress: function(event) {
                            if (suppressKeyPress) {
                                suppressKeyPress = false;
                                if (!this.isMultiLine || this.menu.element.is(":visible")) {
                                    event.preventDefault();
                                }
                                return;
                            }
                            if (suppressKeyPressRepeat) {
                                return;
                            }
    
                            // replicate some key handlers to allow them to repeat in Firefox and Opera
                            var keyCode = $.ui.keyCode;
                            switch (event.keyCode) {
                                case keyCode.PAGE_UP:
                                    this._move("previousPage", event);
                                    break;
                                case keyCode.PAGE_DOWN:
                                    this._move("nextPage", event);
                                    break;
                                case keyCode.UP:
                                    this._keyEvent("previous", event);
                                    break;
                                case keyCode.DOWN:
                                    this._keyEvent("next", event);
                                    break;
                            }
                        },
                        input: function(event) {
                            if (suppressInput) {
                                suppressInput = false;
                                event.preventDefault();
                                return;
                            }
                            this._searchTimeout(event);
                        },
                        focus: function() {
                            this.selectedItem = null;
                            this.previous = this._value();
                        },
                        blur: function(event) {
                            if (this.cancelBlur) {
                                delete this.cancelBlur;
                                return;
                            }
    
                            clearTimeout(this.searching);
                            this.close(event);
                            this._change(event);
                        }
                    });
    
                    this._initSource();
                    this.menu = $("<ul>")
                .addClass("ui-autocomplete ui-front")
                .appendTo(this._appendTo())
                .menu({
                    // disable ARIA support, the live region takes care of that
                    role: null
                })
                .hide()
                .menu("instance");
    
                    this._on(this.menu.element, {
                        mousedown: function(event) {
                            // prevent moving focus out of the text field
                            event.preventDefault();
    
                            // IE doesn't prevent moving focus even with event.preventDefault()
                            // so we set a flag to know when we should ignore the blur event
                            this.cancelBlur = true;
                            this._delay(function() {
                                delete this.cancelBlur;
                            });
    
                            // clicking on the scrollbar causes focus to shift to the body
                            // but we can't detect a mouseup or a click immediately afterward
                            // so we have to track the next mousedown and close the menu if
                            // the user clicks somewhere outside of the autocomplete
                            var menuElement = this.menu.element[0];
                            if (!$(event.target).closest(".ui-menu-item").length) {
                                this._delay(function() {
                                    var that = this;
                                    this.document.one("mousedown", function(event) {
                                        if (event.target !== that.element[0] &&
                                        event.target !== menuElement &&
                                        !$.contains(menuElement, event.target)) {
                                            that.close();
                                        }
                                    });
                                });
                            }
                        },
                        menufocus: function(event, ui) {
                            var label, item;
                            // support: Firefox
                            // Prevent accidental activation of menu items in Firefox (#7024 #9118)
                            if (this.isNewMenu) {
                                this.isNewMenu = false;
                                if (event.originalEvent && /^mouse/.test(event.originalEvent.type)) {
                                    this.menu.blur();
    
                                    this.document.one("mousemove", function() {
                                        $(event.target).trigger(event.originalEvent);
                                    });
    
                                    return;
                                }
                            }
    
                            item = ui.item.data("ui-autocomplete-item");
                            if (false !== this._trigger("focus", event, { item: item })) {
                                // use value to match what will end up in the input, if it was a key event
                                if (event.originalEvent && /^key/.test(event.originalEvent.type)) {
                                    this._value(item.value);
                                }
                            }
    
                            // Announce the value in the liveRegion
                            label = ui.item.attr("aria-label") || item.value;
                            if (label && jQuery.trim(label).length) {
                                this.liveRegion.children().hide();
                                $("<div>").text(label).appendTo(this.liveRegion);
                            }
                        },
                        menuselect: function(event, ui) {
                            var item = ui.item.data("ui-autocomplete-item"),
                        previous = this.previous;
    
                            // only trigger when focus was lost (click on menu)
                            if (this.element[0] !== this.document[0].activeElement) {
                                this.element.focus();
                                this.previous = previous;
                                // #6109 - IE triggers two focus events and the second
                                // is asynchronous, so we need to reset the previous
                                // term synchronously and asynchronously :-(
                                this._delay(function() {
                                    this.previous = previous;
                                    this.selectedItem = item;
                                });
                            }
    
                            if (false !== this._trigger("select", event, { item: item })) {
                                this._value(item.value);
                            }
                            // reset the term after the select event
                            // this allows custom select handling to work properly
                            this.term = this._value();
    
                            this.close(event);
                            this.selectedItem = item;
                        }
                    });
    
                    this.liveRegion = $("<span>", {
                        role: "status",
                        "aria-live": "assertive",
                        "aria-relevant": "additions"
                    })
                .addClass("ui-helper-hidden-accessible")
                .appendTo(this.document[0].body);
    
                    // turning off autocomplete prevents the browser from remembering the
                    // value when navigating through history, so we re-enable autocomplete
                    // if the page is unloaded before the widget is destroyed. #7790
                    this._on(this.window, {
                        beforeunload: function() {
                            this.element.removeAttr("autocomplete");
                        }
                    });
                },
    
                _destroy: function() {
                    clearTimeout(this.searching);
                    this.element
                .removeClass("ui-autocomplete-input")
                .removeAttr("autocomplete");
                    this.menu.element.remove();
                    this.liveRegion.remove();
                },
    
                _setOption: function(key, value) {
                    this._super(key, value);
                    if (key === "source") {
                        this._initSource();
                    }
                    if (key === "appendTo") {
                        this.menu.element.appendTo(this._appendTo());
                    }
                    if (key === "disabled" && value && this.xhr) {
                        this.xhr.abort();
                    }
                },
    
                _appendTo: function() {
                    var element = this.options.appendTo;
    
                    if (element) {
                        element = element.jquery || element.nodeType ?
                    $(element) :
                    this.document.find(element).eq(0);
                    }
    
                    if (!element || !element[0]) {
                        element = this.element.closest(".ui-front");
                    }
    
                    if (!element.length) {
                        element = this.document[0].body;
                    }
    
                    return element;
                },
    
                _initSource: function() {
                    var array, url, type
                    that = this;
                    if ($.isArray(this.options.source)) {
                        array = this.options.source;
                        type = this.options.matchType;
                        this.source = function(request, response) {
                        response($.ui.autocomplete.filter(array, request.term, type));
                        };
                    } else if (typeof this.options.source === "string") {
                        url = this.options.source;
                        this.source = function(request, response) {
                            if (that.xhr) {
                                that.xhr.abort();
                            }
                            that.xhr = $.ajax({
                                url: url,
                                data: request,
                                dataType: "json",
                                success: function(data) {
                                    response(data);
                                },
                                error: function() {
                                    response([]);
                                }
                            });
                        };
                    } else {
                        this.source = this.options.source;
                    }
                },
    
                _searchTimeout: function(event) {
                    clearTimeout(this.searching);
                    this.searching = this._delay(function() {
    
                        // Search if the value has changed, or if the user retypes the same value (see #7434)
                        var equalValues = this.term === this._value(),
                    menuVisible = this.menu.element.is(":visible"),
                    modifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;
    
                        if (!equalValues || (equalValues && !menuVisible && !modifierKey)) {
                            this.selectedItem = null;
                            this.search(null, event);
                        }
                    }, this.options.delay);
                },
    
                search: function(value, event) {
                    value = value != null ? value : this._value();
    
                    // always save the actual value, not the one passed as an argument
                    this.term = this._value();
    
                    if (value.length < this.options.minLength) {
                        return this.close(event);
                    }
    
                    if (this._trigger("search", event) === false) {
                        return;
                    }
    
                    return this._search(value);
                },
    
                _search: function(value) {
                    this.pending++;
                    this.element.addClass("ui-autocomplete-loading");
                    this.cancelSearch = false;
    
                    this.source({ term: value }, this._response());
                },
    
                _response: function() {
                    var index = ++this.requestIndex;
    
                    return $.proxy(function(content) {
                        if (index === this.requestIndex) {
                            this.__response(content);
                        }
    
                        this.pending--;
                        if (!this.pending) {
                            this.element.removeClass("ui-autocomplete-loading");
                        }
                    }, this);
                },
    
                __response: function(content) {
                    if (content) {
                        content = this._normalize(content);
                    }
                    this._trigger("response", null, { content: content });
                    if (!this.options.disabled && content && content.length && !this.cancelSearch) {
                        this._suggest(content);
                        this._trigger("open");
                    } else {
                        // use ._close() instead of .close() so we don't cancel future searches
                        this._close();
                    }
                },
    
                close: function(event) {
                    this.cancelSearch = true;
                    this._close(event);
                },
    
                _close: function(event) {
                    if (this.menu.element.is(":visible")) {
                        this.menu.element.hide();
                        this.menu.blur();
                        this.isNewMenu = true;
                        this._trigger("close", event);
                    }
                },
    
                _change: function(event) {
                    if (this.previous !== this._value()) {
                        this._trigger("change", event, { item: this.selectedItem });
                    }
                },
    
                _normalize: function(items) {
                    // assume all items have the right format when the first item is complete
                    if (items.length && items[0].label && items[0].value) {
                        return items;
                    }
                    return $.map(items, function(item) {
                        if (typeof item === "string") {
                            return {
                                label: item,
                                value: item
                            };
                        }
                        return $.extend({}, item, {
                            label: item.label || item.value,
                            value: item.value || item.label
                        });
                    });
                },
    
                _suggest: function(items) {
                    var ul = this.menu.element.empty();
                    this._renderMenu(ul, items);
                    this.isNewMenu = true;
                    this.menu.refresh();
    
                    // size and position menu
                    ul.show();
                    this._resizeMenu();
                    ul.position($.extend({
                        of: this.element
                    }, this.options.position));
    
                    if (this.options.autoFocus) {
                        this.menu.next();
                    }
                },
    
                _resizeMenu: function() {
                    var ul = this.menu.element;
                    ul.outerWidth(Math.max(
                    // Firefox wraps long text (possibly a rounding bug)
                    // so we add 1px to avoid the wrapping (#7513)
                ul.width("").outerWidth() + 1,
                this.element.outerWidth()
            ));
                },
    
                _renderMenu: function(ul, items) {
                    var that = this;
                    $.each(items, function(index, item) {
                        that._renderItemData(ul, item);
                    });
                },
    
                _renderItemData: function(ul, item) {
                    return this._renderItem(ul, item).data("ui-autocomplete-item", item);
                },
    
                _renderItem: function(ul, item) {
                    return $("<li>").text(item.label).appendTo(ul);
                },
    
                _move: function(direction, event) {
                    if (!this.menu.element.is(":visible")) {
                        this.search(null, event);
                        return;
                    }
                    if (this.menu.isFirstItem() && /^previous/.test(direction) ||
                    this.menu.isLastItem() && /^next/.test(direction)) {
    
                        if (!this.isMultiLine) {
                            this._value(this.term);
                        }
    
                        this.menu.blur();
                        return;
                    }
                    this.menu[direction](event);
                },
    
                widget: function() {
                    return this.menu.element;
                },
    
                _value: function() {
                    return this.valueMethod.apply(this.element, arguments);
                },
    
                _keyEvent: function(keyEvent, event) {
                    if (!this.isMultiLine || this.menu.element.is(":visible")) {
                        this._move(keyEvent, event);
    
                        // prevents moving cursor to beginning/end of the text field in some browsers
                        event.preventDefault();
                    }
                }
            });
    
            $.extend($.ui.autocomplete, {
                escapeRegex: function(value) {
                    return value.replace(/[-[]{}()*+?.,\^$|#s]/g, "\$&");
                },
                filter: function(array, term,type) {
                    var matcher = new RegExp($.ui.autocomplete.escapeRegex(term), "i");
    
                    return $.grep(array, function(value) {
                        if (type == "label") {
                            return matcher.test(value.value);
                        } else if (type == "value") {
                            return matcher.test(value.value);
    
                        } else {
                            return matcher.test(value.label || value.value || value);
                        }
                    });
                }
            });
    
            // live region extension, adding a `messages` option
            // NOTE: This is an experimental API. We are still investigating
            // a full solution for string manipulation and internationalization.
            $.widget("ui.autocomplete", $.ui.autocomplete, {
                options: {
                    messages: {
                        noResults: "No search results.",
                        results: function(amount) {
                            return amount + (amount > 1 ? " results are" : " result is") +
                        " available, use up and down arrow keys to navigate.";
                        }
                    }
                },
    
                __response: function(content) {
                    var message;
                    this._superApply(arguments);
                    if (this.options.disabled || this.cancelSearch) {
                        return;
                    }
                    if (content && content.length) {
                        message = this.options.messages.results(content.length);
                    } else {
                        message = this.options.messages.noResults;
                    }
                    this.liveRegion.children().hide();
                    $("<div>").text(message).appendTo(this.liveRegion);
                }
            });
    
            var autocomplete = $.ui.autocomplete;
    
    
    
        }));
  • 相关阅读:
    1.Spring MVC详解
    servlet的九大内置对象
    Hibernate设置事务的隔离级别
    wamp下php报错session_start(): open(d:/wamp/tmpsess_ku776hvb06ko4lv9d11e7mnfj1, O_RDWR) failed: No such file or directory
    json_decode()相关报错
    wamp下var_dump()相关问题
    es6箭头函数内部判断
    Json数组对象取值
    npm指向淘宝源
    APICloud之封装webApp
  • 原文地址:https://www.cnblogs.com/blackice/p/5129378.html
Copyright © 2020-2023  润新知