(function ($){ if (typeof $.fn.each2 == "undefined") { $.fn.extend({ each2: function (c){ var j = $([0] ), i = -1, l = _AN_Read_length("length", this); while (++i < l && (j.context = j[0] = this[i]) && c.call(j[0], i, j) !== false ); return this; } } ); } } )(jQuery); (function ($, undefined){ "use strict"; if (window.Select2 !== undefined) { return ; } var KEY, AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer, lastMousePosition = { x: 0, y: 0} , $document, scrollBarDimensions, KEY = { TAB: 9, ENTER: 13, ESC: 27, SPACE: 32, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40, SHIFT: 16, CTRL: 17, ALT: 18, PAGE_UP: 33, PAGE_DOWN: 34, HOME: 36, END: 35, BACKSPACE: 8, DELETE: 46, isArrow: function (k){ k = k.which? k.which: k; switch (k){ case KEY.LEFT: case KEY.RIGHT: case KEY.UP: case KEY.DOWN: return true ; } return false ; } , isControl: function (e){ var k = e.which; switch (k){ case KEY.SHIFT: case KEY.CTRL: case KEY.ALT: return true ; } if (e.metaKey) return true ; return false ; } , isFunctionKey: function (k){ k = k.which? k.which: k; return k >= 112 && k <= 123; } } , MEASURE_SCROLLBAR_TEMPLATE = "
"; $document = $(document); nextUid = (function (){ var counter = 1; return function (){ return counter++ ; } ; } ()); function indexOf(value, array){ var i = 0, l = _AN_Read_length("length", array); for (; i < l; i = i + 1){ if (equal(value, array[i])) return i; } return -1; } function measureScrollbar(){ var $template = $(MEASURE_SCROLLBAR_TEMPLATE); $template.appendTo('body'); var dim = { width: $template.width() - $template[0].clientWidth, height: $template.height() - $template[0].clientHeight} ; $template.remove(); return dim; } function equal(a, b){ if (a === b) return true ; if (a === undefined || b === undefined) return false ; if (a === null || b === null ) return false ; if (a.constructor === String) return a + '' === b + ''; if (b.constructor === String) return b + '' === a + ''; return false ; } function splitVal(string, separator){ var val, i, l; if (string === null || _AN_Read_length('length', string) < 1) return [] ; val = string.split(separator); for (i = 0, l = _AN_Read_length('length', val); i < l; i = i + 1)val[i] = $.trim(val[i]); return val; } function getSideBorderPadding(element){ return element.outerWidth(false ) - element.width(); } function installKeyUpChangeEvent(element){ var key = "keyup-change-value"; element.on("keydown", function (){ if ($.data(element, key) === undefined) { $.data(element, key, element.val()); } } ); element.on("keyup", function (){ var val = $.data(element, key); if (val !== undefined && element.val() !== val) { $.removeData(element, key); element.trigger("keyup-change"); } } ); } $document.on("mousemove", function (e){ lastMousePosition.x = e.pageX; lastMousePosition.y = e.pageY; } ); function installFilteredMouseMove(element){ element.on("mousemove", function (e){ var lastpos = lastMousePosition; if (lastpos === undefined || lastpos.x !== e.pageX || lastpos.y !== e.pageY) { $(_AN_Read_target("target", e)).trigger("mousemove-filtered", e); } } ); } function debounce(quietMillis, fn, ctx){ ctx = ctx || undefined; var timeout; return function (){ var args = arguments; window.clearTimeout(timeout); timeout = _AN_Call_settimeout("setTimeout", window, function (){ fn.apply(ctx, args); } , quietMillis); } ; } function thunk(formula){ var evaluated = false , value; return function (){ if (evaluated === false ) { value = formula(); evaluated = true ; } return value; } ; } ; function installDebouncedScroll(threshold, element){ var notify = debounce(threshold, function (e){ element.trigger("scroll-debounced", e); } ); element.on("scroll", function (e){ if (indexOf(_AN_Read_target("target", e), element.get()) >= 0) notify(e); } ); } function focus($el){ if ($el[0] === document.activeElement) return ; _AN_Call_settimeout("setTimeout", window, function (){ var el = $el[0], pos = _AN_Read_length("length", $el.val()), range; $el.focus(); if ($el.is(":visible") && el === document.activeElement) { if (el.setSelectionRange) { el.setSelectionRange(pos, pos); } else if (el.createTextRange) { range = el.createTextRange(); range.collapse(false ); range.select(); } } } , 0); } function getCursorInfo(el){ el = $(el)[0]; var offset = 0; var length = 0; if ('selectionStart' in el) { offset = el.selectionStart; length = el.selectionEnd - offset; } else if ('selection' in document) { el.focus(); var sel = document.selection.createRange(); length = _AN_Read_length('length', document.selection.createRange().text); sel.moveStart('character', - _AN_Read_length('length', el.value)); offset = _AN_Read_length('length', sel.text) - length; } return { offset: offset, length: length} ; } function killEvent(event){ event.preventDefault(); event.stopPropagation(); } function killEventImmediately(event){ event.preventDefault(); event.stopImmediatePropagation(); } function measureTextWidth(e){ if (!sizer) { var style = e[0].currentStyle || window.getComputedStyle(e[0], null ); sizer = $(_AN_Call_createelement('createElement', document, "div")).css({ position: "absolute", left: "-10000px", top: "-10000px", display: "none", fontSize: style.fontSize, fontFamily: style.fontFamily, fontStyle: style.fontStyle, fontWeight: style.fontWeight, letterSpacing: style.letterSpacing, textTransform: style.textTransform, whiteSpace: "nowrap"} ); sizer.attr("class", "select2-sizer"); $("body").append(sizer); } sizer.text(e.val()); return sizer.width(); } function syncCssClasses(dest, src, adapter){ var classes, replacements = [] , adapted; classes = dest.attr("class"); if (classes) { classes = '' + classes; $(classes.split(" ")).each2(function (){ if (this.indexOf("select2-") === 0) { replacements.push(this); } } ); } classes = src.attr("class"); if (classes) { classes = '' + classes; $(classes.split(" ")).each2(function (){ if (this.indexOf("select2-") !== 0) { adapted = adapter(this); if (adapted) { replacements.push(this); } } } ); } dest.attr("class", replacements.join(" ")); } function markMatch(text, term, markup, escapeMarkup){ var match = text.toUpperCase().indexOf(term.toUpperCase()), tl = _AN_Read_length("length", term); if (match < 0) { markup.push(escapeMarkup(text)); return ; } markup.push(escapeMarkup(text.substring(0, match))); markup.push(""); markup.push(escapeMarkup(text.substring(match, match + tl))); markup.push(""); markup.push(escapeMarkup(text.substring(match + tl, _AN_Read_length("length", text)))); } function defaultEscapeMarkup(markup){ var replace_map = { '\\': '\', '&': '&', '<': '<', '>': '>', '"': '"', "'": ''', "/": '/'} ; return _AN_Call_replace('replace', String(markup), /[&<>"'\/\\]/g, function (match){ return replace_map[match]; } ); } function ajax(options){ var timeout, requestSequence = 0, handler = null , quietMillis = options.quietMillis || 100, ajaxUrl = _AN_Read_url('url', options), self = this; return function (query){ window.clearTimeout(timeout); timeout = _AN_Call_settimeout('setTimeout', window, function (){ requestSequence += 1; var requestNumber = requestSequence, data = options.data, url = ajaxUrl, transport = options.transport || $.fn.select2.ajaxDefaults.transport, deprecated = { type: options.type || 'GET', cache: options.cache || false , jsonpCallback: options.jsonpCallback || undefined, dataType: options.dataType || "json"} , params = $.extend({ } , $.fn.select2.ajaxDefaults.params, deprecated); data = data? data.call(self, query.term, query.page, query.context): null ; url = (typeof url === 'function')? url.call(self, query.term, query.page, query.context): url; if (handler) { handler.abort(); } if (options.params) { if ($.isFunction(options.params)) { $.extend(params, options.params.call(self)); } else { $.extend(params, options.params); } } $.extend(params, { url: url, dataType: options.dataType, data: data, success: function (data){ if (requestNumber < requestSequence) { return ; } var results = options.results(data, query.page); query.callback(results); } } ); handler = transport.call(self, params); } , quietMillis); } ; } function local(options){ var data = options, dataText, tmp, text = function (item){ return "" + item.text; } ; if ($.isArray(data)) { tmp = data; data = { results: tmp} ; } if ($.isFunction(data) === false ) { tmp = data; data = function (){ return tmp; } ; } var dataItem = data(); if (dataItem.text) { text = dataItem.text; if (!$.isFunction(text)) { dataText = dataItem.text; text = function (item){ return item[dataText]; } ; } } return function (query){ var t = query.term, filtered = { results: [] } , process; if (t === "") { query.callback(data()); return ; } process = function (datum, collection){ var group, attr; datum = datum[0]; if (datum.children) { group = { } ; for (attr in datum){ if (datum.hasOwnProperty(attr)) group[attr] = datum[attr]; } group.children = [] ; $(datum.children).each2(function (i, childDatum){ process(childDatum, group.children); } ); if (_AN_Read_length("length", group.children) || query.matcher(t, text(group), datum)) { collection.push(group); } } else { if (query.matcher(t, text(datum), datum)) { collection.push(datum); } } } ; $(data().results).each2(function (i, datum){ process(datum, filtered.results); } ); query.callback(filtered); } ; } function tags(data){ var isFunc = $.isFunction(data); return function (query){ var t = query.term, filtered = { results: [] } ; $(isFunc? data(): data).each(function (){ var isObject = this.text !== undefined, text = isObject? this.text: this; if (t === "" || query.matcher(t, text)) { filtered.results.push(isObject? this: { id: this, text: this} ); } } ); query.callback(filtered); } ; } function checkFormatter(formatter, formatterName){ if ($.isFunction(formatter)) return true ; if (!formatter) return false ; throw new Error(formatterName + " must be a function or a falsy value") } function evaluate(val){ return $.isFunction(val)? val(): val; } function countResults(results){ var count = 0; $.each(results, function (i, item){ if (item.children) { count += countResults(item.children); } else { count++ ; } } ); return count; } function defaultTokenizer(input, selection, selectCallback, opts){ var original = input, dupe = false , token, index, i, l, separator; if (!opts.createSearchChoice || !opts.tokenSeparators || _AN_Read_length("length", opts.tokenSeparators) < 1) return undefined; while (true ){ index = -1; for (i = 0, l = _AN_Read_length("length", opts.tokenSeparators); i < l; i++ ){ separator = opts.tokenSeparators[i]; index = input.indexOf(separator); if (index >= 0) break ; } if (index < 0) break ; token = input.substring(0, index); input = input.substring(index + _AN_Read_length("length", separator)); if (_AN_Read_length("length", token) > 0) { token = opts.createSearchChoice(token, selection); if (token !== undefined && token !== null && opts.id(token) !== undefined && opts.id(token) !== null ) { dupe = false ; for (i = 0, l = _AN_Read_length("length", selection); i < l; i++ ){ if (equal(opts.id(token), opts.id(selection[i]))) { dupe = true ; break ; } } if (!dupe) selectCallback(token); } } } if (original !== input) return input; } function clazz(SuperClass, methods){ var constructor = function (){ } ; constructor.prototype = new SuperClass(); constructor.prototype.constructor = constructor; constructor.prototype.parent = SuperClass.prototype; constructor.prototype = $.extend(constructor.prototype, methods); return constructor; } AbstractSelect2 = clazz(Object, { bind: function (func){ var self = this; return function (){ func.apply(self, arguments); } ; } , init: function (opts){ var results, search, resultsSelector = ".select2-results", disabled, readonly; this.opts = opts = this.prepareOpts(opts); this.id = opts.id; if (opts.element.data("select2") !== undefined && opts.element.data("select2") !== null ) { opts.element.data("select2").destroy(); } this.container = this.createContainer(); this.containerId = "s2id_" + (opts.element.attr("id") || "autogen" + nextUid()); this.containerSelector = "#" + _AN_Call_replace("replace", this.containerId, /([;&,\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '\\$1'); this.container.attr("id", this.containerId); this.body = thunk(function (){ return opts.element.closest("body"); } ); syncCssClasses(this.container, this.opts.element, this.opts.adaptContainerCssClass); this.container.css(evaluate(opts.containerCss)); this.container.addClass(evaluate(opts.containerCssClass)); this.elementTabIndex = this.opts.element.attr("tabindex"); this.opts.element.data("select2", this).attr("tabindex", "-1").before(this.container); this.container.data("select2", this); this.dropdown = this.container.find(".select2-drop"); this.dropdown.addClass(evaluate(opts.dropdownCssClass)); this.dropdown.data("select2", this); this.results = results = this.container.find(resultsSelector); _AN_Write_search("search", this, false , search = this.container.find("input.select2-input")); this.resultsPage = 0; this.context = null ; this.initContainer(); installFilteredMouseMove(this.results); this.dropdown.on("mousemove-filtered touchstart touchmove touchend", resultsSelector, this.bind(this.highlightUnderEvent)); installDebouncedScroll(80, this.results); this.dropdown.on("scroll-debounced", resultsSelector, this.bind(this.loadMoreIfNeeded)); $(this.container).on("change", ".select2-input", function (e){ e.stopPropagation(); } ); $(this.dropdown).on("change", ".select2-input", function (e){ e.stopPropagation(); } ); if ($.fn.mousewheel) { results.mousewheel(function (e, delta, deltaX, deltaY){ var top = results.scrollTop(), height; if (deltaY > 0 && top - deltaY <= 0) { results.scrollTop(0); killEvent(e); } else if (deltaY < 0 && results.get(0).scrollHeight - results.scrollTop() + deltaY <= results.height()) { results.scrollTop(results.get(0).scrollHeight - results.height()); killEvent(e); } } ); } installKeyUpChangeEvent(search); search.on("keyup-change input paste", this.bind(this.updateResults)); search.on("focus", function (){ search.addClass("select2-focused"); } ); search.on("blur", function (){ search.removeClass("select2-focused"); } ); this.dropdown.on("mouseup", resultsSelector, this.bind(function (e){ if (_AN_Read_length("length", $(_AN_Read_target("target", e)).closest(".select2-result-selectable")) > 0) { this.highlightUnderEvent(e); this.selectHighlighted(e); } } )); this.dropdown.on("click mouseup mousedown", function (e){ e.stopPropagation(); } ); if ($.isFunction(this.opts.initSelection)) { this.initSelection(); this.monitorSource(); } if (opts.maximumInputLength !== null ) { _AN_Read_search("search", this).attr("maxlength", opts.maximumInputLength); } var disabled = opts.element.prop("disabled"); if (disabled === undefined) disabled = false ; this.enable(!disabled); var readonly = opts.element.prop("readonly"); if (readonly === undefined) readonly = false ; this.readonly(readonly); scrollBarDimensions = scrollBarDimensions || measureScrollbar(); this.autofocus = opts.element.prop("autofocus"); opts.element.prop("autofocus", false ); if (this.autofocus) this.focus(); } , destroy: function (){ var element = this.opts.element, select2 = element.data("select2"); if (this.propertyObserver) { delete this.propertyObserver; this.propertyObserver = null ; } if (select2 !== undefined) { select2.container.remove(); select2.dropdown.remove(); element.removeClass("select2-offscreen").removeData("select2").off(".select2").prop("autofocus", this.autofocus || false ); if (this.elementTabIndex) { element.attr({ tabindex: this.elementTabIndex} ); } else { element.removeAttr("tabindex"); } _AN_Call_show("show", element); } } , optionToData: function (element){ if (element.is("option")) { return { id: element.prop("value"), text: element.text(), element: element.get(), css: element.attr("class"), disabled: element.prop("disabled"), locked: equal(element.attr("locked"), "locked") || equal(element.data("locked"), true )} ; } else if (element.is("optgroup")) { return { text: element.attr("label"), children: [] , element: element.get(), css: element.attr("class")} ; } } , prepareOpts: function (opts){ var element, select, idKey, ajaxUrl, self = this; element = opts.element; if (element.get(0).tagName.toLowerCase() === "select") { this.select = select = opts.element; } if (select) { $.each(["id", "multiple", "ajax", "query", "createSearchChoice", "initSelection", "data", "tags"] , function (){ if (this in opts) { throw new Error("Option '" + this + "' is not allowed for Select2 when attached to a ", "
", " ", " ", "
"] .join("")); return container; } , enableInterface: function (){ if (this.parent.enableInterface.apply(this, arguments)) { this.focusser.prop("disabled", !this.isInterfaceEnabled()); } } , opening: function (){ var el, range, len; if (this.opts.minimumResultsForSearch >= 0) { this.showSearch(true ); } this.parent.opening.apply(this, arguments); if (this.showSearchInput !== false ) { _AN_Read_search("search", this).val(this.focusser.val()); } _AN_Read_search("search", this).focus(); el = _AN_Read_search("search", this).get(0); if (el.createTextRange) { range = el.createTextRange(); range.collapse(false ); range.select(); } else if (el.setSelectionRange) { len = _AN_Read_length("length", _AN_Read_search("search", this).val()); el.setSelectionRange(len, len); } this.focusser.prop("disabled", true ).val(""); this.updateResults(true ); this.opts.element.trigger($.Event("select2-open")); } , close: function (){ if (!this.opened()) return ; this.parent.close.apply(this, arguments); this.focusser.removeAttr("disabled"); this.focusser.focus(); } , focus: function (){ if (this.opened()) { this.close(); } else { this.focusser.removeAttr("disabled"); this.focusser.focus(); } } , isFocused: function (){ return this.container.hasClass("select2-container-active"); } , cancel: function (){ this.parent.cancel.apply(this, arguments); this.focusser.removeAttr("disabled"); this.focusser.focus(); } , initContainer: function (){ var selection, container = this.container, dropdown = this.dropdown; if (this.opts.minimumResultsForSearch < 0) { this.showSearch(false ); } else { this.showSearch(true ); } this.selection = selection = container.find(".select2-choice"); this.focusser = container.find(".select2-focusser"); this.focusser.attr("id", "s2id_autogen" + nextUid()); $("label[for='" + this.opts.element.attr("id") + "']").attr('for', this.focusser.attr('id')); this.focusser.attr("tabindex", this.elementTabIndex); _AN_Read_search("search", this).on("keydown", this.bind(function (e){ if (!this.isInterfaceEnabled()) return ; if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) { killEvent(e); return ; } switch (e.which){ case KEY.UP: case KEY.DOWN: this.moveHighlight((e.which === KEY.UP)? -1: 1); killEvent(e); return ; case KEY.ENTER: this.selectHighlighted(); killEvent(e); return ; case KEY.TAB: this.selectHighlighted({ noFocus: true } ); return ; case KEY.ESC: this.cancel(e); killEvent(e); return ; } } )); _AN_Read_search("search", this).on("blur", this.bind(function (e){ if (document.activeElement === this.body().get(0)) { _AN_Call_settimeout("setTimeout", window, this.bind(function (){ _AN_Read_search("search", this).focus(); } ), 0); } } )); this.focusser.on("keydown", this.bind(function (e){ if (!this.isInterfaceEnabled()) return ; if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) { return ; } if (this.opts.openOnEnter === false && e.which === KEY.ENTER) { killEvent(e); return ; } if (e.which == KEY.DOWN || e.which == KEY.UP || (e.which == KEY.ENTER && this.opts.openOnEnter)) { if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) return ; _AN_Call_open("open", this); killEvent(e); return ; } if (e.which == KEY.DELETE || e.which == KEY.BACKSPACE) { if (this.opts.allowClear) { _AN_Call_clear("clear", this); } killEvent(e); return ; } } )); installKeyUpChangeEvent(this.focusser); this.focusser.on("keyup-change input", this.bind(function (e){ if (this.opts.minimumResultsForSearch >= 0) { e.stopPropagation(); if (this.opened()) return ; _AN_Call_open("open", this); } } )); selection.on("mousedown", "abbr", this.bind(function (e){ if (!this.isInterfaceEnabled()) return ; _AN_Call_clear("clear", this); killEventImmediately(e); this.close(); this.selection.focus(); } )); selection.on("mousedown", this.bind(function (e){ if (!this.container.hasClass("select2-container-active")) { this.opts.element.trigger($.Event("select2-focus")); } if (this.opened()) { this.close(); } else if (this.isInterfaceEnabled()) { _AN_Call_open("open", this); } killEvent(e); } )); dropdown.on("mousedown", this.bind(function (){ _AN_Read_search("search", this).focus(); } )); selection.on("focus", this.bind(function (e){ killEvent(e); } )); this.focusser.on("focus", this.bind(function (){ if (!this.container.hasClass("select2-container-active")) { this.opts.element.trigger($.Event("select2-focus")); } this.container.addClass("select2-container-active"); } )).on("blur", this.bind(function (){ if (!this.opened()) { this.container.removeClass("select2-container-active"); this.opts.element.trigger($.Event("select2-blur")); } } )); _AN_Read_search("search", this).on("focus", this.bind(function (){ if (!this.container.hasClass("select2-container-active")) { this.opts.element.trigger($.Event("select2-focus")); } this.container.addClass("select2-container-active"); } )); this.initContainerWidth(); this.opts.element.addClass("select2-offscreen"); this.setPlaceholder(); } , clear: function (triggerChange){ var data = this.selection.data("select2-data"); if (data) { var placeholderOption = this.getPlaceholderOption(); this.opts.element.val(placeholderOption? placeholderOption.val(): ""); this.selection.find(".select2-chosen").empty(); this.selection.removeData("select2-data"); this.setPlaceholder(); if (triggerChange !== false ) { this.opts.element.trigger({ type: "select2-removed", val: this.id(data), choice: data} ); this.triggerChange({ removed: data} ); } } } , initSelection: function (){ var selected; if (this.isPlaceholderOptionSelected()) { this.updateSelection([] ); this.close(); this.setPlaceholder(); } else { 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(); } } ); } } , isPlaceholderOptionSelected: function (){ var placeholderOption; return ((placeholderOption = this.getPlaceholderOption()) !== undefined && placeholderOption.is(':selected')) || (this.opts.element.val() === "") || (this.opts.element.val() === undefined) || (this.opts.element.val() === null ); } , prepareOpts: function (){ var opts = this.parent.prepareOpts.apply(this, arguments), self = this; if (opts.element.get(0).tagName.toLowerCase() === "select") { opts.initSelection = function (element, callback){ var selected = element.find(":selected"); callback(self.optionToData(selected)); } ; } else if ("data" in opts) { opts.initSelection = opts.initSelection || function (element, callback){ var id = element.val(); var match = null ; opts.query({ matcher: function (term, text, el){ var is_match = equal(id, opts.id(el)); if (is_match) { match = el; } return is_match; } , callback: !$.isFunction(callback)? $.noop: function (){ callback(match); } } ); } ; } return opts; } , getPlaceholder: function (){ if (this.select) { if (this.getPlaceholderOption() === undefined) { return undefined; } } return this.parent.getPlaceholder.apply(this, arguments); } , setPlaceholder: function (){ var placeholder = this.getPlaceholder(); if (this.isPlaceholderOptionSelected() && placeholder !== undefined) { if (this.select && this.getPlaceholderOption() === undefined) return ; this.selection.find(".select2-chosen").html(this.opts.escapeMarkup(placeholder)); this.selection.addClass("select2-default"); this.container.removeClass("select2-allowclear"); } } , postprocessResults: function (data, initial, noHighlightUpdate){ var selected = 0, self = this, showSearchInput = true ; this.findHighlightableChoices().each2(function (i, elm){ if (equal(self.id(elm.data("select2-data")), self.opts.element.val())) { selected = i; return false ; } } ); if (noHighlightUpdate !== false ) { if (initial === true && selected >= 0) { this.highlight(selected); } else { this.highlight(0); } } if (initial === true ) { var min = this.opts.minimumResultsForSearch; if (min >= 0) { this.showSearch(countResults(data.results) >= min); } } } , showSearch: function (showSearchInput){ if (this.showSearchInput === showSearchInput) return ; this.showSearchInput = showSearchInput; this.dropdown.find(".select2-search").toggleClass("select2-search-hidden", !showSearchInput); this.dropdown.find(".select2-search").toggleClass("select2-offscreen", !showSearchInput); $(this.dropdown, this.container).toggleClass("select2-with-searchbox", showSearchInput); } , onSelect: function (data, options){ if (!this.triggerSelect(data)) { return ; } var old = this.opts.element.val(), oldData = this.data(); this.opts.element.val(this.id(data)); this.updateSelection(data); this.opts.element.trigger({ type: "select2-selected", val: this.id(data), choice: data} ); this.close(); if (!options || !options.noFocus) this.selection.focus(); if (!equal(old, this.id(data))) { this.triggerChange({ added: data, removed: oldData} ); } } , updateSelection: function (data){ var container = this.selection.find(".select2-chosen"), formatted, cssClass; this.selection.data("select2-data", data); container.empty(); formatted = this.opts.formatSelection(data, container, this.opts.escapeMarkup); if (formatted !== undefined) { container.append(formatted); } cssClass = this.opts.formatSelectionCssClass(data, container); if (cssClass !== undefined) { container.addClass(cssClass); } this.selection.removeClass("select2-default"); if (this.opts.allowClear && this.getPlaceholder() !== undefined) { this.container.addClass("select2-allowclear"); } } , val: function (){ var val, triggerChange = false , data = null , self = this, oldData = this.data(); if (_AN_Read_length("length", arguments) === 0) { return this.opts.element.val(); } val = arguments[0]; if (_AN_Read_length("length", arguments) > 1) { triggerChange = arguments[1]; } if (this.select) { this.select.val(val).find(":selected").each2(function (i, elm){ data = self.optionToData(elm); return false ; } ); this.updateSelection(data); this.setPlaceholder(); if (triggerChange) { this.triggerChange({ added: data, removed: oldData} ); } } else { if (!val && val !== 0) { _AN_Call_clear("clear", this, triggerChange); return ; } if (this.opts.initSelection === undefined) { throw new Error("cannot call val() if initSelection() is not defined") } this.opts.element.val(val); this.opts.initSelection(this.opts.element, function (data){ self.opts.element.val(!data? "": self.id(data)); self.updateSelection(data); self.setPlaceholder(); if (triggerChange) { self.triggerChange({ added: data, removed: oldData} ); } } ); } } , clearSearch: function (){ _AN_Read_search("search", this).val(""); this.focusser.val(""); } , data: function (value, triggerChange){ var data; if (_AN_Read_length("length", arguments) === 0) { data = this.selection.data("select2-data"); if (data == undefined) data = null ; return data; } else { if (!value || value === "") { _AN_Call_clear("clear", this, triggerChange); } else { data = this.data(); this.opts.element.val(!value? "": this.id(value)); this.updateSelection(value); if (triggerChange) { this.triggerChange({ added: value, removed: data} ); } } } } } ); MultiSelect2 = clazz(AbstractSelect2, { createContainer: function (){ var container = $(_AN_Call_createelement("createElement", document, "div")).attr({ "class": "select2-container select2-container-multi"} ).html(["", "
", " ", "
"] .join("")); return container; } , prepareOpts: function (){ var opts = this.parent.prepareOpts.apply(this, arguments), self = this; if (opts.element.get(0).tagName.toLowerCase() === "select") { opts.initSelection = function (element, callback){ var data = [] ; element.find(":selected").each2(function (i, elm){ data.push(self.optionToData(elm)); } ); callback(data); } ; } else if ("data" in opts) { opts.initSelection = opts.initSelection || function (element, callback){ var ids = splitVal(element.val(), opts.separator); var matches = [] ; opts.query({ matcher: function (term, text, el){ var is_match = _AN_Read_length("length", $.grep(ids, function (id){ return equal(id, opts.id(el)); } )); if (is_match) { matches.push(el); } return is_match; } , callback: !$.isFunction(callback)? $.noop: function (){ var ordered = [] ; for (var i = 0; i < _AN_Read_length("length", ids); i++ ){ var id = ids[i]; for (var j = 0; j < _AN_Read_length("length", matches); j++ ){ var match = matches[j]; if (equal(id, opts.id(match))) { ordered.push(match); matches.splice(j, 1); break ; } } } callback(ordered); } } ); } ; } return opts; } , selectChoice: function (choice){ var selected = this.container.find(".select2-search-choice-focus"); if (_AN_Read_length("length", selected) && choice && choice[0] == selected[0]) { } else { if (selected.length) { this.opts.element.trigger("choice-deselected", selected); } selected.removeClass("select2-search-choice-focus"); if (choice && _AN_Read_length("length", choice)) { this.close(); choice.addClass("select2-search-choice-focus"); this.opts.element.trigger("choice-selected", choice); } } } , initContainer: function (){ 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("mousedown", ".select2-search-choice", function (e){ _AN_Read_search("search", _this)[0].focus(); _this.selectChoice($(this)); } ); _AN_Read_search("search", this).attr("id", "s2id_autogen" + nextUid()); $("label[for='" + this.opts.element.attr("id") + "']").attr('for', _AN_Read_search('search', this).attr('id')); _AN_Read_search('search', this).on("input paste", this.bind(function (){ if (!this.isInterfaceEnabled()) return ; if (!this.opened()) { _AN_Call_open("open", this); } } )); _AN_Read_search("search", this).attr("tabindex", this.elementTabIndex); this.keydowns = 0; _AN_Read_search("search", this).on("keydown", this.bind(function (e){ if (!this.isInterfaceEnabled()) return ; ++this.keydowns; var selected = selection.find(".select2-search-choice-focus"); var prev = selected.prev(".select2-search-choice:not(.select2-locked)"); var next = selected.next(".select2-search-choice:not(.select2-locked)"); var pos = getCursorInfo(_AN_Read_search("search", this)); if (_AN_Read_length("length", selected) && (e.which == KEY.LEFT || e.which == KEY.RIGHT || e.which == KEY.BACKSPACE || e.which == KEY.DELETE || e.which == KEY.ENTER)) { var selectedChoice = selected; if (e.which == KEY.LEFT && _AN_Read_length("length", prev)) { selectedChoice = prev; } else if (e.which == KEY.RIGHT) { selectedChoice = _AN_Read_length("length", next)? next: null ; } else if (e.which === KEY.BACKSPACE) { this.unselect(selected.first()); _AN_Read_search("search", this).width(10); selectedChoice = _AN_Read_length("length", prev)? prev: next; } else if (e.which == KEY.DELETE) { this.unselect(selected.first()); _AN_Read_search("search", this).width(10); selectedChoice = _AN_Read_length("length", next)? next: null ; } else if (e.which == KEY.ENTER) { selectedChoice = null ; } this.selectChoice(selectedChoice); killEvent(e); if (!selectedChoice || !_AN_Read_length("length", selectedChoice)) { _AN_Call_open("open", this); } return ; } else if (((e.which === KEY.BACKSPACE && this.keydowns == 1) || e.which == KEY.LEFT) && (pos.offset == 0 && !_AN_Read_length("length", pos))) { this.selectChoice(selection.find(".select2-search-choice:not(.select2-locked)").last()); killEvent(e); return ; } else { this.selectChoice(null ); } if (this.opened()) { switch (e.which){ case KEY.UP: case KEY.DOWN: this.moveHighlight((e.which === KEY.UP)? -1: 1); killEvent(e); return ; case KEY.ENTER: this.selectHighlighted(); killEvent(e); return ; case KEY.TAB: this.selectHighlighted({ noFocus: true } ); this.close(); return ; case KEY.ESC: this.cancel(e); killEvent(e); return ; } } if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.BACKSPACE || e.which === KEY.ESC) { return ; } if (e.which === KEY.ENTER) { if (this.opts.openOnEnter === false ) { return ; } else if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) { return ; } } _AN_Call_open("open", this); if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) { killEvent(e); } if (e.which === KEY.ENTER) { killEvent(e); } } )); _AN_Read_search("search", this).on("keyup", this.bind(function (e){ this.keydowns = 0; this.resizeSearch(); } )); _AN_Read_search("search", this).on("blur", this.bind(function (e){ this.container.removeClass("select2-container-active"); _AN_Read_search("search", this).removeClass("select2-focused"); this.selectChoice(null ); if (!this.opened()) this.clearSearch(); e.stopImmediatePropagation(); this.opts.element.trigger($.Event("select2-blur")); } )); this.container.on("click", selector, this.bind(function (e){ if (!this.isInterfaceEnabled()) return ; if (_AN_Read_length("length", $(_AN_Read_target("target", e)).closest(".select2-search-choice")) > 0) { return ; } this.selectChoice(null ); this.clearPlaceholder(); if (!this.container.hasClass("select2-container-active")) { this.opts.element.trigger($.Event("select2-focus")); } _AN_Call_open("open", this); this.focusSearch(); e.preventDefault(); } )); this.container.on("focus", selector, this.bind(function (){ if (!this.isInterfaceEnabled()) return ; if (!this.container.hasClass("select2-container-active")) { this.opts.element.trigger($.Event("select2-focus")); } this.container.addClass("select2-container-active"); this.dropdown.addClass("select2-drop-active"); this.clearPlaceholder(); } )); this.initContainerWidth(); this.opts.element.addClass("select2-offscreen"); this.clearSearch(); } , enableInterface: function (){ if (this.parent.enableInterface.apply(this, arguments)) { _AN_Read_search("search", this).prop("disabled", !this.isInterfaceEnabled()); } } , initSelection: function (){ var data; if (this.opts.element.val() === "" && this.opts.element.text() === "") { this.updateSelection([] ); this.close(); this.clearSearch(); } if (this.select || this.opts.element.val() !== "") { var self = this; this.opts.initSelection.call(null , this.opts.element, function (data){ if (data !== undefined && data !== null ) { self.updateSelection(data); self.close(); self.clearSearch(); } } ); } } , clearSearch: function (){ var placeholder = this.getPlaceholder(), maxWidth = this.getMaxSearchWidth(); if (placeholder !== undefined && _AN_Read_length("length", this.getVal()) === 0 && _AN_Read_search("search", this).hasClass("select2-focused") === false ) { _AN_Read_search("search", this).val(placeholder).addClass("select2-default"); _AN_Read_search("search", this).width(maxWidth > 0? maxWidth: this.container.css("width")); } else { _AN_Read_search("search", this).val("").width(10); } } , clearPlaceholder: function (){ if (_AN_Read_search("search", this).hasClass("select2-default")) { _AN_Read_search("search", this).val("").removeClass("select2-default"); } } , opening: function (){ this.clearPlaceholder(); this.resizeSearch(); this.parent.opening.apply(this, arguments); this.focusSearch(); this.updateResults(true ); _AN_Read_search("search", this).focus(); this.opts.element.trigger($.Event("select2-open")); } , close: function (){ if (!this.opened()) return ; this.parent.close.apply(this, arguments); } , focus: function (){ this.close(); _AN_Read_search("search", this).focus(); } , isFocused: function (){ return _AN_Read_search("search", this).hasClass("select2-focused"); } , updateSelection: function (data){ var ids = [] , filtered = [] , self = this; $(data).each(function (){ if (indexOf(self.id(this), ids) < 0) { ids.push(self.id(this)); filtered.push(this); } } ); data = filtered; this.selection.find(".select2-search-choice").remove(); $(data).each(function (){ self.addSelectedChoice(this); } ); self.postprocessResults(); } , tokenize: function (){ var input = _AN_Read_search("search", this).val(); input = this.opts.tokenizer(input, this.data(), this.bind(this.onSelect), this.opts); if (input != null && input != undefined) { _AN_Read_search("search", this).val(input); if (_AN_Read_length("length", input) > 0) { _AN_Call_open("open", this); } } } , onSelect: function (data, options){ if (!this.triggerSelect(data)) { return ; } this.addSelectedChoice(data); this.opts.element.trigger({ type: "selected", val: this.id(data), choice: data} ); if (this.select || !this.opts.closeOnSelect) this.postprocessResults(); if (this.opts.closeOnSelect) { this.close(); _AN_Read_search("search", this).width(10); } else { if (this.countSelectableResults() > 0) { _AN_Read_search("search", this).width(10); this.resizeSearch(); if (this.getMaximumSelectionSize() > 0 && _AN_Read_length("length", this.val()) >= this.getMaximumSelectionSize()) { this.updateResults(true ); } this.positionDropdown(); } else { this.close(); _AN_Read_search("search", this).width(10); } } this.triggerChange({ added: data} ); if (!options || !options.noFocus) this.focusSearch(); } , cancel: function (){ this.close(); this.focusSearch(); } , addSelectedChoice: function (data){ var enableChoice = !data.locked, enabledItem = $("
  • " + "
    " + " " + "
  • "), disabledItem = $("
  • " + "
    " + "
  • "); 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("
    " + formatted + "
    "); } cssClass = this.opts.formatSelectionCssClass(data, choice.find("div")); if (cssClass != undefined) { choice.addClass(cssClass); } if (enableChoice) { choice.find(".select2-search-choice-close").on("mousedown", killEvent).on("click dblclick", this.bind(function (e){ if (!this.isInterfaceEnabled()) return ; $(_AN_Read_target("target", e)).closest(".select2-search-choice").fadeOut('fast', this.bind(function (){ this.unselect($(_AN_Read_target('target', e))); this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus"); this.close(); this.focusSearch(); } )).dequeue(); killEvent(e); } )).on("focus", this.bind(function (){ if (!this.isInterfaceEnabled()) return ; this.container.addClass("select2-container-active"); this.dropdown.addClass("select2-drop-active"); } )); } choice.data("select2-data", data); choice.insertBefore(this.searchContainer); val.push(id); this.setVal(val); } , unselect: function (selected){ var val = this.getVal(), data, index; selected = selected.closest(".select2-search-choice"); if (_AN_Read_length("length", selected) === 0) { throw "Invalid argument: " + selected + ". Must be .select2-search-choice" } data = selected.data("select2-data"); if (!data) { return ; } index = indexOf(this.id(data), val); if (index >= 0) { val.splice(index, 1); this.setVal(val); if (this.select) this.postprocessResults(); } selected.remove(); this.opts.element.trigger({ type: "removed", val: this.id(data), choice: data} ); this.triggerChange({ removed: data} ); } , postprocessResults: function (data, initial, noHighlightUpdate){ var val = this.getVal(), choices = this.results.find(".select2-result"), compound = this.results.find(".select2-result-with-children"), self = this; choices.each2(function (i, choice){ var id = self.id(choice.data("select2-data")); if (indexOf(id, val) >= 0) { choice.addClass("select2-selected"); choice.find(".select2-result-selectable").addClass("select2-selected"); } } ); compound.each2(function (i, choice){ if (!choice.is('.select2-result-selectable') && _AN_Read_length('length', choice.find(".select2-result-selectable:not(.select2-selected)")) === 0) { choice.addClass("select2-selected"); } } ); if (this.highlight() == -1 && noHighlightUpdate !== false ) { self.highlight(0); } if (!this.opts.createSearchChoice && !_AN_Read_length("length", choices.filter('.select2-result:not(.select2-selected)')) > 0) { if (!data || data && !data.more && _AN_Read_length('length', this.results.find(".select2-no-results")) === 0) { if (checkFormatter(self.opts.formatNoMatches, "formatNoMatches")) { this.results.append("
  • " + self.opts.formatNoMatches(_AN_Read_search("search", self).val()) + "
  • "); } } } } , getMaxSearchWidth: function (){ return this.selection.width() - getSideBorderPadding(_AN_Read_search("search", this)); } , resizeSearch: function (){ var minimumWidth, left, maxWidth, containerLeft, searchWidth, sideBorderPadding = getSideBorderPadding(_AN_Read_search("search", this)); minimumWidth = measureTextWidth(_AN_Read_search("search", this)) + 10; left = _AN_Read_search("search", this).offset().left; maxWidth = this.selection.width(); containerLeft = this.selection.offset().left; searchWidth = maxWidth - (left - containerLeft) - sideBorderPadding; if (searchWidth < minimumWidth) { searchWidth = maxWidth - sideBorderPadding; } if (searchWidth < 40) { searchWidth = maxWidth - sideBorderPadding; } if (searchWidth <= 0) { searchWidth = minimumWidth; } _AN_Read_search("search", this).width(searchWidth); } , getVal: function (){ 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); } } , setVal: function (val){ var unique; if (this.select) { this.select.val(val); } else { unique = [] ; $(val).each(function (){ if (indexOf(this, unique) < 0) unique.push(this); } ); this.opts.element.val(_AN_Read_length("length", unique) === 0? "": unique.join(this.opts.separator)); } } , buildChangeDetails: function (old, current){ var current = current.slice(0), old = old.slice(0); for (var i = 0; i < _AN_Read_length("length", current); i++ ){ for (var j = 0; j < _AN_Read_length("length", old); j++ ){ if (equal(this.opts.id(current[i]), this.opts.id(old[j]))) { current.splice(i, 1); i-- ; old.splice(j, 1); j-- ; } } } return { added: current, removed: old} ; } , val: function (val, triggerChange){ var oldData, self = this, changeDetails; if (_AN_Read_length("length", arguments) === 0) { return this.getVal(); } oldData = this.data(); if (!_AN_Read_length("length", oldData)) oldData = [] ; if (!val && val !== 0) { this.opts.element.val(""); this.updateSelection([] ); this.clearSearch(); if (triggerChange) { this.triggerChange({ added: this.data(), removed: oldData} ); } return ; } this.setVal(val); if (this.select) { this.opts.initSelection(this.select, this.bind(this.updateSelection)); if (triggerChange) { this.triggerChange(this.buildChangeDetails(oldData, this.data())); } } else { if (this.opts.initSelection === undefined) { throw new Error("val() cannot be called if initSelection() is not defined") } this.opts.initSelection(this.opts.element, function (data){ var ids = $.map(data, self.id); self.setVal(ids); self.updateSelection(data); self.clearSearch(); if (triggerChange) { self.triggerChange(this.buildChangeDetails(oldData, this.data())); } } ); } this.clearSearch(); } , onSortStart: function (){ if (this.select) { throw new Error("Sorting of elements is not supported when attached to instead.") } _AN_Read_search("search", this).width(0); this.searchContainer.hide(); } , onSortEnd: function (){ var val = [] , self = this; _AN_Call_show("show", this.searchContainer); this.searchContainer.appendTo(this.searchContainer.parent()); this.resizeSearch(); this.selection.find(".select2-search-choice").each(function (){ val.push(self.opts.id($(this).data("select2-data"))); } ); this.setVal(val); this.triggerChange(); } , data: function (values, triggerChange){ var self = this, ids, old; if (_AN_Read_length("length", arguments) === 0) { return this.selection.find(".select2-search-choice").map(function (){ return $(this).data("select2-data"); } ).get(); } else { old = this.data(); if (!values) { values = [] ; } ids = $.map(values, function (e){ return self.opts.id(e); } ); this.setVal(ids); this.updateSelection(values); this.clearSearch(); if (triggerChange) { this.triggerChange(this.buildChangeDetails(old, this.data())); } } } } ); $.fn.select2 = function (){ var args = Array.prototype.slice.call(arguments, 0), opts, select2, method, value, multiple, allowedMethods = ["val", "destroy", "opened", "open", "close", "focus", "isFocused", "container", "dropdown", "onSortStart", "onSortEnd", "enable", "readonly", "positionDropdown", "data", "search"] , valueMethods = ["val", "opened", "isFocused", "container", "data"] , methodsMap = { search: "externalSearch"} ; this.each(function (){ if (_AN_Read_length("length", args) === 0 || typeof (args[0]) === "object") { opts = _AN_Read_length("length", args) === 0? { } : $.extend({ } , args[0]); opts.element = $(this); if (opts.element.get(0).tagName.toLowerCase() === "select") { multiple = opts.element.prop("multiple"); } else { multiple = opts.multiple || false ; if ("tags" in opts) { opts.multiple = multiple = true ; } } select2 = multiple? new MultiSelect2(): new SingleSelect2(); _AN_Call_init("init", select2, opts); } else if (typeof (args[0]) === "string") { if (indexOf(args[0], allowedMethods) < 0) { throw "Unknown method: " + args[0] } value = undefined; select2 = $(this).data("select2"); if (select2 === undefined) return ; method = args[0]; if (method === "container") { value = select2.container; } else if (method === "dropdown") { value = select2.dropdown; } else { if (methodsMap[method]) method = methodsMap[method]; value = select2[method].apply(select2, args.slice(1)); } if (indexOf(args[0], valueMethods) >= 0) { return false ; } } else { throw "Invalid arguments to select2 plugin: " + args } } ); return (value === undefined)? this: value; } ; $.fn.select2.defaults = { 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); return markup.join(""); } , formatSelection: function (data, container, escapeMarkup){ return data? escapeMarkup(data.text): undefined; } , sortResults: function (results, container, query){ return results; } , formatResultCssClass: function (data){ return undefined; } , formatSelectionCssClass: function (data, container){ return undefined; } , formatNoMatches: function (){ return "No matches found"; } , formatInputTooShort: function (input, min){ var n = min - _AN_Read_length("length", input); return "Please enter " + n + " more character" + (n == 1? "": "s"); } , formatInputTooLong: function (input, max){ var n = _AN_Read_length("length", input) - 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.id; } , matcher: function (term, text){ return ('' + text).toUpperCase().indexOf(('' + term).toUpperCase()) >= 0; } , separator: ",", tokenSeparators: [] , tokenizer: defaultTokenizer, escapeMarkup: defaultEscapeMarkup, blurOnChange: false , selectOnBlur: false , adaptContainerCssClass: function (c){ return c; } , adaptDropdownCssClass: function (c){ return null ; } } ; $.fn.select2.ajaxDefaults = { transport: $.ajax, params: { type: "GET", cache: false , dataType: "json"} } ; window.Select2 = { query: { ajax: ajax, local: local, tags: tags} , util: { debounce: debounce, markMatch: markMatch, escapeMarkup: defaultEscapeMarkup} , "class": { "abstract": AbstractSelect2, "single": SingleSelect2, "multi": MultiSelect2} } ; } (jQuery));