\",\r\n \"
\",\r\n \" \",\r\n \" \",\r\n \"
\",\r\n \"
\",\r\n \"
\"].join(\"\"));\r\n return container;\r\n },\r\n\r\n // single\r\n enableInterface: function() {\r\n if (this.parent.enableInterface.apply(this, arguments)) {\r\n this.focusser.prop(\"disabled\", !this.isInterfaceEnabled());\r\n }\r\n },\r\n\r\n // single\r\n opening: function () {\r\n var el, range, len;\r\n\r\n if (this.opts.minimumResultsForSearch >= 0) {\r\n this.showSearch(true);\r\n }\r\n\r\n this.parent.opening.apply(this, arguments);\r\n\r\n if (this.showSearchInput !== false) {\r\n // IE appends focusser.val() at the end of field :/ so we manually insert it at the beginning using a range\r\n // all other browsers handle this just fine\r\n\r\n this.search.val(this.focusser.val());\r\n }\r\n if (this.opts.shouldFocusInput(this)) {\r\n if (!this.probablyMobile) {\r\n this.search.focus();\r\n // move the cursor to the end after focussing, otherwise it will be at the beginning and\r\n // new text will appear *before* focusser.val()\r\n el = this.search.get(0);\r\n if (el.createTextRange) {\r\n range = el.createTextRange();\r\n range.collapse(false);\r\n range.select();\r\n } else if (el.setSelectionRange) {\r\n len = this.search.val().length;\r\n el.setSelectionRange(len, len);\r\n }\r\n }\r\n }\r\n\r\n // initializes search's value with nextSearchTerm (if defined by user)\r\n // ignore nextSearchTerm if the dropdown is opened by the user pressing a letter\r\n if(this.search.val() === \"\") {\r\n if(this.nextSearchTerm != undefined){\r\n this.search.val(this.nextSearchTerm);\r\n this.search.select();\r\n }\r\n }\r\n\r\n this.focusser.prop(\"disabled\", true).val(\"\");\r\n this.updateResults(true);\r\n this.opts.element.trigger($.Event(\"select2-open\"));\r\n },\r\n\r\n // single\r\n close: function () {\r\n if (!this.opened()) return;\r\n this.parent.close.apply(this, arguments);\r\n\r\n this.focusser.prop(\"disabled\", false);\r\n\r\n if (this.opts.shouldFocusInput(this)) {\r\n //this.focusser.focus();\r\n this.container.focus();\r\n }\r\n },\r\n\r\n // single\r\n focus: function () {\r\n if (this.opened()) {\r\n this.close();\r\n } else {\r\n //this.focusser.prop(\"disabled\", false);\r\n if (this.opts.shouldFocusInput(this)) {\r\n this.container.focus();\r\n }\r\n }\r\n },\r\n\r\n // single\r\n isFocused: function () {\r\n return this.container.hasClass(\"select2-container-active\");\r\n },\r\n\r\n // single\r\n cancel: function () {\r\n this.parent.cancel.apply(this, arguments);\r\n this.focusser.prop(\"disabled\", false);\r\n\r\n if (this.opts.shouldFocusInput(this)) {\r\n this.focusser.focus();\r\n }\r\n },\r\n\r\n // single\r\n destroy: function() {\r\n $(\"label[for='\" + this.focusser.attr('id') + \"']\")\r\n .attr('for', this.opts.element.attr(\"id\"));\r\n this.parent.destroy.apply(this, arguments);\r\n\r\n cleanupJQueryElements.call(this,\r\n \"selection\",\r\n \"focusser\"\r\n );\r\n },\r\n\r\n // single\r\n initContainer: function () {\r\n\r\n var selection,\r\n container = this.container,\r\n dropdown = this.dropdown,\r\n idSuffix = nextUid(),\r\n elementLabel;\r\n\r\n if (this.opts.minimumResultsForSearch < 0) {\r\n this.showSearch(false);\r\n } else {\r\n this.showSearch(true);\r\n }\r\n\r\n this.selection = selection = container.find(\".select2-choice\");\r\n\r\n this.focusser = container.find(\".select2-focusser\");\r\n\r\n // add aria associations\r\n selection.find(\".select2-chosen\").attr(\"id\", \"select2-chosen-\"+idSuffix);\r\n this.focusser.attr(\"aria-labelledby\", \"select2-chosen-\"+idSuffix);\r\n this.results.attr(\"id\", \"select2-results-\"+idSuffix);\r\n this.search.attr(\"aria-owns\", \"select2-results-\"+idSuffix);\r\n this.selection.attr(\"aria-label\", \"Select\");\r\n\r\n // rewrite labels from original element to focusser\r\n this.focusser.attr(\"id\", \"s2id_autogen\"+idSuffix);\r\n\r\n elementLabel = $(\"label[for='\" + this.opts.element.attr(\"id\") + \"']\");\r\n\r\n this.focusser.prev()\r\n .text(elementLabel.text())\r\n .attr('for', this.focusser.attr('id'));\r\n\r\n // Ensure the original element retains an accessible name\r\n var originalTitle = this.opts.element.attr(\"title\");\r\n this.opts.element.attr(\"title\", (originalTitle || elementLabel.text()));\r\n\r\n this.focusser.attr(\"tabindex\", this.elementTabIndex);\r\n\r\n // write label for search field using the label from the focusser element\r\n this.search.attr(\"id\", this.focusser.attr('id') + '_search');\r\n\r\n this.search.prev()\r\n .text($(\"label[for='\" + this.focusser.attr('id') + \"']\").text())\r\n .attr('for', this.search.attr('id'));\r\n\r\n this.search.on(\"keydown\", this.bind(function (e) {\r\n if (!this.isInterfaceEnabled()) return;\r\n\r\n if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) {\r\n // prevent the page from scrolling\r\n killEvent(e);\r\n return;\r\n }\r\n\r\n switch (e.which) {\r\n case KEY.UP:\r\n case KEY.DOWN:\r\n this.moveHighlight((e.which === KEY.UP) ? -1 : 1);\r\n killEvent(e);\r\n return;\r\n case KEY.ENTER:\r\n this.selectHighlighted();\r\n killEvent(e);\r\n return;\r\n case KEY.TAB:\r\n this.selectHighlighted({noFocus: true});\r\n return;\r\n case KEY.ESC:\r\n this.cancel(e);\r\n killEvent(e);\r\n return;\r\n }\r\n }));\r\n\r\n this.search.on(\"blur\", this.bind(function(e) {\r\n // a workaround for chrome to keep the search field focussed when the scroll bar is used to scroll the dropdown.\r\n // without this the search field loses focus which is annoying\r\n if (document.activeElement === this.body.get(0)) {\r\n window.setTimeout(this.bind(function() {\r\n if (this.opened()) {\r\n this.search.focus();\r\n }\r\n }), 0);\r\n }\r\n }));\r\n\r\n this.container.on(\"keydown\", this.bind(function (e) {\r\n if (!this.isInterfaceEnabled()) return;\r\n\r\n if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) {\r\n return;\r\n }\r\n\r\n if (this.opts.openOnEnter === false && e.which === KEY.ENTER) {\r\n killEvent(e);\r\n return;\r\n }\r\n\r\n if (e.which == KEY.DOWN || e.which == KEY.UP\r\n || (e.which == KEY.ENTER && this.opts.openOnEnter)) {\r\n\r\n if (e.altKey || e.ctrlKey || e.shiftKey || e.metaKey) return;\r\n\r\n this.open();\r\n killEvent(e);\r\n return;\r\n }\r\n\r\n if (e.which == KEY.DELETE || e.which == KEY.BACKSPACE) {\r\n if (this.opts.allowClear) {\r\n this.clear();\r\n }\r\n killEvent(e);\r\n return;\r\n }\r\n }));\r\n\r\n\r\n// this.container.on(\"focus\", this.bind(function (e) {\r\n// this.container.addClass('select2-container-active');\r\n// //this.focusser.focus();\r\n// }));\r\n\r\n installKeyUpChangeEvent(this.focusser);\r\n this.container.on(\"keyup-change input\", this.bind(function(e) {\r\n if (this.opts.minimumResultsForSearch >= 0) {\r\n e.stopPropagation();\r\n if (this.opened()) return;\r\n this.open();\r\n }\r\n }));\r\n\r\n selection.on(\"mousedown touchstart\", \"abbr\", this.bind(function (e) {\r\n if (!this.isInterfaceEnabled()) return;\r\n this.clear();\r\n killEventImmediately(e);\r\n this.close();\r\n this.selection.focus();\r\n }));\r\n\r\n selection.on(\"mousedown touchstart\", this.bind(function (e) {\r\n\r\n killEvent(e);\r\n\r\n //setTimeout(function(){}, 10);\r\n\r\n // Prevent IE from generating a click event on the body\r\n reinsertElement(selection);\r\n\r\n if (!this.container.hasClass(\"select2-container-active\")) {\r\n this.opts.element.trigger($.Event(\"select2-focus\"));\r\n }\r\n\r\n if (this.opened()) {\r\n this.close();\r\n } else if (this.isInterfaceEnabled()) {\r\n this.open();\r\n }\r\n\r\n\r\n }));\r\n\r\n dropdown.on(\"mousedown touchstart\", this.bind(function() {\r\n if (this.opts.shouldFocusInput(this) && !this.probablyMobile) {\r\n this.search.focus();\r\n }\r\n }));\r\n\r\n selection.on(\"focus\", this.bind(function(e) {\r\n killEvent(e);\r\n }));\r\n\r\n this.container.on(\"focus\", this.bind(function(){\r\n if (!this.container.hasClass(\"select2-container-active\")) {\r\n this.opts.element.trigger($.Event(\"select2-focus\"));\r\n }\r\n this.container.addClass(\"select2-container-active\");\r\n })).on(\"blur\", this.bind(function() {\r\n if (!this.opened()) {\r\n this.container.removeClass(\"select2-container-active\");\r\n this.opts.element.trigger($.Event(\"select2-blur\"));\r\n }\r\n }));\r\n this.search.on(\"focus\", this.bind(function(){\r\n if (!this.container.hasClass(\"select2-container-active\")) {\r\n this.opts.element.trigger($.Event(\"select2-focus\"));\r\n }\r\n this.container.addClass(\"select2-container-active\");\r\n }));\r\n\r\n this.initContainerWidth();\r\n this.opts.element.addClass(\"select2-offscreen\");\r\n this.setPlaceholder();\r\n\r\n },\r\n\r\n // single\r\n clear: function(triggerChange) {\r\n var data=this.selection.data(\"select2-data\");\r\n if (data) { // guard against queued quick consecutive clicks\r\n var evt = $.Event(\"select2-clearing\");\r\n this.opts.element.trigger(evt);\r\n if (evt.isDefaultPrevented()) {\r\n return;\r\n }\r\n var placeholderOption = this.getPlaceholderOption();\r\n this.opts.element.val(placeholderOption ? placeholderOption.val() : \"\");\r\n this.selection.find(\".select2-chosen\").empty();\r\n this.selection.removeData(\"select2-data\");\r\n this.setPlaceholder();\r\n\r\n if (triggerChange !== false){\r\n this.opts.element.trigger({ type: \"select2-removed\", val: this.id(data), choice: data });\r\n this.triggerChange({removed:data});\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Sets selection based on source element's value\r\n */\r\n // single\r\n initSelection: function () {\r\n var selected;\r\n if (this.isPlaceholderOptionSelected()) {\r\n this.updateSelection(null);\r\n this.close();\r\n this.setPlaceholder();\r\n } else {\r\n var self = this;\r\n this.opts.initSelection.call(null, this.opts.element, function(selected){\r\n if (selected !== undefined && selected !== null) {\r\n self.updateSelection(selected);\r\n self.close();\r\n self.setPlaceholder();\r\n self.nextSearchTerm = self.opts.nextSearchTerm(selected, self.search.val());\r\n }\r\n });\r\n }\r\n },\r\n\r\n isPlaceholderOptionSelected: function() {\r\n var placeholderOption;\r\n if (this.getPlaceholder() === undefined) return false; // no placeholder specified so no option should be considered\r\n return ((placeholderOption = this.getPlaceholderOption()) !== undefined && placeholderOption.prop(\"selected\"))\r\n || (this.opts.element.val() === \"\")\r\n || (this.opts.element.val() === undefined)\r\n || (this.opts.element.val() === null);\r\n },\r\n\r\n // single\r\n prepareOpts: function () {\r\n var opts = this.parent.prepareOpts.apply(this, arguments),\r\n self=this;\r\n\r\n if (opts.element.get(0).tagName.toLowerCase() === \"select\") {\r\n // install the selection initializer\r\n opts.initSelection = function (element, callback) {\r\n var selected = element.find(\"option\").filter(function() { return this.selected && !this.disabled });\r\n // a single select box always has a value, no need to null check 'selected'\r\n callback(self.optionToData(selected));\r\n };\r\n } else if (\"data\" in opts) {\r\n // install default initSelection when applied to hidden input and data is local\r\n opts.initSelection = opts.initSelection || function (element, callback) {\r\n var id = element.val();\r\n //search in data by id, storing the actual matching item\r\n var match = null;\r\n opts.query({\r\n matcher: function(term, text, el){\r\n var is_match = equal(id, opts.id(el));\r\n if (is_match) {\r\n match = el;\r\n }\r\n return is_match;\r\n },\r\n callback: !$.isFunction(callback) ? $.noop : function() {\r\n callback(match);\r\n }\r\n });\r\n };\r\n }\r\n\r\n return opts;\r\n },\r\n\r\n // single\r\n getPlaceholder: function() {\r\n // if a placeholder is specified on a single select without a valid placeholder option ignore it\r\n if (this.select) {\r\n if (this.getPlaceholderOption() === undefined) {\r\n return undefined;\r\n }\r\n }\r\n\r\n return this.parent.getPlaceholder.apply(this, arguments);\r\n },\r\n\r\n // single\r\n setPlaceholder: function () {\r\n var placeholder = this.getPlaceholder();\r\n\r\n if (this.isPlaceholderOptionSelected() && placeholder !== undefined) {\r\n\r\n // check for a placeholder option if attached to a select\r\n if (this.select && this.getPlaceholderOption() === undefined) return;\r\n\r\n this.selection.find(\".select2-chosen\").html(this.opts.escapeMarkup(placeholder));\r\n\r\n this.selection.addClass(\"select2-default\");\r\n\r\n this.container.removeClass(\"select2-allowclear\");\r\n }\r\n },\r\n\r\n // single\r\n postprocessResults: function (data, initial, noHighlightUpdate) {\r\n var selected = 0, self = this, showSearchInput = true;\r\n\r\n // find the selected element in the result list\r\n\r\n this.findHighlightableChoices().each2(function (i, elm) {\r\n if (equal(self.id(elm.data(\"select2-data\")), self.opts.element.val())) {\r\n selected = i;\r\n return false;\r\n }\r\n });\r\n\r\n // and highlight it\r\n if (noHighlightUpdate !== false) {\r\n if (initial === true && selected >= 0) {\r\n this.highlight(selected);\r\n } else {\r\n this.highlight(0);\r\n }\r\n }\r\n\r\n // hide the search box if this is the first we got the results and there are enough of them for search\r\n\r\n if (initial === true) {\r\n var min = this.opts.minimumResultsForSearch;\r\n if (min >= 0) {\r\n this.showSearch(countResults(data.results) >= min);\r\n }\r\n }\r\n },\r\n\r\n // single\r\n showSearch: function(showSearchInput) {\r\n if (this.showSearchInput === showSearchInput) return;\r\n\r\n this.showSearchInput = showSearchInput;\r\n\r\n this.dropdown.find(\".select2-search\").toggleClass(\"select2-search-hidden\", !showSearchInput);\r\n this.dropdown.find(\".select2-search\").toggleClass(\"select2-offscreen\", !showSearchInput);\r\n //add \"select2-with-searchbox\" to the container if search box is shown\r\n $(this.dropdown, this.container).toggleClass(\"select2-with-searchbox\", showSearchInput);\r\n },\r\n\r\n // single\r\n onSelect: function (data, options) {\r\n\r\n if (!this.triggerSelect(data)) { return; }\r\n\r\n var old = this.opts.element.val(),\r\n oldData = this.data();\r\n\r\n this.opts.element.val(this.id(data));\r\n this.updateSelection(data);\r\n\r\n this.opts.element.trigger({ type: \"select2-selected\", val: this.id(data), choice: data });\r\n\r\n this.nextSearchTerm = this.opts.nextSearchTerm(data, this.search.val());\r\n this.close();\r\n\r\n if ((!options || !options.noFocus) && this.opts.shouldFocusInput(this)) {\r\n this.focusser.focus();\r\n }\r\n\r\n if (!equal(old, this.id(data))) {\r\n this.triggerChange({ added: data, removed: oldData });\r\n }\r\n },\r\n\r\n // single\r\n updateSelection: function (data) {\r\n\r\n var container=this.selection.find(\".select2-chosen\"), formatted, cssClass;\r\n\r\n this.selection.data(\"select2-data\", data);\r\n\r\n container.empty();\r\n if (data !== null) {\r\n formatted=this.opts.formatSelection(data, container, this.opts.escapeMarkup);\r\n }\r\n if (formatted !== undefined) {\r\n container.append(formatted);\r\n }\r\n cssClass=this.opts.formatSelectionCssClass(data, container);\r\n if (cssClass !== undefined) {\r\n container.addClass(cssClass);\r\n }\r\n\r\n this.selection.removeClass(\"select2-default\");\r\n\r\n if (this.opts.allowClear && this.getPlaceholder() !== undefined) {\r\n this.container.addClass(\"select2-allowclear\");\r\n }\r\n },\r\n\r\n // single\r\n val: function () {\r\n var val,\r\n triggerChange = false,\r\n data = null,\r\n self = this,\r\n oldData = this.data();\r\n\r\n if (arguments.length === 0) {\r\n return this.opts.element.val();\r\n }\r\n\r\n val = arguments[0];\r\n\r\n if (arguments.length > 1) {\r\n triggerChange = arguments[1];\r\n }\r\n\r\n if (this.select) {\r\n this.select\r\n .val(val)\r\n .find(\"option\").filter(function() { return this.selected }).each2(function (i, elm) {\r\n data = self.optionToData(elm);\r\n return false;\r\n });\r\n this.updateSelection(data);\r\n this.setPlaceholder();\r\n if (triggerChange) {\r\n this.triggerChange({added: data, removed:oldData});\r\n }\r\n } else {\r\n // val is an id. !val is true for [undefined,null,'',0] - 0 is legal\r\n if (!val && val !== 0) {\r\n this.clear(triggerChange);\r\n return;\r\n }\r\n if (this.opts.initSelection === undefined) {\r\n throw new Error(\"cannot call val() if initSelection() is not defined\");\r\n }\r\n this.opts.element.val(val);\r\n this.opts.initSelection(this.opts.element, function(data){\r\n self.opts.element.val(!data ? \"\" : self.id(data));\r\n self.updateSelection(data);\r\n self.setPlaceholder();\r\n if (triggerChange) {\r\n self.triggerChange({added: data, removed:oldData});\r\n }\r\n });\r\n }\r\n },\r\n\r\n // single\r\n clearSearch: function () {\r\n this.search.val(\"\");\r\n this.focusser.val(\"\");\r\n },\r\n\r\n // single\r\n data: function(value) {\r\n var data,\r\n triggerChange = false;\r\n\r\n if (arguments.length === 0) {\r\n data = this.selection.data(\"select2-data\");\r\n if (data == undefined) data = null;\r\n return data;\r\n } else {\r\n if (arguments.length > 1) {\r\n triggerChange = arguments[1];\r\n }\r\n if (!value) {\r\n this.clear(triggerChange);\r\n } else {\r\n data = this.data();\r\n this.opts.element.val(!value ? \"\" : this.id(value));\r\n this.updateSelection(value);\r\n if (triggerChange) {\r\n this.triggerChange({added: value, removed:data});\r\n }\r\n }\r\n }\r\n }\r\n });\r\n\r\n MultiSelect2 = clazz(AbstractSelect2, {\r\n\r\n // multi\r\n createContainer: function () {\r\n var container = $(document.createElement(\"div\")).attr({\r\n \"class\": \"select2-container select2-container-multi\"\r\n }).html([\r\n \"