Changeset - 304e83e9bcde
[Not reviewed]
default
0 2 0
Mads Kiilerich - 9 years ago 2016-06-10 01:19:58
madski@unity3d.com
js: update select2 to 3.5.4

(4.x seems like a more major upgrade - we stick to the 3 series for now.)

Note that select2-bootstrap.css *not* is upgraded. It is a separate thing (see
LICENSE.md) and currently unused. (Select2 now has similar functionality built
in - that should perhaps be used with Bootstrap instead.)
2 files changed with 350 insertions and 110 deletions:
0 comments (0 inline, 0 general)
kallithea/public/js/select2/select2.css
Show inline comments
 
/*
 
Version: 3.5.0 Timestamp: Mon Jun 16 19:29:44 EDT 2014
 
Version: 3.5.4 Timestamp: Sun Aug 30 13:30:32 EDT 2015
 
*/
 
.select2-container {
 
    margin: 0;
 
    position: relative;
 
    display: inline-block;
 
    /* inline-block for ie7 */
 
    zoom: 1;
 
    *display: inline;
 
    vertical-align: middle;
 
}
 

	
 
.select2-container,
 
.select2-drop,
 
.select2-search,
 
@@ -177,16 +174,12 @@ html[dir="rtl"] .select2-container .sele
 

	
 
.select2-drop-auto-width {
 
    border-top: 1px solid #aaa;
 
    width: auto;
 
}
 

	
 
.select2-drop-auto-width .select2-search {
 
    padding-top: 4px;
 
}
 

	
 
.select2-container .select2-choice .select2-arrow {
 
    display: inline-block;
 
    width: 18px;
 
    height: 100%;
 
    position: absolute;
 
    right: 0;
 
@@ -227,14 +220,13 @@ html[dir="rtl"] .select2-container .sele
 

	
 
.select2-search {
 
    display: inline-block;
 
    width: 100%;
 
    min-height: 26px;
 
    margin: 0;
 
    padding-left: 4px;
 
    padding-right: 4px;
 
    padding: 4px 4px 0 4px;
 

	
 
    position: relative;
 
    z-index: 10000;
 

	
 
    white-space: nowrap;
 
}
 
@@ -270,16 +262,12 @@ html[dir="rtl"] .select2-search input {
 
    background: url('select2.png') no-repeat -37px -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
 
    background: url('select2.png') no-repeat -37px -22px, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
 
    background: url('select2.png') no-repeat -37px -22px, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
 
    background: url('select2.png') no-repeat -37px -22px, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0;
 
}
 

	
 
.select2-drop.select2-drop-above .select2-search input {
 
    margin-top: 4px;
 
}
 

	
 
.select2-search input.select2-active {
 
    background: #fff url('select2-spinner.gif') no-repeat 100%;
 
    background: url('select2-spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, #fff), color-stop(0.99, #eee));
 
    background: url('select2-spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, #fff 85%, #eee 99%);
 
    background: url('select2-spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, #fff 85%, #eee 99%);
 
    background: url('select2-spinner.gif') no-repeat 100%, linear-gradient(to bottom, #fff 85%, #eee 99%) 0 0;
 
@@ -419,15 +407,15 @@ html[dir="rtl"] .select2-results {
 

	
 
.select2-results .select2-highlighted ul {
 
    background: #fff;
 
    color: #000;
 
}
 

	
 

	
 
.select2-results .select2-no-results,
 
.select2-results .select2-searching,
 
.select2-results .select2-ajax-error,
 
.select2-results .select2-selection-limit {
 
    background: #f4f4f4;
 
    display: list-item;
 
    padding-left: 5px;
 
}
 

	
 
@@ -451,12 +439,16 @@ disabled look for disabled choices in th
 
}
 

	
 
.select2-more-results.select2-active {
 
    background: #f4f4f4 url('select2-spinner.gif') no-repeat 100%;
 
}
 

	
 
.select2-results .select2-ajax-error {
 
    background: rgba(255, 50, 50, .2);
 
}
 

	
 
.select2-more-results {
 
    background: #f4f4f4;
 
    display: list-item;
 
}
 

	
 
/* disabled styles */
 
@@ -579,13 +571,13 @@ html[dir="rtl"] .select2-container-multi
 

	
 
    background-color: #e4e4e4;
 
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#f4f4f4', GradientType=0);
 
    background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eee));
 
    background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
 
    background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
 
    background-image: linear-gradient(to top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
 
    background-image: linear-gradient(to bottom, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eee 100%);
 
}
 
html[dir="rtl"] .select2-container-multi .select2-choices .select2-search-choice
 
{
 
    margin: 3px 5px 3px 0;
 
    padding: 3px 18px 3px 5px;
 
}
kallithea/public/js/select2/select2.js
Show inline comments
 
/*
 
Copyright 2012 Igor Vaynberg
 

	
 
Version: 3.5.0 Timestamp: Mon Jun 16 19:29:44 EDT 2014
 
Version: 3.5.4 Timestamp: Sun Aug 30 13:30:32 EDT 2015
 

	
 
This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU
 
General Public License version 2 (the "GPL License"). You may choose either license to govern your
 
use of this software only upon the condition that you accept all of the terms of either the Apache
 
License or the GPL License.
 

	
 
@@ -43,13 +43,13 @@ the specific language governing permissi
 
    /*global document, window, jQuery, console */
 

	
 
    if (window.Select2 !== undefined) {
 
        return;
 
    }
 

	
 
    var KEY, AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer,
 
    var AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer,
 
        lastMousePosition={x:0,y:0}, $document, scrollBarDimensions,
 

	
 
    KEY = {
 
        TAB: 9,
 
        ENTER: 13,
 
        ESC: 27,
 
@@ -129,13 +129,13 @@ the specific language governing permissi
 
        }
 
        return -1;
 
    }
 

	
 
    function measureScrollbar () {
 
        var $template = $( MEASURE_SCROLLBAR_TEMPLATE );
 
        $template.appendTo('body');
 
        $template.appendTo(document.body);
 

	
 
        var dim = {
 
            width: $template.width() - $template[0].clientWidth,
 
            height: $template.height() - $template[0].clientHeight
 
        };
 
        $template.remove();
 
@@ -157,22 +157,22 @@ the specific language governing permissi
 
        if (a.constructor === String) return a+'' === b+''; // a+'' - in case 'a' is a String object
 
        if (b.constructor === String) return b+'' === a+''; // b+'' - in case 'b' is a String object
 
        return false;
 
    }
 

	
 
    /**
 
     * Splits the string into an array of values, trimming each value. An empty array is returned for nulls or empty
 
     * Splits the string into an array of values, transforming each value. An empty array is returned for nulls or empty
 
     * strings
 
     * @param string
 
     * @param separator
 
     */
 
    function splitVal(string, separator) {
 
    function splitVal(string, separator, transform) {
 
        var val, i, l;
 
        if (string === null || string.length < 1) return [];
 
        val = string.split(separator);
 
        for (i = 0, l = val.length; i < l; i = i + 1) val[i] = $.trim(val[i]);
 
        for (i = 0, l = val.length; i < l; i = i + 1) val[i] = transform(val[i]);
 
        return val;
 
    }
 

	
 
    function getSideBorderPadding(element) {
 
        return element.outerWidth(false) - element.width();
 
    }
 
@@ -308,13 +308,13 @@ the specific language governing permissi
 
                fontWeight: style.fontWeight,
 
                letterSpacing: style.letterSpacing,
 
                textTransform: style.textTransform,
 
                whiteSpace: "nowrap"
 
            });
 
            sizer.attr("class","select2-sizer");
 
            $("body").append(sizer);
 
            $(document.body).append(sizer);
 
        }
 
        sizer.text(e.val());
 
        return sizer.width();
 
    }
 

	
 
    function syncCssClasses(dest, src, adapter) {
 
@@ -441,12 +441,22 @@ the specific language governing permissi
 
                    data: data,
 
                    success: function (data) {
 
                        // TODO - replace query.page with query so users have access to term, page, etc.
 
                        // added query as third paramter to keep backwards compatibility
 
                        var results = options.results(data, query.page, query);
 
                        query.callback(results);
 
                    },
 
                    error: function(jqXHR, textStatus, errorThrown){
 
                        var results = {
 
                            hasError: true,
 
                            jqXHR: jqXHR,
 
                            textStatus: textStatus,
 
                            errorThrown: errorThrown
 
                        };
 

	
 
                        query.callback(results);
 
                    }
 
                });
 
                handler = transport.call(self, params);
 
            }, quietMillis);
 
        };
 
    }
 
@@ -686,28 +696,31 @@ the specific language governing permissi
 
                opts.element.data("select2") !== null) {
 
                opts.element.data("select2").destroy();
 
            }
 

	
 
            this.container = this.createContainer();
 

	
 
            this.liveRegion = $('.select2-hidden-accessible');
 
            if (this.liveRegion.length == 0) {
 
            this.liveRegion = $("<span>", {
 
                    role: "status",
 
                    "aria-live": "polite"
 
                })
 
                .addClass("select2-hidden-accessible")
 
                .appendTo(document.body);
 
            }
 

	
 
            this.containerId="s2id_"+(opts.element.attr("id") || "autogen"+nextUid());
 
            this.containerEventName= this.containerId
 
                .replace(/([.])/g, '_')
 
                .replace(/([;&,\-\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '\\$1');
 
            this.container.attr("id", this.containerId);
 

	
 
            this.container.attr("title", opts.element.attr("title"));
 

	
 
            this.body = $("body");
 
            this.body = $(document.body);
 

	
 
            syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass);
 

	
 
            this.container.attr("style", opts.element.attr("style"));
 
            this.container.css(evaluate(opts.containerCss, this.opts.element));
 
            this.container.addClass(evaluate(opts.containerCssClass, this.opts.element));
 
@@ -798,13 +811,13 @@ the specific language governing permissi
 
            // trap all mouse events from leaving the dropdown. sometimes there may be a modal that is listening
 
            // for mouse events outside of itself so it can close itself. since the dropdown is now outside the select2's
 
            // dom it will trigger the popup close, which is not what we want
 
            // focusin can cause focus wars between modals and select2 since the dropdown is outside the modal.
 
            this.dropdown.on("click mouseup mousedown touchstart touchend focusin", function (e) { e.stopPropagation(); });
 

	
 
            this.nextSearchTerm = undefined;
 
            this.lastSearchTerm = undefined;
 

	
 
            if ($.isFunction(this.opts.initSelection)) {
 
                // initialize selection based on the current value of the source element
 
                this.initSelection();
 

	
 
                // if the user has provided a function that can set selection based on the value of the source element
 
@@ -833,42 +846,48 @@ the specific language governing permissi
 

	
 
            this.search.attr("placeholder", opts.searchInputPlaceholder);
 
        },
 

	
 
        // abstract
 
        destroy: function () {
 
            var element=this.opts.element, select2 = element.data("select2");
 
            var element=this.opts.element, select2 = element.data("select2"), self = this;
 

	
 
            this.close();
 

	
 
            if (element.length && element[0].detachEvent) {
 
            if (element.length && element[0].detachEvent && self._sync) {
 
                element.each(function () {
 
                    this.detachEvent("onpropertychange", this._sync);
 
                    if (self._sync) {
 
                        this.detachEvent("onpropertychange", self._sync);
 
                    }
 
                });
 
            }
 
            if (this.propertyObserver) {
 
                this.propertyObserver.disconnect();
 
                this.propertyObserver = null;
 
            }
 
            this._sync = null;
 

	
 
            if (select2 !== undefined) {
 
                select2.container.remove();
 
                select2.liveRegion.remove();
 
                select2.dropdown.remove();
 
                element.removeData("select2")
 
                    .off(".select2");
 
                if (!element.is("input[type='hidden']")) {
 
                element
 
                    .removeClass("select2-offscreen")
 
                    .removeData("select2")
 
                    .off(".select2")
 
                        .show()
 
                    .prop("autofocus", this.autofocus || false);
 
                if (this.elementTabIndex) {
 
                    element.attr({tabindex: this.elementTabIndex});
 
                } else {
 
                    element.removeAttr("tabindex");
 
                }
 
                element.show();
 
                } else {
 
                    element.css("display", "");
 
                }
 
            }
 

	
 
            cleanupJQueryElements.call(this,
 
                "container",
 
                "liveRegion",
 
                "dropdown",
 
@@ -914,12 +933,161 @@ the specific language governing permissi
 
                    if (this in opts) {
 
                        throw new Error("Option '" + this + "' is not allowed for Select2 when attached to a <select> element.");
 
                    }
 
                });
 
            }
 

	
 
            opts.debug = opts.debug || $.fn.select2.defaults.debug;
 

	
 
            // Warnings for options renamed/removed in Select2 4.0.0
 
            // Only when it's enabled through debug mode
 
            if (opts.debug && console && console.warn) {
 
                // id was removed
 
                if (opts.id != null) {
 
                    console.warn(
 
                        'Select2: The `id` option has been removed in Select2 4.0.0, ' +
 
                        'consider renaming your `id` property or mapping the property before your data makes it to Select2. ' +
 
                        'You can read more at https://select2.github.io/announcements-4.0.html#changed-id'
 
                    );
 
                }
 

	
 
                // text was removed
 
                if (opts.text != null) {
 
                    console.warn(
 
                        'Select2: The `text` option has been removed in Select2 4.0.0, ' +
 
                        'consider renaming your `text` property or mapping the property before your data makes it to Select2. ' +
 
                        'You can read more at https://select2.github.io/announcements-4.0.html#changed-id'
 
                    );
 
                }
 

	
 
                // sortResults was renamed to results
 
                if (opts.sortResults != null) {
 
                    console.warn(
 
                        'Select2: the `sortResults` option has been renamed to `sorter` in Select2 4.0.0. '
 
                    );
 
                }
 

	
 
                // selectOnBlur was renamed to selectOnClose
 
                if (opts.selectOnBlur != null) {
 
                    console.warn(
 
                        'Select2: The `selectOnBlur` option has been renamed to `selectOnClose` in Select2 4.0.0.'
 
                    );
 
                }
 

	
 
                // ajax.results was renamed to ajax.processResults
 
                if (opts.ajax != null && opts.ajax.results != null) {
 
                    console.warn(
 
                        'Select2: The `ajax.results` option has been renamed to `ajax.processResults` in Select2 4.0.0.'
 
                    );
 
                }
 

	
 
                // format* options were renamed to language.*
 
                if (opts.formatNoResults != null) {
 
                    console.warn(
 
                        'Select2: The `formatNoResults` option has been renamed to `language.noResults` in Select2 4.0.0.'
 
                    );
 
                }
 
                if (opts.formatSearching != null) {
 
                    console.warn(
 
                        'Select2: The `formatSearching` option has been renamed to `language.searching` in Select2 4.0.0.'
 
                    );
 
                }
 
                if (opts.formatInputTooShort != null) {
 
                    console.warn(
 
                        'Select2: The `formatInputTooShort` option has been renamed to `language.inputTooShort` in Select2 4.0.0.'
 
                    );
 
                }
 
                if (opts.formatInputTooLong != null) {
 
                    console.warn(
 
                        'Select2: The `formatInputTooLong` option has been renamed to `language.inputTooLong` in Select2 4.0.0.'
 
                    );
 
                }
 
                if (opts.formatLoading != null) {
 
                    console.warn(
 
                        'Select2: The `formatLoading` option has been renamed to `language.loadingMore` in Select2 4.0.0.'
 
                    );
 
                }
 
                if (opts.formatSelectionTooBig != null) {
 
                    console.warn(
 
                        'Select2: The `formatSelectionTooBig` option has been renamed to `language.maximumSelected` in Select2 4.0.0.'
 
                    );
 
                }
 

	
 
                if (opts.element.data('select2Tags')) {
 
                    console.warn(
 
                        'Select2: The `data-select2-tags` attribute has been renamed to `data-tags` in Select2 4.0.0.'
 
                    );
 
                }
 
            }
 

	
 
            // Aliasing options renamed in Select2 4.0.0
 

	
 
            // data-select2-tags -> data-tags
 
            if (opts.element.data('tags') != null) {
 
                var elemTags = opts.element.data('tags');
 

	
 
                // data-tags should actually be a boolean
 
                if (!$.isArray(elemTags)) {
 
                    elemTags = [];
 
                }
 

	
 
                opts.element.data('select2Tags', elemTags);
 
            }
 

	
 
            // sortResults -> sorter
 
            if (opts.sorter != null) {
 
                opts.sortResults = opts.sorter;
 
            }
 

	
 
            // selectOnBlur -> selectOnClose
 
            if (opts.selectOnClose != null) {
 
                opts.selectOnBlur = opts.selectOnClose;
 
            }
 

	
 
            // ajax.results -> ajax.processResults
 
            if (opts.ajax != null) {
 
                if ($.isFunction(opts.ajax.processResults)) {
 
                    opts.ajax.results = opts.ajax.processResults;
 
                }
 
            }
 

	
 
            // Formatters/language options
 
            if (opts.language != null) {
 
                var lang = opts.language;
 

	
 
                // formatNoMatches -> language.noMatches
 
                if ($.isFunction(lang.noMatches)) {
 
                    opts.formatNoMatches = lang.noMatches;
 
                }
 

	
 
                // formatSearching -> language.searching
 
                if ($.isFunction(lang.searching)) {
 
                    opts.formatSearching = lang.searching;
 
                }
 

	
 
                // formatInputTooShort -> language.inputTooShort
 
                if ($.isFunction(lang.inputTooShort)) {
 
                    opts.formatInputTooShort = lang.inputTooShort;
 
                }
 

	
 
                // formatInputTooLong -> language.inputTooLong
 
                if ($.isFunction(lang.inputTooLong)) {
 
                    opts.formatInputTooLong = lang.inputTooLong;
 
                }
 

	
 
                // formatLoading -> language.loadingMore
 
                if ($.isFunction(lang.loadingMore)) {
 
                    opts.formatLoading = lang.loadingMore;
 
                }
 

	
 
                // formatSelectionTooBig -> language.maximumSelected
 
                if ($.isFunction(lang.maximumSelected)) {
 
                    opts.formatSelectionTooBig = lang.maximumSelected;
 
                }
 
            }
 

	
 
            opts = $.extend({}, {
 
                populateResults: function(container, results, query) {
 
                    var populate, id=this.opts.id, liveRegion=this.liveRegion;
 

	
 
                    populate=function(results, container, depth) {
 

	
 
@@ -957,13 +1125,12 @@ the specific language governing permissi
 
                                label.html(formatted);
 
                                node.append(label);
 
                            }
 

	
 

	
 
                            if (compound) {
 

	
 
                                innerContainer=$("<ul></ul>");
 
                                innerContainer.addClass("select2-result-sub");
 
                                populate(result.children, innerContainer, depth+1);
 
                                node.append(innerContainer);
 
                            }
 

	
 
@@ -1024,17 +1191,16 @@ the specific language governing permissi
 
                    }
 

	
 
                    children.each2(function(i, elm) { process(elm, data.results); });
 

	
 
                    query.callback(data);
 
                });
 
                // this is needed because inside val() we construct choices from options and there id is hardcoded
 
                // this is needed because inside val() we construct choices from options and their id is hardcoded
 
                opts.id=function(e) { return e.id; };
 
            } else {
 
                if (!("query" in opts)) {
 

	
 
                    if ("ajax" in opts) {
 
                        ajaxUrl = opts.element.data("ajax-url");
 
                        if (ajaxUrl && ajaxUrl.length > 0) {
 
                            opts.ajax.url = ajaxUrl;
 
                        }
 
                        opts.query = ajax.call(opts.element, opts.ajax);
 
@@ -1045,13 +1211,13 @@ the specific language governing permissi
 
                        if (opts.createSearchChoice === undefined) {
 
                            opts.createSearchChoice = function (term) { return {id: $.trim(term), text: $.trim(term)}; };
 
                        }
 
                        if (opts.initSelection === undefined) {
 
                            opts.initSelection = function (element, callback) {
 
                                var data = [];
 
                                $(splitVal(element.val(), opts.separator)).each(function () {
 
                                $(splitVal(element.val(), opts.separator, opts.transformVal)).each(function () {
 
                                    var obj = { id: this, text: this },
 
                                        tags = opts.tags;
 
                                    if ($.isFunction(tags)) tags=tags();
 
                                    $(tags).each(function() { if (equal(this.id, obj.id)) { obj = this; return false; } });
 
                                    data.push(obj);
 
                                });
 
@@ -1100,17 +1266,21 @@ the specific language governing permissi
 
                this.enable(!disabled);
 

	
 
                var readonly = el.prop("readonly");
 
                if (readonly === undefined) readonly = false;
 
                this.readonly(readonly);
 

	
 
                if (this.container) {
 
                syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass);
 
                this.container.addClass(evaluate(this.opts.containerCssClass, this.opts.element));
 

	
 
                }
 

	
 
                if (this.dropdown) {
 
                syncCssClasses(this.dropdown, this.opts.element, this.opts.adaptDropdownCssClass);
 
                this.dropdown.addClass(evaluate(this.opts.dropdownCssClass, this.opts.element));
 
                }
 

	
 
            });
 

	
 
            // IE8-10 (IE9/10 won't fire propertyChange via attachEventListener)
 
            if (el.length && el[0].attachEvent) {
 
                el.each(function() {
 
@@ -1209,27 +1379,33 @@ the specific language governing permissi
 
            return (this.container) ? this.container.hasClass("select2-dropdown-open") : false;
 
        },
 

	
 
        // abstract
 
        positionDropdown: function() {
 
            var $dropdown = this.dropdown,
 
                offset = this.container.offset(),
 
                height = this.container.outerHeight(false),
 
                width = this.container.outerWidth(false),
 
                container = this.container,
 
                offset = container.offset(),
 
                height = container.outerHeight(false),
 
                width = container.outerWidth(false),
 
                dropHeight = $dropdown.outerHeight(false),
 
                $window = $(window),
 
                windowWidth = $window.width(),
 
                windowHeight = $window.height(),
 
                viewPortRight = $window.scrollLeft() + windowWidth,
 
                viewportBottom = $window.scrollTop() + windowHeight,
 
                dropTop = offset.top + height,
 
                dropLeft = offset.left,
 
                enoughRoomBelow = dropTop + dropHeight <= viewportBottom,
 
                enoughRoomAbove = (offset.top - dropHeight) >= $window.scrollTop(),
 
                dropWidth = $dropdown.outerWidth(false),
 
                enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight,
 
                enoughRoomOnRight = function() {
 
                    return dropLeft + dropWidth <= viewPortRight;
 
                },
 
                enoughRoomOnLeft = function() {
 
                    return offset.left + viewPortRight + container.outerWidth(false)  > dropWidth;
 
                },
 
                aboveNow = $dropdown.hasClass("select2-drop-above"),
 
                bodyOffset,
 
                above,
 
                changeDirection,
 
                css,
 
                resultsListNode;
 
@@ -1258,13 +1434,12 @@ the specific language governing permissi
 
                dropHeight = $dropdown.outerHeight(false);
 
                viewPortRight = $window.scrollLeft() + windowWidth;
 
                viewportBottom = $window.scrollTop() + windowHeight;
 
                dropTop = offset.top + height;
 
                dropLeft = offset.left;
 
                dropWidth = $dropdown.outerWidth(false);
 
                enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight;
 
                $dropdown.show();
 

	
 
                // fix so the cursor does not move to the left within the search-textbox in IE
 
                this.focusSearch();
 
            }
 

	
 
@@ -1273,13 +1448,12 @@ the specific language governing permissi
 
                $dropdown.addClass('select2-drop-auto-width');
 
                $dropdown.css('width', '');
 
                // Add scrollbar width to dropdown if vertical scrollbar is present
 
                dropWidth = $dropdown.outerWidth(false) + (resultsListNode.scrollHeight === resultsListNode.clientHeight ? 0 : scrollBarDimensions.width);
 
                dropWidth > width ? width = dropWidth : dropWidth = width;
 
                dropHeight = $dropdown.outerHeight(false);
 
                enoughRoomOnRight = dropLeft + dropWidth <= viewPortRight;
 
            }
 
            else {
 
                this.container.removeClass('select2-drop-auto-width');
 
            }
 

	
 
            //console.log("below/ droptop:", dropTop, "dropHeight", dropHeight, "sum", (dropTop+dropHeight)+" viewport bottom", viewportBottom, "enough?", enoughRoomBelow);
 
@@ -1289,26 +1463,27 @@ the specific language governing permissi
 
            if (this.body.css('position') !== 'static') {
 
                bodyOffset = this.body.offset();
 
                dropTop -= bodyOffset.top;
 
                dropLeft -= bodyOffset.left;
 
            }
 

	
 
            if (!enoughRoomOnRight) {
 
            if (!enoughRoomOnRight() && enoughRoomOnLeft()) {
 
                dropLeft = offset.left + this.container.outerWidth(false) - dropWidth;
 
            }
 

	
 
            css =  {
 
                left: dropLeft,
 
                width: width
 
            };
 

	
 
            if (above) {
 
                this.container.addClass("select2-drop-above");
 
                $dropdown.addClass("select2-drop-above");
 
                dropHeight = $dropdown.outerHeight(false);
 
                css.top = offset.top - dropHeight;
 
                css.bottom = 'auto';
 
                this.container.addClass("select2-drop-above");
 
                $dropdown.addClass("select2-drop-above");
 
            }
 
            else {
 
                css.top = dropTop;
 
                css.bottom = 'auto';
 
                this.container.removeClass("select2-drop-above");
 
                $dropdown.removeClass("select2-drop-above");
 
@@ -1378,13 +1553,13 @@ the specific language governing permissi
 
            if(this.dropdown[0] !== this.body.children().last()[0]) {
 
                this.dropdown.detach().appendTo(this.body);
 
            }
 

	
 
            // create the dropdown mask if doesn't already exist
 
            mask = $("#select2-drop-mask");
 
            if (mask.length == 0) {
 
            if (mask.length === 0) {
 
                mask = $(document.createElement("div"));
 
                mask.attr("id","select2-drop-mask").attr("class","select2-drop-mask");
 
                mask.hide();
 
                mask.appendTo(this.body);
 
                mask.on("mousedown touchstart click", function (e) {
 
                    // Prevent IE from generating a click event on the body
 
@@ -1455,12 +1630,15 @@ the specific language governing permissi
 

	
 
            // Now that the dropdown is closed, unbind the global document mousemove event
 
            $document.off("mousemove.select2Event");
 

	
 
            this.clearSearch();
 
            this.search.removeClass("select2-active");
 

	
 
            // Remove the aria active descendant for highlighted element
 
            this.search.removeAttr("aria-activedescendant");
 
            this.opts.element.trigger($.Event("select2-close"));
 
        },
 

	
 
        /**
 
         * Opens control, sets input value, and updates results.
 
         */
 
@@ -1473,12 +1651,33 @@ the specific language governing permissi
 

	
 
        // abstract
 
        clearSearch: function () {
 

	
 
        },
 

	
 
        /**
 
         * @return {Boolean} Whether or not search value was changed.
 
         * @private
 
         */
 
        prefillNextSearchTerm: function () {
 
            // initializes search's value with nextSearchTerm (if defined by user)
 
            // ignore nextSearchTerm if the dropdown is opened by the user pressing a letter
 
            if(this.search.val() !== "") {
 
                return false;
 
            }
 

	
 
            var nextSearchTerm = this.opts.nextSearchTerm(this.data(), this.lastSearchTerm);
 
            if(nextSearchTerm !== undefined){
 
                this.search.val(nextSearchTerm);
 
                this.search.select();
 
                return true;
 
            }
 

	
 
            return false;
 
        },
 

	
 
        //abstract
 
        getMaximumSelectionSize: function() {
 
            return evaluate(this.opts.maximumSelectionSize, this.opts.element);
 
        },
 

	
 
        // abstract
 
@@ -1512,13 +1711,13 @@ the specific language governing permissi
 
                more = results.find("li.select2-more-results");
 
                if (more.length > 0) {
 
                    hb = more.offset().top + more.outerHeight(true);
 
                }
 
            }
 

	
 
            rb = results.offset().top + results.outerHeight(true);
 
            rb = results.offset().top + results.outerHeight(false);
 
            if (hb > rb) {
 
                results.scrollTop(results.scrollTop() + (hb - rb));
 
            }
 
            y = topOffset - results.offset().top;
 

	
 
            // make sure the top of the element is visible
 
@@ -1635,13 +1834,13 @@ the specific language governing permissi
 

	
 

	
 
                    self.opts.populateResults.call(this, results, data.results, {term: term, page: page, context:context});
 
                    self.postprocessResults(data, false, false);
 

	
 
                    if (data.more===true) {
 
                        more.detach().appendTo(results).text(evaluate(self.opts.formatLoadMore, self.opts.element, page+1));
 
                        more.detach().appendTo(results).html(self.opts.escapeMarkup(evaluate(self.opts.formatLoadMore, self.opts.element, page+1)));
 
                        window.setTimeout(function() { self.loadMoreIfNeeded(); }, 10);
 
                    } else {
 
                        more.remove();
 
                    }
 
                    self.positionDropdown();
 
                    self.resultsPage = page;
 
@@ -1688,13 +1887,13 @@ the specific language governing permissi
 
                search.removeClass("select2-active");
 
                self.positionDropdown();
 
                if (results.find('.select2-no-results,.select2-selection-limit,.select2-searching').length) {
 
                    self.liveRegion.text(results.text());
 
                }
 
                else {
 
                    self.liveRegion.text(self.opts.formatMatches(results.find('.select2-result-selectable').length));
 
                    self.liveRegion.text(self.opts.formatMatches(results.find('.select2-result-selectable:not(".select2-selected")').length));
 
                }
 
            }
 

	
 
            function render(html) {
 
                results.html(html);
 
                postRender();
 
@@ -1763,12 +1962,18 @@ the specific language governing permissi
 
                // ignore a response if the select2 has been closed before it was received
 
                if (!this.opened()) {
 
                    this.search.removeClass("select2-active");
 
                    return;
 
                }
 

	
 
                // handle ajax error
 
                if(data.hasError !== undefined && checkFormatter(opts.formatAjaxError, "formatAjaxError")) {
 
                    render("<li class='select2-ajax-error'>" + evaluate(opts.formatAjaxError, opts.element, data.jqXHR, data.textStatus, data.errorThrown) + "</li>");
 
                    return;
 
                }
 

	
 
                // save context, if any
 
                this.context = (data.context===undefined) ? null : data.context;
 
                // create a default choice and prepend it to the list
 
                if (this.opts.createSearchChoice && search.val() !== "") {
 
                    def = this.opts.createSearchChoice.call(self, search.val(), data.results);
 
                    if (def !== undefined && def !== null && self.id(def) !== undefined && self.id(def) !== null) {
 
@@ -1780,12 +1985,15 @@ the specific language governing permissi
 
                        }
 
                    }
 
                }
 

	
 
                if (data.results.length === 0 && checkFormatter(opts.formatNoMatches, "formatNoMatches")) {
 
                    render("<li class='select2-no-results'>" + evaluate(opts.formatNoMatches, opts.element, search.val()) + "</li>");
 
                    if(this.showSearch){
 
                        this.showSearch(search.val());
 
                    }
 
                    return;
 
                }
 

	
 
                results.empty();
 
                self.opts.populateResults.call(this, results, data.results, {term: search.val(), page: this.resultsPage, context:null});
 

	
 
@@ -1884,13 +2092,13 @@ the specific language governing permissi
 
                    return null;
 
                } else if (this.opts.width === "element"){
 
                    return this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px';
 
                } else if (this.opts.width === "copy" || this.opts.width === "resolve") {
 
                    // check if there is inline style on the element that contains width
 
                    style = this.opts.element.attr('style');
 
                    if (style !== undefined) {
 
                    if (typeof(style) === "string") {
 
                        attrs = style.split(';');
 
                        for (i = 0, l = attrs.length; i < l; i = i + 1) {
 
                            attr = attrs[i].replace(/\s/g, '');
 
                            matches = attr.match(/^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i);
 
                            if (matches !== null && matches.length >= 1)
 
                                return matches[1];
 
@@ -1983,20 +2191,13 @@ the specific language governing permissi
 
                } else if (el.setSelectionRange) {
 
                    len = this.search.val().length;
 
                    el.setSelectionRange(len, len);
 
                }
 
            }
 

	
 
            // initializes search's value with nextSearchTerm (if defined by user)
 
            // ignore nextSearchTerm if the dropdown is opened by the user pressing a letter
 
            if(this.search.val() === "") {
 
                if(this.nextSearchTerm != undefined){
 
                    this.search.val(this.nextSearchTerm);
 
                    this.search.select();
 
                }
 
            }
 
            this.prefillNextSearchTerm();
 

	
 
            this.focusser.prop("disabled", true).val("");
 
            this.updateResults(true);
 
            this.opts.element.trigger($.Event("select2-open"));
 
        },
 

	
 
@@ -2077,12 +2278,13 @@ the specific language governing permissi
 
            this.search.attr("aria-owns", "select2-results-"+idSuffix);
 

	
 
            // rewrite labels from original element to focusser
 
            this.focusser.attr("id", "s2id_autogen"+idSuffix);
 

	
 
            elementLabel = $("label[for='" + this.opts.element.attr("id") + "']");
 
            this.opts.element.on('focus.select2', this.bind(function () { this.focus(); }));
 

	
 
            this.focusser.prev()
 
                .text(elementLabel.text())
 
                .attr('for', this.focusser.attr('id'));
 

	
 
            // Ensure the original element retains an accessible name
 
@@ -2098,12 +2300,15 @@ the specific language governing permissi
 
                .text($("label[for='" + this.focusser.attr('id') + "']").text())
 
                .attr('for', this.search.attr('id'));
 

	
 
            this.search.on("keydown", this.bind(function (e) {
 
                if (!this.isInterfaceEnabled()) return;
 

	
 
                // filter 229 keyCodes (input method editor is processing key input)
 
                if (229 == e.keyCode) return;
 

	
 
                if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) {
 
                    // prevent the page from scrolling
 
                    killEvent(e);
 
                    return;
 
                }
 

	
 
@@ -2129,13 +2334,13 @@ the specific language governing permissi
 

	
 
            this.search.on("blur", this.bind(function(e) {
 
                // a workaround for chrome to keep the search field focussed when the scroll bar is used to scroll the dropdown.
 
                // without this the search field loses focus which is annoying
 
                if (document.activeElement === this.body.get(0)) {
 
                    window.setTimeout(this.bind(function() {
 
                        if (this.opened()) {
 
                        if (this.opened() && this.results && this.results.length > 1) {
 
                            this.search.focus();
 
                        }
 
                    }), 0);
 
                }
 
            }));
 

	
 
@@ -2178,17 +2383,23 @@ the specific language governing permissi
 
                    if (this.opened()) return;
 
                    this.open();
 
                }
 
            }));
 

	
 
            selection.on("mousedown touchstart", "abbr", this.bind(function (e) {
 
                if (!this.isInterfaceEnabled()) return;
 
                if (!this.isInterfaceEnabled()) {
 
                    return;
 
                }
 

	
 
                this.clear();
 
                killEventImmediately(e);
 
                this.close();
 

	
 
                if (this.selection) {
 
                this.selection.focus();
 
                }
 
            }));
 

	
 
            selection.on("mousedown touchstart", this.bind(function (e) {
 
                // Prevent IE from generating a click event on the body
 
                reinsertElement(selection);
 

	
 
@@ -2231,13 +2442,13 @@ the specific language governing permissi
 
                    this.opts.element.trigger($.Event("select2-focus"));
 
                }
 
                this.container.addClass("select2-container-active");
 
            }));
 

	
 
            this.initContainerWidth();
 
            this.opts.element.addClass("select2-offscreen");
 
            this.opts.element.hide();
 
            this.setPlaceholder();
 

	
 
        },
 

	
 
        // single
 
        clear: function(triggerChange) {
 
@@ -2275,13 +2486,13 @@ the specific language governing permissi
 
                var self = this;
 
                this.opts.initSelection.call(null, this.opts.element, function(selected){
 
                    if (selected !== undefined && selected !== null) {
 
                        self.updateSelection(selected);
 
                        self.close();
 
                        self.setPlaceholder();
 
                        self.nextSearchTerm = self.opts.nextSearchTerm(selected, self.search.val());
 
                        self.lastSearchTerm = self.search.val();
 
                    }
 
                });
 
            }
 
        },
 

	
 
        isPlaceholderOptionSelected: function() {
 
@@ -2412,13 +2623,13 @@ the specific language governing permissi
 

	
 
            this.opts.element.val(this.id(data));
 
            this.updateSelection(data);
 

	
 
            this.opts.element.trigger({ type: "select2-selected", val: this.id(data), choice: data });
 

	
 
            this.nextSearchTerm = this.opts.nextSearchTerm(data, this.search.val());
 
            this.lastSearchTerm = this.search.val();
 
            this.close();
 

	
 
            if ((!options || !options.noFocus) && this.opts.shouldFocusInput(this)) {
 
                this.focusser.focus();
 
            }
 

	
 
@@ -2466,15 +2677,29 @@ the specific language governing permissi
 
            }
 

	
 
            val = arguments[0];
 

	
 
            if (arguments.length > 1) {
 
                triggerChange = arguments[1];
 

	
 
                if (this.opts.debug && console && console.warn) {
 
                    console.warn(
 
                        'Select2: The second option to `select2("val")` is not supported in Select2 4.0.0. ' +
 
                        'The `change` event will always be triggered in 4.0.0.'
 
                    );
 
                }
 
            }
 

	
 
            if (this.select) {
 
                if (this.opts.debug && console && console.warn) {
 
                    console.warn(
 
                        'Select2: Setting the value on a <select> using `select2("val")` is no longer supported in 4.0.0. ' +
 
                        'You can use the `.val(newValue).trigger("change")` method provided by jQuery instead.'
 
                    );
 
                }
 

	
 
                this.select
 
                    .val(val)
 
                    .find("option").filter(function() { return this.selected }).each2(function (i, elm) {
 
                        data = self.optionToData(elm);
 
                        return false;
 
                    });
 
@@ -2517,12 +2742,19 @@ the specific language governing permissi
 

	
 
            if (arguments.length === 0) {
 
                data = this.selection.data("select2-data");
 
                if (data == undefined) data = null;
 
                return data;
 
            } else {
 
                if (this.opts.debug && console && console.warn) {
 
                    console.warn(
 
                        'Select2: The `select2("data")` method can no longer set selected values in 4.0.0, ' +
 
                        'consider using the `.val()` method instead.'
 
                    );
 
                }
 

	
 
                if (arguments.length > 1) {
 
                    triggerChange = arguments[1];
 
                }
 
                if (!value) {
 
                    this.clear(triggerChange);
 
                } else {
 
@@ -2560,13 +2792,12 @@ the specific language governing permissi
 
        // multi
 
        prepareOpts: function () {
 
            var opts = this.parent.prepareOpts.apply(this, arguments),
 
                self=this;
 

	
 
            // TODO validate placeholder is a string if specified
 

	
 
            if (opts.element.get(0).tagName.toLowerCase() === "select") {
 
                // install the selection initializer
 
                opts.initSelection = function (element, callback) {
 

	
 
                    var data = [];
 

	
 
@@ -2575,13 +2806,13 @@ the specific language governing permissi
 
                    });
 
                    callback(data);
 
                };
 
            } else if ("data" in opts) {
 
                // install default initSelection when applied to hidden input and data is local
 
                opts.initSelection = opts.initSelection || function (element, callback) {
 
                    var ids = splitVal(element.val(), opts.separator);
 
                    var ids = splitVal(element.val(), opts.separator, opts.transformVal);
 
                    //search in data by array of ids, storing matching items in a list
 
                    var matches = [];
 
                    opts.query({
 
                        matcher: function(term, text, el){
 
                            var is_match = $.grep(ids, function(id) {
 
                                return equal(id, opts.id(el));
 
@@ -2652,24 +2883,24 @@ the specific language governing permissi
 
            var selector = ".select2-choices", selection;
 

	
 
            this.searchContainer = this.container.find(".select2-search-field");
 
            this.selection = selection = this.container.find(selector);
 

	
 
            var _this = this;
 
            this.selection.on("click", ".select2-search-choice:not(.select2-locked)", function (e) {
 
                //killEvent(e);
 
            this.selection.on("click", ".select2-container:not(.select2-container-disabled) .select2-search-choice:not(.select2-locked)", function (e) {
 
                _this.search[0].focus();
 
                _this.selectChoice($(this));
 
            });
 

	
 
            // rewrite labels from original element to focusser
 
            this.search.attr("id", "s2id_autogen"+nextUid());
 

	
 
            this.search.prev()
 
                .text($("label[for='" + this.opts.element.attr("id") + "']").text())
 
                .attr('for', this.search.attr('id'));
 
            this.opts.element.on('focus.select2', this.bind(function () { this.focus(); }));
 

	
 
            this.search.on("input paste", this.bind(function() {
 
                if (this.search.attr('placeholder') && this.search.val().length == 0) return;
 
                if (!this.isInterfaceEnabled()) return;
 
                if (!this.opened()) {
 
                    this.open();
 
@@ -2815,13 +3046,13 @@ the specific language governing permissi
 
                this.container.addClass("select2-container-active");
 
                this.dropdown.addClass("select2-drop-active");
 
                this.clearPlaceholder();
 
            }));
 

	
 
            this.initContainerWidth();
 
            this.opts.element.addClass("select2-offscreen");
 
            this.opts.element.hide();
 

	
 
            // set the placeholder if necessary
 
            this.clearSearch();
 
        },
 

	
 
        // multi
 
@@ -2881,22 +3112,15 @@ the specific language governing permissi
 
            this.resizeSearch();
 

	
 
            this.parent.opening.apply(this, arguments);
 

	
 
            this.focusSearch();
 

	
 
            // initializes search's value with nextSearchTerm (if defined by user)
 
            // ignore nextSearchTerm if the dropdown is opened by the user pressing a letter
 
            if(this.search.val() === "") {
 
                if(this.nextSearchTerm != undefined){
 
                    this.search.val(this.nextSearchTerm);
 
                    this.search.select();
 
                }
 
            }
 

	
 
            this.prefillNextSearchTerm();
 
            this.updateResults(true);
 

	
 
            if (this.opts.shouldFocusInput(this)) {
 
                this.search.focus();
 
            }
 
            this.opts.element.trigger($.Event("select2-open"));
 
        },
 

	
 
@@ -2916,27 +3140,24 @@ the specific language governing permissi
 
        isFocused: function () {
 
            return this.search.hasClass("select2-focused");
 
        },
 

	
 
        // multi
 
        updateSelection: function (data) {
 
            var ids = [], filtered = [], self = this;
 
            var ids = {}, filtered = [], self = this;
 

	
 
            // filter out duplicates
 
            $(data).each(function () {
 
                if (indexOf(self.id(this), ids) < 0) {
 
                    ids.push(self.id(this));
 
                if (!(self.id(this) in ids)) {
 
                    ids[self.id(this)] = 0;
 
                    filtered.push(this);
 
                }
 
            });
 
            data = filtered;
 

	
 
            this.selection.find(".select2-search-choice").remove();
 
            $(data).each(function () {
 
                self.addSelectedChoice(this);
 
            });
 
            this.addSelectedChoice(filtered);
 
            self.postprocessResults();
 
        },
 

	
 
        // multi
 
        tokenize: function() {
 
            var input = this.search.val();
 
@@ -2950,20 +3171,20 @@ the specific language governing permissi
 

	
 
        },
 

	
 
        // multi
 
        onSelect: function (data, options) {
 

	
 
            if (!this.triggerSelect(data)) { return; }
 
            if (!this.triggerSelect(data) || data.text === "") { return; }
 

	
 
            this.addSelectedChoice(data);
 

	
 
            this.opts.element.trigger({ type: "selected", val: this.id(data), choice: data });
 

	
 
            // keep track of the search's value before it gets cleared
 
            this.nextSearchTerm = this.opts.nextSearchTerm(data, this.search.val());
 
            this.lastSearchTerm = this.search.val();
 

	
 
            this.clearSearch();
 
            this.updateResults();
 

	
 
            if (this.select || !this.opts.closeOnSelect) this.postprocessResults(data, false, this.opts.closeOnSelect===true);
 

	
 
@@ -2977,16 +3198,14 @@ the specific language governing permissi
 
                    if (this.getMaximumSelectionSize() > 0 && this.val().length >= this.getMaximumSelectionSize()) {
 
                        // if we reached max selection size repaint the results so choices
 
                        // are replaced with the max selection reached message
 
                        this.updateResults(true);
 
                    } else {
 
                        // initializes search's value with nextSearchTerm and update search result
 
                        if(this.nextSearchTerm != undefined){
 
                            this.search.val(this.nextSearchTerm);
 
                        if (this.prefillNextSearchTerm()) {
 
                            this.updateResults();
 
                            this.search.select();
 
                        }
 
                    }
 
                    this.positionDropdown();
 
                } else {
 
                    // if nothing left to select close
 
                    this.close();
 
@@ -3006,31 +3225,38 @@ the specific language governing permissi
 
        cancel: function () {
 
            this.close();
 
            this.focusSearch();
 
        },
 

	
 
        addSelectedChoice: function (data) {
 
            var val = this.getVal(), self = this;
 
            $(data).each(function () {
 
                val.push(self.createChoice(this));
 
            });
 
            this.setVal(val);
 
        },
 

	
 
        createChoice: function (data) {
 
            var enableChoice = !data.locked,
 
                enabledItem = $(
 
                    "<li class='select2-search-choice'>" +
 
                    "    <div></div>" +
 
                    "    <a href='#' class='select2-search-choice-close' tabindex='-1'></a>" +
 
                    "</li>"),
 
                disabledItem = $(
 
                    "<li class='select2-search-choice select2-locked'>" +
 
                    "<div></div>" +
 
                    "</li>");
 
            var choice = enableChoice ? enabledItem : disabledItem,
 
                id = this.id(data),
 
                val = this.getVal(),
 
                formatted,
 
                cssClass;
 

	
 
            formatted=this.opts.formatSelection(data, choice.find("div"), this.opts.escapeMarkup);
 
            if (formatted != undefined) {
 
                choice.find("div").replaceWith("<div>"+formatted+"</div>");
 
                choice.find("div").replaceWith($("<div></div>").html(formatted));
 
            }
 
            cssClass=this.opts.formatSelectionCssClass(data, choice.find("div"));
 
            if (cssClass != undefined) {
 
                choice.addClass(cssClass);
 
            }
 

	
 
@@ -3052,14 +3278,13 @@ the specific language governing permissi
 
              }));
 
            }
 

	
 
            choice.data("select2-data", data);
 
            choice.insertBefore(this.searchContainer);
 

	
 
            val.push(id);
 
            this.setVal(val);
 
            return id;
 
        },
 

	
 
        // multi
 
        unselect: function (selected) {
 
            var val = this.getVal(),
 
                data,
 
@@ -3122,13 +3347,13 @@ the specific language governing permissi
 
                if (!choice.is('.select2-result-selectable')
 
                    && choice.find(".select2-result-selectable:not(.select2-selected)").length === 0) {
 
                    choice.addClass("select2-selected");
 
                }
 
            });
 

	
 
            if (this.highlight() == -1 && noHighlightUpdate !== false){
 
            if (this.highlight() == -1 && noHighlightUpdate !== false && this.opts.closeOnSelect === true){
 
                self.highlight(0);
 
            }
 

	
 
            //If all results are chosen render formatNoMatches
 
            if(!this.opts.createSearchChoice && !choices.filter('.select2-result:not(.select2-selected)').length > 0){
 
                if(!data || data && !data.more && this.results.find(".select2-no-results").length === 0) {
 
@@ -3179,26 +3404,28 @@ the specific language governing permissi
 
            var val;
 
            if (this.select) {
 
                val = this.select.val();
 
                return val === null ? [] : val;
 
            } else {
 
                val = this.opts.element.val();
 
                return splitVal(val, this.opts.separator);
 
                return splitVal(val, this.opts.separator, this.opts.transformVal);
 
            }
 
        },
 

	
 
        // multi
 
        setVal: function (val) {
 
            var unique;
 
            if (this.select) {
 
                this.select.val(val);
 
            } else {
 
                unique = [];
 
                var unique = [], valMap = {};
 
                // filter out duplicates
 
                $(val).each(function () {
 
                    if (indexOf(this, unique) < 0) unique.push(this);
 
                    if (!(this in valMap)) {
 
                        unique.push(this);
 
                        valMap[this] = 0;
 
                    }
 
                });
 
                this.opts.element.val(unique.length === 0 ? "" : unique.join(this.opts.separator));
 
            }
 
        },
 

	
 
        // multi
 
@@ -3208,17 +3435,15 @@ the specific language governing permissi
 

	
 
            // remove intersection from each array
 
            for (var i = 0; i < current.length; i++) {
 
                for (var j = 0; j < old.length; j++) {
 
                    if (equal(this.opts.id(current[i]), this.opts.id(old[j]))) {
 
                        current.splice(i, 1);
 
                        if(i>0){
 
                        	i--;
 
                        }
 
                        old.splice(j, 1);
 
                        j--;
 
                        break;
 
                    }
 
                }
 
            }
 

	
 
            return {added: current, removed: old};
 
        },
 
@@ -3382,45 +3607,53 @@ the specific language governing permissi
 
        });
 
        return (value === undefined) ? this : value;
 
    };
 

	
 
    // plugin defaults, accessible to users
 
    $.fn.select2.defaults = {
 
        debug: false,
 
        width: "copy",
 
        loadMorePadding: 0,
 
        closeOnSelect: true,
 
        openOnEnter: true,
 
        containerCss: {},
 
        dropdownCss: {},
 
        containerCssClass: "",
 
        dropdownCssClass: "",
 
        formatResult: function(result, container, query, escapeMarkup) {
 
            var markup=[];
 
            markMatch(result.text, query.term, markup, escapeMarkup);
 
            markMatch(this.text(result), query.term, markup, escapeMarkup);
 
            return markup.join("");
 
        },
 
        transformVal: function(val) {
 
            return $.trim(val);
 
        },
 
        formatSelection: function (data, container, escapeMarkup) {
 
            return data ? escapeMarkup(data.text) : undefined;
 
            return data ? escapeMarkup(this.text(data)) : undefined;
 
        },
 
        sortResults: function (results, container, query) {
 
            return results;
 
        },
 
        formatResultCssClass: function(data) {return data.css;},
 
        formatSelectionCssClass: function(data, container) {return undefined;},
 
        formatMatches: function (matches) { if (matches === 1) { return "One result is available, press enter to select it."; } return matches + " results are available, use up and down arrow keys to navigate."; },
 
        formatNoMatches: function () { return "No matches found"; },
 
        formatInputTooShort: function (input, min) { var n = min - input.length; return "Please enter " + n + " or more character" + (n == 1? "" : "s"); },
 
        formatInputTooLong: function (input, max) { var n = input.length - max; return "Please delete " + n + " character" + (n == 1? "" : "s"); },
 
        formatSelectionTooBig: function (limit) { return "You can only select " + limit + " item" + (limit == 1 ? "" : "s"); },
 
        formatLoadMore: function (pageNumber) { return "Loading more results…"; },
 
        formatSearching: function () { return "Searching…"; },
 
        minimumResultsForSearch: 0,
 
        minimumInputLength: 0,
 
        maximumInputLength: null,
 
        maximumSelectionSize: 0,
 
        id: function (e) { return e == undefined ? null : e.id; },
 
        text: function (e) {
 
          if (e && this.data && this.data.text) {
 
            if ($.isFunction(this.data.text)) {
 
              return this.data.text(e);
 
            } else {
 
              return e[this.data.text];
 
            }
 
          } else {
 
            return e.text;
 
          }
 
        },
 
        matcher: function(term, text) {
 
            return stripDiacritics(''+text).toUpperCase().indexOf(stripDiacritics(''+term).toUpperCase()) >= 0;
 
        },
 
        separator: ",",
 
        tokenSeparators: [],
 
        tokenizer: defaultTokenizer,
 
@@ -3448,12 +3681,27 @@ the specific language governing permissi
 
            }
 

	
 
            return true;
 
        }
 
    };
 

	
 
    $.fn.select2.locales = [];
 

	
 
    $.fn.select2.locales['en'] = {
 
         formatMatches: function (matches) { if (matches === 1) { return "One result is available, press enter to select it."; } return matches + " results are available, use up and down arrow keys to navigate."; },
 
         formatNoMatches: function () { return "No matches found"; },
 
         formatAjaxError: function (jqXHR, textStatus, errorThrown) { return "Loading failed"; },
 
         formatInputTooShort: function (input, min) { var n = min - input.length; return "Please enter " + n + " or more character" + (n == 1 ? "" : "s"); },
 
         formatInputTooLong: function (input, max) { var n = input.length - max; return "Please delete " + n + " character" + (n == 1 ? "" : "s"); },
 
         formatSelectionTooBig: function (limit) { return "You can only select " + limit + " item" + (limit == 1 ? "" : "s"); },
 
         formatLoadMore: function (pageNumber) { return "Loading more results…"; },
 
         formatSearching: function () { return "Searching…"; }
 
    };
 

	
 
    $.extend($.fn.select2.defaults, $.fn.select2.locales['en']);
 

	
 
    $.fn.select2.ajaxDefaults = {
 
        transport: $.ajax,
 
        params: {
 
            type: "GET",
 
            cache: false,
 
            dataType: "json"
0 comments (0 inline, 0 general)