PluginProbe
Customify / 2.6.0
Customify v2.6.0
2.10.9 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.7.1 1.3.0 1.3.1 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.6.0 1.6.0.1 1.6.5 1.7.0 1.7.1 All 77 releases
customify / js / select2.js

select2.js in Customify 2.6.0, at js/select2.js

6,045 lines 148.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*!
2 * Select2 4.0.11
3 * https://select2.github.io
4 *
5 * Released under the MIT license
6 * https://github.com/select2/select2/blob/master/LICENSE.md
7 */
8 ;(function (factory) {
9 if (typeof define === 'function' && define.amd) {
10 // AMD. Register as an anonymous module.
11 define(['jquery'], factory);
12 } else if (typeof module === 'object' && module.exports) {
13 // Node/CommonJS
14 module.exports = function (root, jQuery) {
15 if (jQuery === undefined) {
16 // require('jQuery') returns a factory that requires window to
17 // build a jQuery instance, we normalize how we use modules
18 // that require this pattern but the window provided is a noop
19 // if it's defined (how jquery works)
20 if (typeof window !== 'undefined') {
21 jQuery = require('jquery');
22 }
23 else {
24 jQuery = require('jquery')(root);
25 }
26 }
27 factory(jQuery);
28 return jQuery;
29 };
30 } else {
31 // Browser globals
32 factory(jQuery);
33 }
34 } (function (jQuery) {
35 // This is needed so we can catch the AMD loader configuration and use it
36 // The inner file should be wrapped (by `banner.start.js`) in a function that
37 // returns the AMD loader references.
38 var S2 =(function () {
39 // Restore the Select2 AMD loader so it can be used
40 // Needed mostly in the language files, where the loader is not inserted
41 if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) {
42 var S2 = jQuery.fn.select2.amd;
43 }
44 var S2;(function () { if (!S2 || !S2.requirejs) {
45 if (!S2) { S2 = {}; } else { require = S2; }
46 /**
47 * @license almond 0.3.3 Copyright jQuery Foundation and other contributors.
48 * Released under MIT license, http://github.com/requirejs/almond/LICENSE
49 */
50 //Going sloppy to avoid 'use strict' string cost, but strict practices should
51 //be followed.
52 /*global setTimeout: false */
53
54 var requirejs, require, define;
55 (function (undef) {
56 var main, req, makeMap, handlers,
57 defined = {},
58 waiting = {},
59 config = {},
60 defining = {},
61 hasOwn = Object.prototype.hasOwnProperty,
62 aps = [].slice,
63 jsSuffixRegExp = /\.js$/;
64
65 function hasProp(obj, prop) {
66 return hasOwn.call(obj, prop);
67 }
68
69 /**
70 * Given a relative module name, like ./something, normalize it to
71 * a real name that can be mapped to a path.
72 * @param {String} name the relative name
73 * @param {String} baseName a real name that the name arg is relative
74 * to.
75 * @returns {String} normalized name
76 */
77 function normalize(name, baseName) {
78 var nameParts, nameSegment, mapValue, foundMap, lastIndex,
79 foundI, foundStarMap, starI, i, j, part, normalizedBaseParts,
80 baseParts = baseName && baseName.split("/"),
81 map = config.map,
82 starMap = (map && map['*']) || {};
83
84 //Adjust any relative paths.
85 if (name) {
86 name = name.split('/');
87 lastIndex = name.length - 1;
88
89 // If wanting node ID compatibility, strip .js from end
90 // of IDs. Have to do this here, and not in nameToUrl
91 // because node allows either .js or non .js to map
92 // to same file.
93 if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
94 name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
95 }
96
97 // Starts with a '.' so need the baseName
98 if (name[0].charAt(0) === '.' && baseParts) {
99 //Convert baseName to array, and lop off the last part,
100 //so that . matches that 'directory' and not name of the baseName's
101 //module. For instance, baseName of 'one/two/three', maps to
102 //'one/two/three.js', but we want the directory, 'one/two' for
103 //this normalization.
104 normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
105 name = normalizedBaseParts.concat(name);
106 }
107
108 //start trimDots
109 for (i = 0; i < name.length; i++) {
110 part = name[i];
111 if (part === '.') {
112 name.splice(i, 1);
113 i -= 1;
114 } else if (part === '..') {
115 // If at the start, or previous value is still ..,
116 // keep them so that when converted to a path it may
117 // still work when converted to a path, even though
118 // as an ID it is less than ideal. In larger point
119 // releases, may be better to just kick out an error.
120 if (i === 0 || (i === 1 && name[2] === '..') || name[i - 1] === '..') {
121 continue;
122 } else if (i > 0) {
123 name.splice(i - 1, 2);
124 i -= 2;
125 }
126 }
127 }
128 //end trimDots
129
130 name = name.join('/');
131 }
132
133 //Apply map config if available.
134 if ((baseParts || starMap) && map) {
135 nameParts = name.split('/');
136
137 for (i = nameParts.length; i > 0; i -= 1) {
138 nameSegment = nameParts.slice(0, i).join("/");
139
140 if (baseParts) {
141 //Find the longest baseName segment match in the config.
142 //So, do joins on the biggest to smallest lengths of baseParts.
143 for (j = baseParts.length; j > 0; j -= 1) {
144 mapValue = map[baseParts.slice(0, j).join('/')];
145
146 //baseName segment has config, find if it has one for
147 //this name.
148 if (mapValue) {
149 mapValue = mapValue[nameSegment];
150 if (mapValue) {
151 //Match, update name to the new value.
152 foundMap = mapValue;
153 foundI = i;
154 break;
155 }
156 }
157 }
158 }
159
160 if (foundMap) {
161 break;
162 }
163
164 //Check for a star map match, but just hold on to it,
165 //if there is a shorter segment match later in a matching
166 //config, then favor over this star map.
167 if (!foundStarMap && starMap && starMap[nameSegment]) {
168 foundStarMap = starMap[nameSegment];
169 starI = i;
170 }
171 }
172
173 if (!foundMap && foundStarMap) {
174 foundMap = foundStarMap;
175 foundI = starI;
176 }
177
178 if (foundMap) {
179 nameParts.splice(0, foundI, foundMap);
180 name = nameParts.join('/');
181 }
182 }
183
184 return name;
185 }
186
187 function makeRequire(relName, forceSync) {
188 return function () {
189 //A version of a require function that passes a moduleName
190 //value for items that may need to
191 //look up paths relative to the moduleName
192 var args = aps.call(arguments, 0);
193
194 //If first arg is not require('string'), and there is only
195 //one arg, it is the array form without a callback. Insert
196 //a null so that the following concat is correct.
197 if (typeof args[0] !== 'string' && args.length === 1) {
198 args.push(null);
199 }
200 return req.apply(undef, args.concat([relName, forceSync]));
201 };
202 }
203
204 function makeNormalize(relName) {
205 return function (name) {
206 return normalize(name, relName);
207 };
208 }
209
210 function makeLoad(depName) {
211 return function (value) {
212 defined[depName] = value;
213 };
214 }
215
216 function callDep(name) {
217 if (hasProp(waiting, name)) {
218 var args = waiting[name];
219 delete waiting[name];
220 defining[name] = true;
221 main.apply(undef, args);
222 }
223
224 if (!hasProp(defined, name) && !hasProp(defining, name)) {
225 throw new Error('No ' + name);
226 }
227 return defined[name];
228 }
229
230 //Turns a plugin!resource to [plugin, resource]
231 //with the plugin being undefined if the name
232 //did not have a plugin prefix.
233 function splitPrefix(name) {
234 var prefix,
235 index = name ? name.indexOf('!') : -1;
236 if (index > -1) {
237 prefix = name.substring(0, index);
238 name = name.substring(index + 1, name.length);
239 }
240 return [prefix, name];
241 }
242
243 //Creates a parts array for a relName where first part is plugin ID,
244 //second part is resource ID. Assumes relName has already been normalized.
245 function makeRelParts(relName) {
246 return relName ? splitPrefix(relName) : [];
247 }
248
249 /**
250 * Makes a name map, normalizing the name, and using a plugin
251 * for normalization if necessary. Grabs a ref to plugin
252 * too, as an optimization.
253 */
254 makeMap = function (name, relParts) {
255 var plugin,
256 parts = splitPrefix(name),
257 prefix = parts[0],
258 relResourceName = relParts[1];
259
260 name = parts[1];
261
262 if (prefix) {
263 prefix = normalize(prefix, relResourceName);
264 plugin = callDep(prefix);
265 }
266
267 //Normalize according
268 if (prefix) {
269 if (plugin && plugin.normalize) {
270 name = plugin.normalize(name, makeNormalize(relResourceName));
271 } else {
272 name = normalize(name, relResourceName);
273 }
274 } else {
275 name = normalize(name, relResourceName);
276 parts = splitPrefix(name);
277 prefix = parts[0];
278 name = parts[1];
279 if (prefix) {
280 plugin = callDep(prefix);
281 }
282 }
283
284 //Using ridiculous property names for space reasons
285 return {
286 f: prefix ? prefix + '!' + name : name, //fullName
287 n: name,
288 pr: prefix,
289 p: plugin
290 };
291 };
292
293 function makeConfig(name) {
294 return function () {
295 return (config && config.config && config.config[name]) || {};
296 };
297 }
298
299 handlers = {
300 require: function (name) {
301 return makeRequire(name);
302 },
303 exports: function (name) {
304 var e = defined[name];
305 if (typeof e !== 'undefined') {
306 return e;
307 } else {
308 return (defined[name] = {});
309 }
310 },
311 module: function (name) {
312 return {
313 id: name,
314 uri: '',
315 exports: defined[name],
316 config: makeConfig(name)
317 };
318 }
319 };
320
321 main = function (name, deps, callback, relName) {
322 var cjsModule, depName, ret, map, i, relParts,
323 args = [],
324 callbackType = typeof callback,
325 usingExports;
326
327 //Use name if no relName
328 relName = relName || name;
329 relParts = makeRelParts(relName);
330
331 //Call the callback to define the module, if necessary.
332 if (callbackType === 'undefined' || callbackType === 'function') {
333 //Pull out the defined dependencies and pass the ordered
334 //values to the callback.
335 //Default to [require, exports, module] if no deps
336 deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
337 for (i = 0; i < deps.length; i += 1) {
338 map = makeMap(deps[i], relParts);
339 depName = map.f;
340
341 //Fast path CommonJS standard dependencies.
342 if (depName === "require") {
343 args[i] = handlers.require(name);
344 } else if (depName === "exports") {
345 //CommonJS module spec 1.1
346 args[i] = handlers.exports(name);
347 usingExports = true;
348 } else if (depName === "module") {
349 //CommonJS module spec 1.1
350 cjsModule = args[i] = handlers.module(name);
351 } else if (hasProp(defined, depName) ||
352 hasProp(waiting, depName) ||
353 hasProp(defining, depName)) {
354 args[i] = callDep(depName);
355 } else if (map.p) {
356 map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
357 args[i] = defined[depName];
358 } else {
359 throw new Error(name + ' missing ' + depName);
360 }
361 }
362
363 ret = callback ? callback.apply(defined[name], args) : undefined;
364
365 if (name) {
366 //If setting exports via "module" is in play,
367 //favor that over return value and exports. After that,
368 //favor a non-undefined return value over exports use.
369 if (cjsModule && cjsModule.exports !== undef &&
370 cjsModule.exports !== defined[name]) {
371 defined[name] = cjsModule.exports;
372 } else if (ret !== undef || !usingExports) {
373 //Use the return value from the function.
374 defined[name] = ret;
375 }
376 }
377 } else if (name) {
378 //May just be an object definition for the module. Only
379 //worry about defining if have a module name.
380 defined[name] = callback;
381 }
382 };
383
384 requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
385 if (typeof deps === "string") {
386 if (handlers[deps]) {
387 //callback in this case is really relName
388 return handlers[deps](callback);
389 }
390 //Just return the module wanted. In this scenario, the
391 //deps arg is the module name, and second arg (if passed)
392 //is just the relName.
393 //Normalize module name, if it contains . or ..
394 return callDep(makeMap(deps, makeRelParts(callback)).f);
395 } else if (!deps.splice) {
396 //deps is a config object, not an array.
397 config = deps;
398 if (config.deps) {
399 req(config.deps, config.callback);
400 }
401 if (!callback) {
402 return;
403 }
404
405 if (callback.splice) {
406 //callback is an array, which means it is a dependency list.
407 //Adjust args if there are dependencies
408 deps = callback;
409 callback = relName;
410 relName = null;
411 } else {
412 deps = undef;
413 }
414 }
415
416 //Support require(['a'])
417 callback = callback || function () {};
418
419 //If relName is a function, it is an errback handler,
420 //so remove it.
421 if (typeof relName === 'function') {
422 relName = forceSync;
423 forceSync = alt;
424 }
425
426 //Simulate async callback;
427 if (forceSync) {
428 main(undef, deps, callback, relName);
429 } else {
430 //Using a non-zero value because of concern for what old browsers
431 //do, and latest browsers "upgrade" to 4 if lower value is used:
432 //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
433 //If want a value immediately, use require('id') instead -- something
434 //that works in almond on the global level, but not guaranteed and
435 //unlikely to work in other AMD implementations.
436 setTimeout(function () {
437 main(undef, deps, callback, relName);
438 }, 4);
439 }
440
441 return req;
442 };
443
444 /**
445 * Just drops the config on the floor, but returns req in case
446 * the config return value is used.
447 */
448 req.config = function (cfg) {
449 return req(cfg);
450 };
451
452 /**
453 * Expose module registry for debugging and tooling
454 */
455 requirejs._defined = defined;
456
457 define = function (name, deps, callback) {
458 if (typeof name !== 'string') {
459 throw new Error('See almond README: incorrect module build, no module name');
460 }
461
462 //This module may not have dependencies
463 if (!deps.splice) {
464 //deps is not an array, so probably means
465 //an object literal or factory function for
466 //the value. Adjust args.
467 callback = deps;
468 deps = [];
469 }
470
471 if (!hasProp(defined, name) && !hasProp(waiting, name)) {
472 waiting[name] = [name, deps, callback];
473 }
474 };
475
476 define.amd = {
477 jQuery: true
478 };
479 }());
480
481 S2.requirejs = requirejs;S2.require = require;S2.define = define;
482 }
483 }());
484 S2.define("almond", function(){});
485
486 /* global jQuery:false, $:false */
487 S2.define('jquery',[],function () {
488 var _$ = jQuery || $;
489
490 if (_$ == null && console && console.error) {
491 console.error(
492 'Select2: An instance of jQuery or a jQuery-compatible library was not ' +
493 'found. Make sure that you are including jQuery before Select2 on your ' +
494 'web page.'
495 );
496 }
497
498 return _$;
499 });
500
501 S2.define('select2/utils',[
502 'jquery'
503 ], function ($) {
504 var Utils = {};
505
506 Utils.Extend = function (ChildClass, SuperClass) {
507 var __hasProp = {}.hasOwnProperty;
508
509 function BaseConstructor () {
510 this.constructor = ChildClass;
511 }
512
513 for (var key in SuperClass) {
514 if (__hasProp.call(SuperClass, key)) {
515 ChildClass[key] = SuperClass[key];
516 }
517 }
518
519 BaseConstructor.prototype = SuperClass.prototype;
520 ChildClass.prototype = new BaseConstructor();
521 ChildClass.__super__ = SuperClass.prototype;
522
523 return ChildClass;
524 };
525
526 function getMethods (theClass) {
527 var proto = theClass.prototype;
528
529 var methods = [];
530
531 for (var methodName in proto) {
532 var m = proto[methodName];
533
534 if (typeof m !== 'function') {
535 continue;
536 }
537
538 if (methodName === 'constructor') {
539 continue;
540 }
541
542 methods.push(methodName);
543 }
544
545 return methods;
546 }
547
548 Utils.Decorate = function (SuperClass, DecoratorClass) {
549 var decoratedMethods = getMethods(DecoratorClass);
550 var superMethods = getMethods(SuperClass);
551
552 function DecoratedClass () {
553 var unshift = Array.prototype.unshift;
554
555 var argCount = DecoratorClass.prototype.constructor.length;
556
557 var calledConstructor = SuperClass.prototype.constructor;
558
559 if (argCount > 0) {
560 unshift.call(arguments, SuperClass.prototype.constructor);
561
562 calledConstructor = DecoratorClass.prototype.constructor;
563 }
564
565 calledConstructor.apply(this, arguments);
566 }
567
568 DecoratorClass.displayName = SuperClass.displayName;
569
570 function ctr () {
571 this.constructor = DecoratedClass;
572 }
573
574 DecoratedClass.prototype = new ctr();
575
576 for (var m = 0; m < superMethods.length; m++) {
577 var superMethod = superMethods[m];
578
579 DecoratedClass.prototype[superMethod] =
580 SuperClass.prototype[superMethod];
581 }
582
583 var calledMethod = function (methodName) {
584 // Stub out the original method if it's not decorating an actual method
585 var originalMethod = function () {};
586
587 if (methodName in DecoratedClass.prototype) {
588 originalMethod = DecoratedClass.prototype[methodName];
589 }
590
591 var decoratedMethod = DecoratorClass.prototype[methodName];
592
593 return function () {
594 var unshift = Array.prototype.unshift;
595
596 unshift.call(arguments, originalMethod);
597
598 return decoratedMethod.apply(this, arguments);
599 };
600 };
601
602 for (var d = 0; d < decoratedMethods.length; d++) {
603 var decoratedMethod = decoratedMethods[d];
604
605 DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod);
606 }
607
608 return DecoratedClass;
609 };
610
611 var Observable = function () {
612 this.listeners = {};
613 };
614
615 Observable.prototype.on = function (event, callback) {
616 this.listeners = this.listeners || {};
617
618 if (event in this.listeners) {
619 this.listeners[event].push(callback);
620 } else {
621 this.listeners[event] = [callback];
622 }
623 };
624
625 Observable.prototype.trigger = function (event) {
626 var slice = Array.prototype.slice;
627 var params = slice.call(arguments, 1);
628
629 this.listeners = this.listeners || {};
630
631 // Params should always come in as an array
632 if (params == null) {
633 params = [];
634 }
635
636 // If there are no arguments to the event, use a temporary object
637 if (params.length === 0) {
638 params.push({});
639 }
640
641 // Set the `_type` of the first object to the event
642 params[0]._type = event;
643
644 if (event in this.listeners) {
645 this.invoke(this.listeners[event], slice.call(arguments, 1));
646 }
647
648 if ('*' in this.listeners) {
649 this.invoke(this.listeners['*'], arguments);
650 }
651 };
652
653 Observable.prototype.invoke = function (listeners, params) {
654 for (var i = 0, len = listeners.length; i < len; i++) {
655 listeners[i].apply(this, params);
656 }
657 };
658
659 Utils.Observable = Observable;
660
661 Utils.generateChars = function (length) {
662 var chars = '';
663
664 for (var i = 0; i < length; i++) {
665 var randomChar = Math.floor(Math.random() * 36);
666 chars += randomChar.toString(36);
667 }
668
669 return chars;
670 };
671
672 Utils.bind = function (func, context) {
673 return function () {
674 func.apply(context, arguments);
675 };
676 };
677
678 Utils._convertData = function (data) {
679 for (var originalKey in data) {
680 var keys = originalKey.split('-');
681
682 var dataLevel = data;
683
684 if (keys.length === 1) {
685 continue;
686 }
687
688 for (var k = 0; k < keys.length; k++) {
689 var key = keys[k];
690
691 // Lowercase the first letter
692 // By default, dash-separated becomes camelCase
693 key = key.substring(0, 1).toLowerCase() + key.substring(1);
694
695 if (!(key in dataLevel)) {
696 dataLevel[key] = {};
697 }
698
699 if (k == keys.length - 1) {
700 dataLevel[key] = data[originalKey];
701 }
702
703 dataLevel = dataLevel[key];
704 }
705
706 delete data[originalKey];
707 }
708
709 return data;
710 };
711
712 Utils.hasScroll = function (index, el) {
713 // Adapted from the function created by @ShadowScripter
714 // and adapted by @BillBarry on the Stack Exchange Code Review website.
715 // The original code can be found at
716 // http://codereview.stackexchange.com/q/13338
717 // and was designed to be used with the Sizzle selector engine.
718
719 var $el = $(el);
720 var overflowX = el.style.overflowX;
721 var overflowY = el.style.overflowY;
722
723 //Check both x and y declarations
724 if (overflowX === overflowY &&
725 (overflowY === 'hidden' || overflowY === 'visible')) {
726 return false;
727 }
728
729 if (overflowX === 'scroll' || overflowY === 'scroll') {
730 return true;
731 }
732
733 return ($el.innerHeight() < el.scrollHeight ||
734 $el.innerWidth() < el.scrollWidth);
735 };
736
737 Utils.escapeMarkup = function (markup) {
738 var replaceMap = {
739 '\\': '&#92;',
740 '&': '&amp;',
741 '<': '&lt;',
742 '>': '&gt;',
743 '"': '&quot;',
744 '\'': '&#39;',
745 '/': '&#47;'
746 };
747
748 // Do not try to escape the markup if it's not a string
749 if (typeof markup !== 'string') {
750 return markup;
751 }
752
753 return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
754 return replaceMap[match];
755 });
756 };
757
758 // Append an array of jQuery nodes to a given element.
759 Utils.appendMany = function ($element, $nodes) {
760 // jQuery 1.7.x does not support $.fn.append() with an array
761 // Fall back to a jQuery object collection using $.fn.add()
762 if ($.fn.jquery.substr(0, 3) === '1.7') {
763 var $jqNodes = $();
764
765 $.map($nodes, function (node) {
766 $jqNodes = $jqNodes.add(node);
767 });
768
769 $nodes = $jqNodes;
770 }
771
772 $element.append($nodes);
773 };
774
775 // Cache objects in Utils.__cache instead of $.data (see #4346)
776 Utils.__cache = {};
777
778 var id = 0;
779 Utils.GetUniqueElementId = function (element) {
780 // Get a unique element Id. If element has no id,
781 // creates a new unique number, stores it in the id
782 // attribute and returns the new id.
783 // If an id already exists, it simply returns it.
784
785 var select2Id = element.getAttribute('data-select2-id');
786 if (select2Id == null) {
787 // If element has id, use it.
788 if (element.id) {
789 select2Id = element.id;
790 element.setAttribute('data-select2-id', select2Id);
791 } else {
792 element.setAttribute('data-select2-id', ++id);
793 select2Id = id.toString();
794 }
795 }
796 return select2Id;
797 };
798
799 Utils.StoreData = function (element, name, value) {
800 // Stores an item in the cache for a specified element.
801 // name is the cache key.
802 var id = Utils.GetUniqueElementId(element);
803 if (!Utils.__cache[id]) {
804 Utils.__cache[id] = {};
805 }
806
807 Utils.__cache[id][name] = value;
808 };
809
810 Utils.GetData = function (element, name) {
811 // Retrieves a value from the cache by its key (name)
812 // name is optional. If no name specified, return
813 // all cache items for the specified element.
814 // and for a specified element.
815 var id = Utils.GetUniqueElementId(element);
816 if (name) {
817 if (Utils.__cache[id]) {
818 if (Utils.__cache[id][name] != null) {
819 return Utils.__cache[id][name];
820 }
821 return $(element).data(name); // Fallback to HTML5 data attribs.
822 }
823 return $(element).data(name); // Fallback to HTML5 data attribs.
824 } else {
825 return Utils.__cache[id];
826 }
827 };
828
829 Utils.RemoveData = function (element) {
830 // Removes all cached items for a specified element.
831 var id = Utils.GetUniqueElementId(element);
832 if (Utils.__cache[id] != null) {
833 delete Utils.__cache[id];
834 }
835
836 element.removeAttribute('data-select2-id');
837 };
838
839 return Utils;
840 });
841
842 S2.define('select2/results',[
843 'jquery',
844 './utils'
845 ], function ($, Utils) {
846 function Results ($element, options, dataAdapter) {
847 this.$element = $element;
848 this.data = dataAdapter;
849 this.options = options;
850
851 Results.__super__.constructor.call(this);
852 }
853
854 Utils.Extend(Results, Utils.Observable);
855
856 Results.prototype.render = function () {
857 var $results = $(
858 '<ul class="select2-results__options" role="listbox"></ul>'
859 );
860
861 if (this.options.get('multiple')) {
862 $results.attr('aria-multiselectable', 'true');
863 }
864
865 this.$results = $results;
866
867 return $results;
868 };
869
870 Results.prototype.clear = function () {
871 this.$results.empty();
872 };
873
874 Results.prototype.displayMessage = function (params) {
875 var escapeMarkup = this.options.get('escapeMarkup');
876
877 this.clear();
878 this.hideLoading();
879
880 var $message = $(
881 '<li role="alert" aria-live="assertive"' +
882 ' class="select2-results__option"></li>'
883 );
884
885 var message = this.options.get('translations').get(params.message);
886
887 $message.append(
888 escapeMarkup(
889 message(params.args)
890 )
891 );
892
893 $message[0].className += ' select2-results__message';
894
895 this.$results.append($message);
896 };
897
898 Results.prototype.hideMessages = function () {
899 this.$results.find('.select2-results__message').remove();
900 };
901
902 Results.prototype.append = function (data) {
903 this.hideLoading();
904
905 var $options = [];
906
907 if (data.results == null || data.results.length === 0) {
908 if (this.$results.children().length === 0) {
909 this.trigger('results:message', {
910 message: 'noResults'
911 });
912 }
913
914 return;
915 }
916
917 data.results = this.sort(data.results);
918
919 for (var d = 0; d < data.results.length; d++) {
920 var item = data.results[d];
921
922 var $option = this.option(item);
923
924 $options.push($option);
925 }
926
927 this.$results.append($options);
928 };
929
930 Results.prototype.position = function ($results, $dropdown) {
931 var $resultsContainer = $dropdown.find('.select2-results');
932 $resultsContainer.append($results);
933 };
934
935 Results.prototype.sort = function (data) {
936 var sorter = this.options.get('sorter');
937
938 return sorter(data);
939 };
940
941 Results.prototype.highlightFirstItem = function () {
942 var $options = this.$results
943 .find('.select2-results__option[aria-selected]');
944
945 var $selected = $options.filter('[aria-selected=true]');
946
947 // Check if there are any selected options
948 if ($selected.length > 0) {
949 // If there are selected options, highlight the first
950 $selected.first().trigger('mouseenter');
951 } else {
952 // If there are no selected options, highlight the first option
953 // in the dropdown
954 $options.first().trigger('mouseenter');
955 }
956
957 this.ensureHighlightVisible();
958 };
959
960 Results.prototype.setClasses = function () {
961 var self = this;
962
963 this.data.current(function (selected) {
964 var selectedIds = $.map(selected, function (s) {
965 return s.id.toString();
966 });
967
968 var $options = self.$results
969 .find('.select2-results__option[aria-selected]');
970
971 $options.each(function () {
972 var $option = $(this);
973
974 var item = Utils.GetData(this, 'data');
975
976 // id needs to be converted to a string when comparing
977 var id = '' + item.id;
978
979 if ((item.element != null && item.element.selected) ||
980 (item.element == null && $.inArray(id, selectedIds) > -1)) {
981 $option.attr('aria-selected', 'true');
982 } else {
983 $option.attr('aria-selected', 'false');
984 }
985 });
986
987 });
988 };
989
990 Results.prototype.showLoading = function (params) {
991 this.hideLoading();
992
993 var loadingMore = this.options.get('translations').get('searching');
994
995 var loading = {
996 disabled: true,
997 loading: true,
998 text: loadingMore(params)
999 };
1000 var $loading = this.option(loading);
1001 $loading.className += ' loading-results';
1002
1003 this.$results.prepend($loading);
1004 };
1005
1006 Results.prototype.hideLoading = function () {
1007 this.$results.find('.loading-results').remove();
1008 };
1009
1010 Results.prototype.option = function (data) {
1011 var option = document.createElement('li');
1012 option.className = 'select2-results__option';
1013
1014 var attrs = {
1015 'role': 'option',
1016 'aria-selected': 'false'
1017 };
1018
1019 var matches = window.Element.prototype.matches ||
1020 window.Element.prototype.msMatchesSelector ||
1021 window.Element.prototype.webkitMatchesSelector;
1022
1023 if ((data.element != null && matches.call(data.element, ':disabled')) ||
1024 (data.element == null && data.disabled)) {
1025 delete attrs['aria-selected'];
1026 attrs['aria-disabled'] = 'true';
1027 }
1028
1029 if (data.id == null) {
1030 delete attrs['aria-selected'];
1031 }
1032
1033 if (data._resultId != null) {
1034 option.id = data._resultId;
1035 }
1036
1037 if (data.title) {
1038 option.title = data.title;
1039 }
1040
1041 if (data.children) {
1042 attrs.role = 'group';
1043 attrs['aria-label'] = data.text;
1044 delete attrs['aria-selected'];
1045 }
1046
1047 for (var attr in attrs) {
1048 var val = attrs[attr];
1049
1050 option.setAttribute(attr, val);
1051 }
1052
1053 if (data.children) {
1054 var $option = $(option);
1055
1056 var label = document.createElement('strong');
1057 label.className = 'select2-results__group';
1058
1059 var $label = $(label);
1060 this.template(data, label);
1061
1062 var $children = [];
1063
1064 for (var c = 0; c < data.children.length; c++) {
1065 var child = data.children[c];
1066
1067 var $child = this.option(child);
1068
1069 $children.push($child);
1070 }
1071
1072 var $childrenContainer = $('<ul></ul>', {
1073 'class': 'select2-results__options select2-results__options--nested'
1074 });
1075
1076 $childrenContainer.append($children);
1077
1078 $option.append(label);
1079 $option.append($childrenContainer);
1080 } else {
1081 this.template(data, option);
1082 }
1083
1084 Utils.StoreData(option, 'data', data);
1085
1086 return option;
1087 };
1088
1089 Results.prototype.bind = function (container, $container) {
1090 var self = this;
1091
1092 var id = container.id + '-results';
1093
1094 this.$results.attr('id', id);
1095
1096 container.on('results:all', function (params) {
1097 self.clear();
1098 self.append(params.data);
1099
1100 if (container.isOpen()) {
1101 self.setClasses();
1102 self.highlightFirstItem();
1103 }
1104 });
1105
1106 container.on('results:append', function (params) {
1107 self.append(params.data);
1108
1109 if (container.isOpen()) {
1110 self.setClasses();
1111 }
1112 });
1113
1114 container.on('query', function (params) {
1115 self.hideMessages();
1116 self.showLoading(params);
1117 });
1118
1119 container.on('select', function () {
1120 if (!container.isOpen()) {
1121 return;
1122 }
1123
1124 self.setClasses();
1125
1126 if (self.options.get('scrollAfterSelect')) {
1127 self.highlightFirstItem();
1128 }
1129 });
1130
1131 container.on('unselect', function () {
1132 if (!container.isOpen()) {
1133 return;
1134 }
1135
1136 self.setClasses();
1137
1138 if (self.options.get('scrollAfterSelect')) {
1139 self.highlightFirstItem();
1140 }
1141 });
1142
1143 container.on('open', function () {
1144 // When the dropdown is open, aria-expended="true"
1145 self.$results.attr('aria-expanded', 'true');
1146 self.$results.attr('aria-hidden', 'false');
1147
1148 self.setClasses();
1149 self.ensureHighlightVisible();
1150 });
1151
1152 container.on('close', function () {
1153 // When the dropdown is closed, aria-expended="false"
1154 self.$results.attr('aria-expanded', 'false');
1155 self.$results.attr('aria-hidden', 'true');
1156 self.$results.removeAttr('aria-activedescendant');
1157 });
1158
1159 container.on('results:toggle', function () {
1160 var $highlighted = self.getHighlightedResults();
1161
1162 if ($highlighted.length === 0) {
1163 return;
1164 }
1165
1166 $highlighted.trigger('mouseup');
1167 });
1168
1169 container.on('results:select', function () {
1170 var $highlighted = self.getHighlightedResults();
1171
1172 if ($highlighted.length === 0) {
1173 return;
1174 }
1175
1176 var data = Utils.GetData($highlighted[0], 'data');
1177
1178 if ($highlighted.attr('aria-selected') == 'true') {
1179 self.trigger('close', {});
1180 } else {
1181 self.trigger('select', {
1182 data: data
1183 });
1184 }
1185 });
1186
1187 container.on('results:previous', function () {
1188 var $highlighted = self.getHighlightedResults();
1189
1190 var $options = self.$results.find('[aria-selected]');
1191
1192 var currentIndex = $options.index($highlighted);
1193
1194 // If we are already at the top, don't move further
1195 // If no options, currentIndex will be -1
1196 if (currentIndex <= 0) {
1197 return;
1198 }
1199
1200 var nextIndex = currentIndex - 1;
1201
1202 // If none are highlighted, highlight the first
1203 if ($highlighted.length === 0) {
1204 nextIndex = 0;
1205 }
1206
1207 var $next = $options.eq(nextIndex);
1208
1209 $next.trigger('mouseenter');
1210
1211 var currentOffset = self.$results.offset().top;
1212 var nextTop = $next.offset().top;
1213 var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset);
1214
1215 if (nextIndex === 0) {
1216 self.$results.scrollTop(0);
1217 } else if (nextTop - currentOffset < 0) {
1218 self.$results.scrollTop(nextOffset);
1219 }
1220 });
1221
1222 container.on('results:next', function () {
1223 var $highlighted = self.getHighlightedResults();
1224
1225 var $options = self.$results.find('[aria-selected]');
1226
1227 var currentIndex = $options.index($highlighted);
1228
1229 var nextIndex = currentIndex + 1;
1230
1231 // If we are at the last option, stay there
1232 if (nextIndex >= $options.length) {
1233 return;
1234 }
1235
1236 var $next = $options.eq(nextIndex);
1237
1238 $next.trigger('mouseenter');
1239
1240 var currentOffset = self.$results.offset().top +
1241 self.$results.outerHeight(false);
1242 var nextBottom = $next.offset().top + $next.outerHeight(false);
1243 var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset;
1244
1245 if (nextIndex === 0) {
1246 self.$results.scrollTop(0);
1247 } else if (nextBottom > currentOffset) {
1248 self.$results.scrollTop(nextOffset);
1249 }
1250 });
1251
1252 container.on('results:focus', function (params) {
1253 params.element.addClass('select2-results__option--highlighted');
1254 });
1255
1256 container.on('results:message', function (params) {
1257 self.displayMessage(params);
1258 });
1259
1260 if ($.fn.mousewheel) {
1261 this.$results.on('mousewheel', function (e) {
1262 var top = self.$results.scrollTop();
1263
1264 var bottom = self.$results.get(0).scrollHeight - top + e.deltaY;
1265
1266 var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0;
1267 var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height();
1268
1269 if (isAtTop) {
1270 self.$results.scrollTop(0);
1271
1272 e.preventDefault();
1273 e.stopPropagation();
1274 } else if (isAtBottom) {
1275 self.$results.scrollTop(
1276 self.$results.get(0).scrollHeight - self.$results.height()
1277 );
1278
1279 e.preventDefault();
1280 e.stopPropagation();
1281 }
1282 });
1283 }
1284
1285 this.$results.on('mouseup', '.select2-results__option[aria-selected]',
1286 function (evt) {
1287 var $this = $(this);
1288
1289 var data = Utils.GetData(this, 'data');
1290
1291 if ($this.attr('aria-selected') === 'true') {
1292 if (self.options.get('multiple')) {
1293 self.trigger('unselect', {
1294 originalEvent: evt,
1295 data: data
1296 });
1297 } else {
1298 self.trigger('close', {});
1299 }
1300
1301 return;
1302 }
1303
1304 self.trigger('select', {
1305 originalEvent: evt,
1306 data: data
1307 });
1308 });
1309
1310 this.$results.on('mouseenter', '.select2-results__option[aria-selected]',
1311 function (evt) {
1312 var data = Utils.GetData(this, 'data');
1313
1314 self.getHighlightedResults()
1315 .removeClass('select2-results__option--highlighted');
1316
1317 self.trigger('results:focus', {
1318 data: data,
1319 element: $(this)
1320 });
1321 });
1322 };
1323
1324 Results.prototype.getHighlightedResults = function () {
1325 var $highlighted = this.$results
1326 .find('.select2-results__option--highlighted');
1327
1328 return $highlighted;
1329 };
1330
1331 Results.prototype.destroy = function () {
1332 this.$results.remove();
1333 };
1334
1335 Results.prototype.ensureHighlightVisible = function () {
1336 var $highlighted = this.getHighlightedResults();
1337
1338 if ($highlighted.length === 0) {
1339 return;
1340 }
1341
1342 var $options = this.$results.find('[aria-selected]');
1343
1344 var currentIndex = $options.index($highlighted);
1345
1346 var currentOffset = this.$results.offset().top;
1347 var nextTop = $highlighted.offset().top;
1348 var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset);
1349
1350 var offsetDelta = nextTop - currentOffset;
1351 nextOffset -= $highlighted.outerHeight(false) * 2;
1352
1353 if (currentIndex <= 2) {
1354 this.$results.scrollTop(0);
1355 } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) {
1356 this.$results.scrollTop(nextOffset);
1357 }
1358 };
1359
1360 Results.prototype.template = function (result, container) {
1361 var template = this.options.get('templateResult');
1362 var escapeMarkup = this.options.get('escapeMarkup');
1363
1364 var content = template(result, container);
1365
1366 if (content == null) {
1367 container.style.display = 'none';
1368 } else if (typeof content === 'string') {
1369 container.innerHTML = escapeMarkup(content);
1370 } else {
1371 $(container).append(content);
1372 }
1373 };
1374
1375 return Results;
1376 });
1377
1378 S2.define('select2/keys',[
1379
1380 ], function () {
1381 var KEYS = {
1382 BACKSPACE: 8,
1383 TAB: 9,
1384 ENTER: 13,
1385 SHIFT: 16,
1386 CTRL: 17,
1387 ALT: 18,
1388 ESC: 27,
1389 SPACE: 32,
1390 PAGE_UP: 33,
1391 PAGE_DOWN: 34,
1392 END: 35,
1393 HOME: 36,
1394 LEFT: 37,
1395 UP: 38,
1396 RIGHT: 39,
1397 DOWN: 40,
1398 DELETE: 46
1399 };
1400
1401 return KEYS;
1402 });
1403
1404 S2.define('select2/selection/base',[
1405 'jquery',
1406 '../utils',
1407 '../keys'
1408 ], function ($, Utils, KEYS) {
1409 function BaseSelection ($element, options) {
1410 this.$element = $element;
1411 this.options = options;
1412
1413 BaseSelection.__super__.constructor.call(this);
1414 }
1415
1416 Utils.Extend(BaseSelection, Utils.Observable);
1417
1418 BaseSelection.prototype.render = function () {
1419 var $selection = $(
1420 '<span class="select2-selection" role="combobox" ' +
1421 ' aria-haspopup="true" aria-expanded="false">' +
1422 '</span>'
1423 );
1424
1425 this._tabindex = 0;
1426
1427 if (Utils.GetData(this.$element[0], 'old-tabindex') != null) {
1428 this._tabindex = Utils.GetData(this.$element[0], 'old-tabindex');
1429 } else if (this.$element.attr('tabindex') != null) {
1430 this._tabindex = this.$element.attr('tabindex');
1431 }
1432
1433 $selection.attr('title', this.$element.attr('title'));
1434 $selection.attr('tabindex', this._tabindex);
1435 $selection.attr('aria-disabled', 'false');
1436
1437 this.$selection = $selection;
1438
1439 return $selection;
1440 };
1441
1442 BaseSelection.prototype.bind = function (container, $container) {
1443 var self = this;
1444
1445 var resultsId = container.id + '-results';
1446
1447 this.container = container;
1448
1449 this.$selection.on('focus', function (evt) {
1450 self.trigger('focus', evt);
1451 });
1452
1453 this.$selection.on('blur', function (evt) {
1454 self._handleBlur(evt);
1455 });
1456
1457 this.$selection.on('keydown', function (evt) {
1458 self.trigger('keypress', evt);
1459
1460 if (evt.which === KEYS.SPACE) {
1461 evt.preventDefault();
1462 }
1463 });
1464
1465 container.on('results:focus', function (params) {
1466 self.$selection.attr('aria-activedescendant', params.data._resultId);
1467 });
1468
1469 container.on('selection:update', function (params) {
1470 self.update(params.data);
1471 });
1472
1473 container.on('open', function () {
1474 // When the dropdown is open, aria-expanded="true"
1475 self.$selection.attr('aria-expanded', 'true');
1476 self.$selection.attr('aria-owns', resultsId);
1477
1478 self._attachCloseHandler(container);
1479 });
1480
1481 container.on('close', function () {
1482 // When the dropdown is closed, aria-expanded="false"
1483 self.$selection.attr('aria-expanded', 'false');
1484 self.$selection.removeAttr('aria-activedescendant');
1485 self.$selection.removeAttr('aria-owns');
1486
1487 self.$selection.trigger('focus');
1488
1489 self._detachCloseHandler(container);
1490 });
1491
1492 container.on('enable', function () {
1493 self.$selection.attr('tabindex', self._tabindex);
1494 self.$selection.attr('aria-disabled', 'false');
1495 });
1496
1497 container.on('disable', function () {
1498 self.$selection.attr('tabindex', '-1');
1499 self.$selection.attr('aria-disabled', 'true');
1500 });
1501 };
1502
1503 BaseSelection.prototype._handleBlur = function (evt) {
1504 var self = this;
1505
1506 // This needs to be delayed as the active element is the body when the tab
1507 // key is pressed, possibly along with others.
1508 window.setTimeout(function () {
1509 // Don't trigger `blur` if the focus is still in the selection
1510 if (
1511 (document.activeElement == self.$selection[0]) ||
1512 ($.contains(self.$selection[0], document.activeElement))
1513 ) {
1514 return;
1515 }
1516
1517 self.trigger('blur', evt);
1518 }, 1);
1519 };
1520
1521 BaseSelection.prototype._attachCloseHandler = function (container) {
1522
1523 $(document.body).on('mousedown.select2.' + container.id, function (e) {
1524 var $target = $(e.target);
1525
1526 var $select = $target.closest('.select2');
1527
1528 var $all = $('.select2.select2-container--open');
1529
1530 $all.each(function () {
1531 if (this == $select[0]) {
1532 return;
1533 }
1534
1535 var $element = Utils.GetData(this, 'element');
1536
1537 $element.select2('close');
1538 });
1539 });
1540 };
1541
1542 BaseSelection.prototype._detachCloseHandler = function (container) {
1543 $(document.body).off('mousedown.select2.' + container.id);
1544 };
1545
1546 BaseSelection.prototype.position = function ($selection, $container) {
1547 var $selectionContainer = $container.find('.selection');
1548 $selectionContainer.append($selection);
1549 };
1550
1551 BaseSelection.prototype.destroy = function () {
1552 this._detachCloseHandler(this.container);
1553 };
1554
1555 BaseSelection.prototype.update = function (data) {
1556 throw new Error('The `update` method must be defined in child classes.');
1557 };
1558
1559 return BaseSelection;
1560 });
1561
1562 S2.define('select2/selection/single',[
1563 'jquery',
1564 './base',
1565 '../utils',
1566 '../keys'
1567 ], function ($, BaseSelection, Utils, KEYS) {
1568 function SingleSelection () {
1569 SingleSelection.__super__.constructor.apply(this, arguments);
1570 }
1571
1572 Utils.Extend(SingleSelection, BaseSelection);
1573
1574 SingleSelection.prototype.render = function () {
1575 var $selection = SingleSelection.__super__.render.call(this);
1576
1577 $selection.addClass('select2-selection--single');
1578
1579 $selection.html(
1580 '<span class="select2-selection__rendered"></span>' +
1581 '<span class="select2-selection__arrow" role="presentation">' +
1582 '<b role="presentation"></b>' +
1583 '</span>'
1584 );
1585
1586 return $selection;
1587 };
1588
1589 SingleSelection.prototype.bind = function (container, $container) {
1590 var self = this;
1591
1592 SingleSelection.__super__.bind.apply(this, arguments);
1593
1594 var id = container.id + '-container';
1595
1596 this.$selection.find('.select2-selection__rendered')
1597 .attr('id', id)
1598 .attr('role', 'textbox')
1599 .attr('aria-readonly', 'true');
1600 this.$selection.attr('aria-labelledby', id);
1601
1602 this.$selection.on('mousedown', function (evt) {
1603 // Only respond to left clicks
1604 if (evt.which !== 1) {
1605 return;
1606 }
1607
1608 self.trigger('toggle', {
1609 originalEvent: evt
1610 });
1611 });
1612
1613 this.$selection.on('focus', function (evt) {
1614 // User focuses on the container
1615 });
1616
1617 this.$selection.on('blur', function (evt) {
1618 // User exits the container
1619 });
1620
1621 container.on('focus', function (evt) {
1622 if (!container.isOpen()) {
1623 self.$selection.trigger('focus');
1624 }
1625 });
1626 };
1627
1628 SingleSelection.prototype.clear = function () {
1629 var $rendered = this.$selection.find('.select2-selection__rendered');
1630 $rendered.empty();
1631 $rendered.removeAttr('title'); // clear tooltip on empty
1632 };
1633
1634 SingleSelection.prototype.display = function (data, container) {
1635 var template = this.options.get('templateSelection');
1636 var escapeMarkup = this.options.get('escapeMarkup');
1637
1638 return escapeMarkup(template(data, container));
1639 };
1640
1641 SingleSelection.prototype.selectionContainer = function () {
1642 return $('<span></span>');
1643 };
1644
1645 SingleSelection.prototype.update = function (data) {
1646 if (data.length === 0) {
1647 this.clear();
1648 return;
1649 }
1650
1651 var selection = data[0];
1652
1653 var $rendered = this.$selection.find('.select2-selection__rendered');
1654 var formatted = this.display(selection, $rendered);
1655
1656 $rendered.empty().append(formatted);
1657
1658 var title = selection.title || selection.text;
1659
1660 if (title) {
1661 $rendered.attr('title', title);
1662 } else {
1663 $rendered.removeAttr('title');
1664 }
1665 };
1666
1667 return SingleSelection;
1668 });
1669
1670 S2.define('select2/selection/multiple',[
1671 'jquery',
1672 './base',
1673 '../utils'
1674 ], function ($, BaseSelection, Utils) {
1675 function MultipleSelection ($element, options) {
1676 MultipleSelection.__super__.constructor.apply(this, arguments);
1677 }
1678
1679 Utils.Extend(MultipleSelection, BaseSelection);
1680
1681 MultipleSelection.prototype.render = function () {
1682 var $selection = MultipleSelection.__super__.render.call(this);
1683
1684 $selection.addClass('select2-selection--multiple');
1685
1686 $selection.html(
1687 '<ul class="select2-selection__rendered"></ul>'
1688 );
1689
1690 return $selection;
1691 };
1692
1693 MultipleSelection.prototype.bind = function (container, $container) {
1694 var self = this;
1695
1696 MultipleSelection.__super__.bind.apply(this, arguments);
1697
1698 this.$selection.on('click', function (evt) {
1699 self.trigger('toggle', {
1700 originalEvent: evt
1701 });
1702 });
1703
1704 this.$selection.on(
1705 'click',
1706 '.select2-selection__choice__remove',
1707 function (evt) {
1708 // Ignore the event if it is disabled
1709 if (self.options.get('disabled')) {
1710 return;
1711 }
1712
1713 var $remove = $(this);
1714 var $selection = $remove.parent();
1715
1716 var data = Utils.GetData($selection[0], 'data');
1717
1718 self.trigger('unselect', {
1719 originalEvent: evt,
1720 data: data
1721 });
1722 }
1723 );
1724 };
1725
1726 MultipleSelection.prototype.clear = function () {
1727 var $rendered = this.$selection.find('.select2-selection__rendered');
1728 $rendered.empty();
1729 $rendered.removeAttr('title');
1730 };
1731
1732 MultipleSelection.prototype.display = function (data, container) {
1733 var template = this.options.get('templateSelection');
1734 var escapeMarkup = this.options.get('escapeMarkup');
1735
1736 return escapeMarkup(template(data, container));
1737 };
1738
1739 MultipleSelection.prototype.selectionContainer = function () {
1740 var $container = $(
1741 '<li class="select2-selection__choice">' +
1742 '<span class="select2-selection__choice__remove" role="presentation">' +
1743 '&times;' +
1744 '</span>' +
1745 '</li>'
1746 );
1747
1748 return $container;
1749 };
1750
1751 MultipleSelection.prototype.update = function (data) {
1752 this.clear();
1753
1754 if (data.length === 0) {
1755 return;
1756 }
1757
1758 var $selections = [];
1759
1760 for (var d = 0; d < data.length; d++) {
1761 var selection = data[d];
1762
1763 var $selection = this.selectionContainer();
1764 var formatted = this.display(selection, $selection);
1765
1766 $selection.append(formatted);
1767
1768 var title = selection.title || selection.text;
1769
1770 if (title) {
1771 $selection.attr('title', title);
1772 }
1773
1774 Utils.StoreData($selection[0], 'data', selection);
1775
1776 $selections.push($selection);
1777 }
1778
1779 var $rendered = this.$selection.find('.select2-selection__rendered');
1780
1781 Utils.appendMany($rendered, $selections);
1782 };
1783
1784 return MultipleSelection;
1785 });
1786
1787 S2.define('select2/selection/placeholder',[
1788 '../utils'
1789 ], function (Utils) {
1790 function Placeholder (decorated, $element, options) {
1791 this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
1792
1793 decorated.call(this, $element, options);
1794 }
1795
1796 Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
1797 if (typeof placeholder === 'string') {
1798 placeholder = {
1799 id: '',
1800 text: placeholder
1801 };
1802 }
1803
1804 return placeholder;
1805 };
1806
1807 Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
1808 var $placeholder = this.selectionContainer();
1809
1810 $placeholder.html(this.display(placeholder));
1811 $placeholder.addClass('select2-selection__placeholder')
1812 .removeClass('select2-selection__choice');
1813
1814 return $placeholder;
1815 };
1816
1817 Placeholder.prototype.update = function (decorated, data) {
1818 var singlePlaceholder = (
1819 data.length == 1 && data[0].id != this.placeholder.id
1820 );
1821 var multipleSelections = data.length > 1;
1822
1823 if (multipleSelections || singlePlaceholder) {
1824 return decorated.call(this, data);
1825 }
1826
1827 this.clear();
1828
1829 var $placeholder = this.createPlaceholder(this.placeholder);
1830
1831 this.$selection.find('.select2-selection__rendered').append($placeholder);
1832 };
1833
1834 return Placeholder;
1835 });
1836
1837 S2.define('select2/selection/allowClear',[
1838 'jquery',
1839 '../keys',
1840 '../utils'
1841 ], function ($, KEYS, Utils) {
1842 function AllowClear () { }
1843
1844 AllowClear.prototype.bind = function (decorated, container, $container) {
1845 var self = this;
1846
1847 decorated.call(this, container, $container);
1848
1849 if (this.placeholder == null) {
1850 if (this.options.get('debug') && window.console && console.error) {
1851 console.error(
1852 'Select2: The `allowClear` option should be used in combination ' +
1853 'with the `placeholder` option.'
1854 );
1855 }
1856 }
1857
1858 this.$selection.on('mousedown', '.select2-selection__clear',
1859 function (evt) {
1860 self._handleClear(evt);
1861 });
1862
1863 container.on('keypress', function (evt) {
1864 self._handleKeyboardClear(evt, container);
1865 });
1866 };
1867
1868 AllowClear.prototype._handleClear = function (_, evt) {
1869 // Ignore the event if it is disabled
1870 if (this.options.get('disabled')) {
1871 return;
1872 }
1873
1874 var $clear = this.$selection.find('.select2-selection__clear');
1875
1876 // Ignore the event if nothing has been selected
1877 if ($clear.length === 0) {
1878 return;
1879 }
1880
1881 evt.stopPropagation();
1882
1883 var data = Utils.GetData($clear[0], 'data');
1884
1885 var previousVal = this.$element.val();
1886 this.$element.val(this.placeholder.id);
1887
1888 var unselectData = {
1889 data: data
1890 };
1891 this.trigger('clear', unselectData);
1892 if (unselectData.prevented) {
1893 this.$element.val(previousVal);
1894 return;
1895 }
1896
1897 for (var d = 0; d < data.length; d++) {
1898 unselectData = {
1899 data: data[d]
1900 };
1901
1902 // Trigger the `unselect` event, so people can prevent it from being
1903 // cleared.
1904 this.trigger('unselect', unselectData);
1905
1906 // If the event was prevented, don't clear it out.
1907 if (unselectData.prevented) {
1908 this.$element.val(previousVal);
1909 return;
1910 }
1911 }
1912
1913 this.$element.trigger('change');
1914
1915 this.trigger('toggle', {});
1916 };
1917
1918 AllowClear.prototype._handleKeyboardClear = function (_, evt, container) {
1919 if (container.isOpen()) {
1920 return;
1921 }
1922
1923 if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) {
1924 this._handleClear(evt);
1925 }
1926 };
1927
1928 AllowClear.prototype.update = function (decorated, data) {
1929 decorated.call(this, data);
1930
1931 if (this.$selection.find('.select2-selection__placeholder').length > 0 ||
1932 data.length === 0) {
1933 return;
1934 }
1935
1936 var removeAll = this.options.get('translations').get('removeAllItems');
1937
1938 var $remove = $(
1939 '<span class="select2-selection__clear" title="' + removeAll() +'">' +
1940 '&times;' +
1941 '</span>'
1942 );
1943 Utils.StoreData($remove[0], 'data', data);
1944
1945 this.$selection.find('.select2-selection__rendered').prepend($remove);
1946 };
1947
1948 return AllowClear;
1949 });
1950
1951 S2.define('select2/selection/search',[
1952 'jquery',
1953 '../utils',
1954 '../keys'
1955 ], function ($, Utils, KEYS) {
1956 function Search (decorated, $element, options) {
1957 decorated.call(this, $element, options);
1958 }
1959
1960 Search.prototype.render = function (decorated) {
1961 var $search = $(
1962 '<li class="select2-search select2-search--inline">' +
1963 '<input class="select2-search__field" type="search" tabindex="-1"' +
1964 ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
1965 ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
1966 '</li>'
1967 );
1968
1969 this.$searchContainer = $search;
1970 this.$search = $search.find('input');
1971
1972 var $rendered = decorated.call(this);
1973
1974 this._transferTabIndex();
1975
1976 return $rendered;
1977 };
1978
1979 Search.prototype.bind = function (decorated, container, $container) {
1980 var self = this;
1981
1982 var resultsId = container.id + '-results';
1983
1984 decorated.call(this, container, $container);
1985
1986 container.on('open', function () {
1987 self.$search.attr('aria-controls', resultsId);
1988 self.$search.trigger('focus');
1989 });
1990
1991 container.on('close', function () {
1992 self.$search.val('');
1993 self.$search.removeAttr('aria-controls');
1994 self.$search.removeAttr('aria-activedescendant');
1995 self.$search.trigger('focus');
1996 });
1997
1998 container.on('enable', function () {
1999 self.$search.prop('disabled', false);
2000
2001 self._transferTabIndex();
2002 });
2003
2004 container.on('disable', function () {
2005 self.$search.prop('disabled', true);
2006 });
2007
2008 container.on('focus', function (evt) {
2009 self.$search.trigger('focus');
2010 });
2011
2012 container.on('results:focus', function (params) {
2013 if (params.data._resultId) {
2014 self.$search.attr('aria-activedescendant', params.data._resultId);
2015 } else {
2016 self.$search.removeAttr('aria-activedescendant');
2017 }
2018 });
2019
2020 this.$selection.on('focusin', '.select2-search--inline', function (evt) {
2021 self.trigger('focus', evt);
2022 });
2023
2024 this.$selection.on('focusout', '.select2-search--inline', function (evt) {
2025 self._handleBlur(evt);
2026 });
2027
2028 this.$selection.on('keydown', '.select2-search--inline', function (evt) {
2029 evt.stopPropagation();
2030
2031 self.trigger('keypress', evt);
2032
2033 self._keyUpPrevented = evt.isDefaultPrevented();
2034
2035 var key = evt.which;
2036
2037 if (key === KEYS.BACKSPACE && self.$search.val() === '') {
2038 var $previousChoice = self.$searchContainer
2039 .prev('.select2-selection__choice');
2040
2041 if ($previousChoice.length > 0) {
2042 var item = Utils.GetData($previousChoice[0], 'data');
2043
2044 self.searchRemoveChoice(item);
2045
2046 evt.preventDefault();
2047 }
2048 }
2049 });
2050
2051 this.$selection.on('click', '.select2-search--inline', function (evt) {
2052 if (self.$search.val()) {
2053 evt.stopPropagation();
2054 }
2055 });
2056
2057 // Try to detect the IE version should the `documentMode` property that
2058 // is stored on the document. This is only implemented in IE and is
2059 // slightly cleaner than doing a user agent check.
2060 // This property is not available in Edge, but Edge also doesn't have
2061 // this bug.
2062 var msie = document.documentMode;
2063 var disableInputEvents = msie && msie <= 11;
2064
2065 // Workaround for browsers which do not support the `input` event
2066 // This will prevent double-triggering of events for browsers which support
2067 // both the `keyup` and `input` events.
2068 this.$selection.on(
2069 'input.searchcheck',
2070 '.select2-search--inline',
2071 function (evt) {
2072 // IE will trigger the `input` event when a placeholder is used on a
2073 // search box. To get around this issue, we are forced to ignore all
2074 // `input` events in IE and keep using `keyup`.
2075 if (disableInputEvents) {
2076 self.$selection.off('input.search input.searchcheck');
2077 return;
2078 }
2079
2080 // Unbind the duplicated `keyup` event
2081 self.$selection.off('keyup.search');
2082 }
2083 );
2084
2085 this.$selection.on(
2086 'keyup.search input.search',
2087 '.select2-search--inline',
2088 function (evt) {
2089 // IE will trigger the `input` event when a placeholder is used on a
2090 // search box. To get around this issue, we are forced to ignore all
2091 // `input` events in IE and keep using `keyup`.
2092 if (disableInputEvents && evt.type === 'input') {
2093 self.$selection.off('input.search input.searchcheck');
2094 return;
2095 }
2096
2097 var key = evt.which;
2098
2099 // We can freely ignore events from modifier keys
2100 if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) {
2101 return;
2102 }
2103
2104 // Tabbing will be handled during the `keydown` phase
2105 if (key == KEYS.TAB) {
2106 return;
2107 }
2108
2109 self.handleSearch(evt);
2110 }
2111 );
2112 };
2113
2114 /**
2115 * This method will transfer the tabindex attribute from the rendered
2116 * selection to the search box. This allows for the search box to be used as
2117 * the primary focus instead of the selection container.
2118 *
2119 * @private
2120 */
2121 Search.prototype._transferTabIndex = function (decorated) {
2122 this.$search.attr('tabindex', this.$selection.attr('tabindex'));
2123 this.$selection.attr('tabindex', '-1');
2124 };
2125
2126 Search.prototype.createPlaceholder = function (decorated, placeholder) {
2127 this.$search.attr('placeholder', placeholder.text);
2128 };
2129
2130 Search.prototype.update = function (decorated, data) {
2131 var searchHadFocus = this.$search[0] == document.activeElement;
2132
2133 this.$search.attr('placeholder', '');
2134
2135 decorated.call(this, data);
2136
2137 this.$selection.find('.select2-selection__rendered')
2138 .append(this.$searchContainer);
2139
2140 this.resizeSearch();
2141 if (searchHadFocus) {
2142 this.$search.trigger('focus');
2143 }
2144 };
2145
2146 Search.prototype.handleSearch = function () {
2147 this.resizeSearch();
2148
2149 if (!this._keyUpPrevented) {
2150 var input = this.$search.val();
2151
2152 this.trigger('query', {
2153 term: input
2154 });
2155 }
2156
2157 this._keyUpPrevented = false;
2158 };
2159
2160 Search.prototype.searchRemoveChoice = function (decorated, item) {
2161 this.trigger('unselect', {
2162 data: item
2163 });
2164
2165 this.$search.val(item.text);
2166 this.handleSearch();
2167 };
2168
2169 Search.prototype.resizeSearch = function () {
2170 this.$search.css('width', '25px');
2171
2172 var width = '';
2173
2174 if (this.$search.attr('placeholder') !== '') {
2175 width = this.$selection.find('.select2-selection__rendered').width();
2176 } else {
2177 var minimumWidth = this.$search.val().length + 1;
2178
2179 width = (minimumWidth * 0.75) + 'em';
2180 }
2181
2182 this.$search.css('width', width);
2183 };
2184
2185 return Search;
2186 });
2187
2188 S2.define('select2/selection/eventRelay',[
2189 'jquery'
2190 ], function ($) {
2191 function EventRelay () { }
2192
2193 EventRelay.prototype.bind = function (decorated, container, $container) {
2194 var self = this;
2195 var relayEvents = [
2196 'open', 'opening',
2197 'close', 'closing',
2198 'select', 'selecting',
2199 'unselect', 'unselecting',
2200 'clear', 'clearing'
2201 ];
2202
2203 var preventableEvents = [
2204 'opening', 'closing', 'selecting', 'unselecting', 'clearing'
2205 ];
2206
2207 decorated.call(this, container, $container);
2208
2209 container.on('*', function (name, params) {
2210 // Ignore events that should not be relayed
2211 if ($.inArray(name, relayEvents) === -1) {
2212 return;
2213 }
2214
2215 // The parameters should always be an object
2216 params = params || {};
2217
2218 // Generate the jQuery event for the Select2 event
2219 var evt = $.Event('select2:' + name, {
2220 params: params
2221 });
2222
2223 self.$element.trigger(evt);
2224
2225 // Only handle preventable events if it was one
2226 if ($.inArray(name, preventableEvents) === -1) {
2227 return;
2228 }
2229
2230 params.prevented = evt.isDefaultPrevented();
2231 });
2232 };
2233
2234 return EventRelay;
2235 });
2236
2237 S2.define('select2/translation',[
2238 'jquery',
2239 'require'
2240 ], function ($, require) {
2241 function Translation (dict) {
2242 this.dict = dict || {};
2243 }
2244
2245 Translation.prototype.all = function () {
2246 return this.dict;
2247 };
2248
2249 Translation.prototype.get = function (key) {
2250 return this.dict[key];
2251 };
2252
2253 Translation.prototype.extend = function (translation) {
2254 this.dict = $.extend({}, translation.all(), this.dict);
2255 };
2256
2257 // Static functions
2258
2259 Translation._cache = {};
2260
2261 Translation.loadPath = function (path) {
2262 if (!(path in Translation._cache)) {
2263 var translations = require(path);
2264
2265 Translation._cache[path] = translations;
2266 }
2267
2268 return new Translation(Translation._cache[path]);
2269 };
2270
2271 return Translation;
2272 });
2273
2274 S2.define('select2/diacritics',[
2275
2276 ], function () {
2277 var diacritics = {
2278 '\u24B6': 'A',
2279 '\uFF21': 'A',
2280 '\u00C0': 'A',
2281 '\u00C1': 'A',
2282 '\u00C2': 'A',
2283 '\u1EA6': 'A',
2284 '\u1EA4': 'A',
2285 '\u1EAA': 'A',
2286 '\u1EA8': 'A',
2287 '\u00C3': 'A',
2288 '\u0100': 'A',
2289 '\u0102': 'A',
2290 '\u1EB0': 'A',
2291 '\u1EAE': 'A',
2292 '\u1EB4': 'A',
2293 '\u1EB2': 'A',
2294 '\u0226': 'A',
2295 '\u01E0': 'A',
2296 '\u00C4': 'A',
2297 '\u01DE': 'A',
2298 '\u1EA2': 'A',
2299 '\u00C5': 'A',
2300 '\u01FA': 'A',
2301 '\u01CD': 'A',
2302 '\u0200': 'A',
2303 '\u0202': 'A',
2304 '\u1EA0': 'A',
2305 '\u1EAC': 'A',
2306 '\u1EB6': 'A',
2307 '\u1E00': 'A',
2308 '\u0104': 'A',
2309 '\u023A': 'A',
2310 '\u2C6F': 'A',
2311 '\uA732': 'AA',
2312 '\u00C6': 'AE',
2313 '\u01FC': 'AE',
2314 '\u01E2': 'AE',
2315 '\uA734': 'AO',
2316 '\uA736': 'AU',
2317 '\uA738': 'AV',
2318 '\uA73A': 'AV',
2319 '\uA73C': 'AY',
2320 '\u24B7': 'B',
2321 '\uFF22': 'B',
2322 '\u1E02': 'B',
2323 '\u1E04': 'B',
2324 '\u1E06': 'B',
2325 '\u0243': 'B',
2326 '\u0182': 'B',
2327 '\u0181': 'B',
2328 '\u24B8': 'C',
2329 '\uFF23': 'C',
2330 '\u0106': 'C',
2331 '\u0108': 'C',
2332 '\u010A': 'C',
2333 '\u010C': 'C',
2334 '\u00C7': 'C',
2335 '\u1E08': 'C',
2336 '\u0187': 'C',
2337 '\u023B': 'C',
2338 '\uA73E': 'C',
2339 '\u24B9': 'D',
2340 '\uFF24': 'D',
2341 '\u1E0A': 'D',
2342 '\u010E': 'D',
2343 '\u1E0C': 'D',
2344 '\u1E10': 'D',
2345 '\u1E12': 'D',
2346 '\u1E0E': 'D',
2347 '\u0110': 'D',
2348 '\u018B': 'D',
2349 '\u018A': 'D',
2350 '\u0189': 'D',
2351 '\uA779': 'D',
2352 '\u01F1': 'DZ',
2353 '\u01C4': 'DZ',
2354 '\u01F2': 'Dz',
2355 '\u01C5': 'Dz',
2356 '\u24BA': 'E',
2357 '\uFF25': 'E',
2358 '\u00C8': 'E',
2359 '\u00C9': 'E',
2360 '\u00CA': 'E',
2361 '\u1EC0': 'E',
2362 '\u1EBE': 'E',
2363 '\u1EC4': 'E',
2364 '\u1EC2': 'E',
2365 '\u1EBC': 'E',
2366 '\u0112': 'E',
2367 '\u1E14': 'E',
2368 '\u1E16': 'E',
2369 '\u0114': 'E',
2370 '\u0116': 'E',
2371 '\u00CB': 'E',
2372 '\u1EBA': 'E',
2373 '\u011A': 'E',
2374 '\u0204': 'E',
2375 '\u0206': 'E',
2376 '\u1EB8': 'E',
2377 '\u1EC6': 'E',
2378 '\u0228': 'E',
2379 '\u1E1C': 'E',
2380 '\u0118': 'E',
2381 '\u1E18': 'E',
2382 '\u1E1A': 'E',
2383 '\u0190': 'E',
2384 '\u018E': 'E',
2385 '\u24BB': 'F',
2386 '\uFF26': 'F',
2387 '\u1E1E': 'F',
2388 '\u0191': 'F',
2389 '\uA77B': 'F',
2390 '\u24BC': 'G',
2391 '\uFF27': 'G',
2392 '\u01F4': 'G',
2393 '\u011C': 'G',
2394 '\u1E20': 'G',
2395 '\u011E': 'G',
2396 '\u0120': 'G',
2397 '\u01E6': 'G',
2398 '\u0122': 'G',
2399 '\u01E4': 'G',
2400 '\u0193': 'G',
2401 '\uA7A0': 'G',
2402 '\uA77D': 'G',
2403 '\uA77E': 'G',
2404 '\u24BD': 'H',
2405 '\uFF28': 'H',
2406 '\u0124': 'H',
2407 '\u1E22': 'H',
2408 '\u1E26': 'H',
2409 '\u021E': 'H',
2410 '\u1E24': 'H',
2411 '\u1E28': 'H',
2412 '\u1E2A': 'H',
2413 '\u0126': 'H',
2414 '\u2C67': 'H',
2415 '\u2C75': 'H',
2416 '\uA78D': 'H',
2417 '\u24BE': 'I',
2418 '\uFF29': 'I',
2419 '\u00CC': 'I',
2420 '\u00CD': 'I',
2421 '\u00CE': 'I',
2422 '\u0128': 'I',
2423 '\u012A': 'I',
2424 '\u012C': 'I',
2425 '\u0130': 'I',
2426 '\u00CF': 'I',
2427 '\u1E2E': 'I',
2428 '\u1EC8': 'I',
2429 '\u01CF': 'I',
2430 '\u0208': 'I',
2431 '\u020A': 'I',
2432 '\u1ECA': 'I',
2433 '\u012E': 'I',
2434 '\u1E2C': 'I',
2435 '\u0197': 'I',
2436 '\u24BF': 'J',
2437 '\uFF2A': 'J',
2438 '\u0134': 'J',
2439 '\u0248': 'J',
2440 '\u24C0': 'K',
2441 '\uFF2B': 'K',
2442 '\u1E30': 'K',
2443 '\u01E8': 'K',
2444 '\u1E32': 'K',
2445 '\u0136': 'K',
2446 '\u1E34': 'K',
2447 '\u0198': 'K',
2448 '\u2C69': 'K',
2449 '\uA740': 'K',
2450 '\uA742': 'K',
2451 '\uA744': 'K',
2452 '\uA7A2': 'K',
2453 '\u24C1': 'L',
2454 '\uFF2C': 'L',
2455 '\u013F': 'L',
2456 '\u0139': 'L',
2457 '\u013D': 'L',
2458 '\u1E36': 'L',
2459 '\u1E38': 'L',
2460 '\u013B': 'L',
2461 '\u1E3C': 'L',
2462 '\u1E3A': 'L',
2463 '\u0141': 'L',
2464 '\u023D': 'L',
2465 '\u2C62': 'L',
2466 '\u2C60': 'L',
2467 '\uA748': 'L',
2468 '\uA746': 'L',
2469 '\uA780': 'L',
2470 '\u01C7': 'LJ',
2471 '\u01C8': 'Lj',
2472 '\u24C2': 'M',
2473 '\uFF2D': 'M',
2474 '\u1E3E': 'M',
2475 '\u1E40': 'M',
2476 '\u1E42': 'M',
2477 '\u2C6E': 'M',
2478 '\u019C': 'M',
2479 '\u24C3': 'N',
2480 '\uFF2E': 'N',
2481 '\u01F8': 'N',
2482 '\u0143': 'N',
2483 '\u00D1': 'N',
2484 '\u1E44': 'N',
2485 '\u0147': 'N',
2486 '\u1E46': 'N',
2487 '\u0145': 'N',
2488 '\u1E4A': 'N',
2489 '\u1E48': 'N',
2490 '\u0220': 'N',
2491 '\u019D': 'N',
2492 '\uA790': 'N',
2493 '\uA7A4': 'N',
2494 '\u01CA': 'NJ',
2495 '\u01CB': 'Nj',
2496 '\u24C4': 'O',
2497 '\uFF2F': 'O',
2498 '\u00D2': 'O',
2499 '\u00D3': 'O',
2500 '\u00D4': 'O',
2501 '\u1ED2': 'O',
2502 '\u1ED0': 'O',
2503 '\u1ED6': 'O',
2504 '\u1ED4': 'O',
2505 '\u00D5': 'O',
2506 '\u1E4C': 'O',
2507 '\u022C': 'O',
2508 '\u1E4E': 'O',
2509 '\u014C': 'O',
2510 '\u1E50': 'O',
2511 '\u1E52': 'O',
2512 '\u014E': 'O',
2513 '\u022E': 'O',
2514 '\u0230': 'O',
2515 '\u00D6': 'O',
2516 '\u022A': 'O',
2517 '\u1ECE': 'O',
2518 '\u0150': 'O',
2519 '\u01D1': 'O',
2520 '\u020C': 'O',
2521 '\u020E': 'O',
2522 '\u01A0': 'O',
2523 '\u1EDC': 'O',
2524 '\u1EDA': 'O',
2525 '\u1EE0': 'O',
2526 '\u1EDE': 'O',
2527 '\u1EE2': 'O',
2528 '\u1ECC': 'O',
2529 '\u1ED8': 'O',
2530 '\u01EA': 'O',
2531 '\u01EC': 'O',
2532 '\u00D8': 'O',
2533 '\u01FE': 'O',
2534 '\u0186': 'O',
2535 '\u019F': 'O',
2536 '\uA74A': 'O',
2537 '\uA74C': 'O',
2538 '\u0152': 'OE',
2539 '\u01A2': 'OI',
2540 '\uA74E': 'OO',
2541 '\u0222': 'OU',
2542 '\u24C5': 'P',
2543 '\uFF30': 'P',
2544 '\u1E54': 'P',
2545 '\u1E56': 'P',
2546 '\u01A4': 'P',
2547 '\u2C63': 'P',
2548 '\uA750': 'P',
2549 '\uA752': 'P',
2550 '\uA754': 'P',
2551 '\u24C6': 'Q',
2552 '\uFF31': 'Q',
2553 '\uA756': 'Q',
2554 '\uA758': 'Q',
2555 '\u024A': 'Q',
2556 '\u24C7': 'R',
2557 '\uFF32': 'R',
2558 '\u0154': 'R',
2559 '\u1E58': 'R',
2560 '\u0158': 'R',
2561 '\u0210': 'R',
2562 '\u0212': 'R',
2563 '\u1E5A': 'R',
2564 '\u1E5C': 'R',
2565 '\u0156': 'R',
2566 '\u1E5E': 'R',
2567 '\u024C': 'R',
2568 '\u2C64': 'R',
2569 '\uA75A': 'R',
2570 '\uA7A6': 'R',
2571 '\uA782': 'R',
2572 '\u24C8': 'S',
2573 '\uFF33': 'S',
2574 '\u1E9E': 'S',
2575 '\u015A': 'S',
2576 '\u1E64': 'S',
2577 '\u015C': 'S',
2578 '\u1E60': 'S',
2579 '\u0160': 'S',
2580 '\u1E66': 'S',
2581 '\u1E62': 'S',
2582 '\u1E68': 'S',
2583 '\u0218': 'S',
2584 '\u015E': 'S',
2585 '\u2C7E': 'S',
2586 '\uA7A8': 'S',
2587 '\uA784': 'S',
2588 '\u24C9': 'T',
2589 '\uFF34': 'T',
2590 '\u1E6A': 'T',
2591 '\u0164': 'T',
2592 '\u1E6C': 'T',
2593 '\u021A': 'T',
2594 '\u0162': 'T',
2595 '\u1E70': 'T',
2596 '\u1E6E': 'T',
2597 '\u0166': 'T',
2598 '\u01AC': 'T',
2599 '\u01AE': 'T',
2600 '\u023E': 'T',
2601 '\uA786': 'T',
2602 '\uA728': 'TZ',
2603 '\u24CA': 'U',
2604 '\uFF35': 'U',
2605 '\u00D9': 'U',
2606 '\u00DA': 'U',
2607 '\u00DB': 'U',
2608 '\u0168': 'U',
2609 '\u1E78': 'U',
2610 '\u016A': 'U',
2611 '\u1E7A': 'U',
2612 '\u016C': 'U',
2613 '\u00DC': 'U',
2614 '\u01DB': 'U',
2615 '\u01D7': 'U',
2616 '\u01D5': 'U',
2617 '\u01D9': 'U',
2618 '\u1EE6': 'U',
2619 '\u016E': 'U',
2620 '\u0170': 'U',
2621 '\u01D3': 'U',
2622 '\u0214': 'U',
2623 '\u0216': 'U',
2624 '\u01AF': 'U',
2625 '\u1EEA': 'U',
2626 '\u1EE8': 'U',
2627 '\u1EEE': 'U',
2628 '\u1EEC': 'U',
2629 '\u1EF0': 'U',
2630 '\u1EE4': 'U',
2631 '\u1E72': 'U',
2632 '\u0172': 'U',
2633 '\u1E76': 'U',
2634 '\u1E74': 'U',
2635 '\u0244': 'U',
2636 '\u24CB': 'V',
2637 '\uFF36': 'V',
2638 '\u1E7C': 'V',
2639 '\u1E7E': 'V',
2640 '\u01B2': 'V',
2641 '\uA75E': 'V',
2642 '\u0245': 'V',
2643 '\uA760': 'VY',
2644 '\u24CC': 'W',
2645 '\uFF37': 'W',
2646 '\u1E80': 'W',
2647 '\u1E82': 'W',
2648 '\u0174': 'W',
2649 '\u1E86': 'W',
2650 '\u1E84': 'W',
2651 '\u1E88': 'W',
2652 '\u2C72': 'W',
2653 '\u24CD': 'X',
2654 '\uFF38': 'X',
2655 '\u1E8A': 'X',
2656 '\u1E8C': 'X',
2657 '\u24CE': 'Y',
2658 '\uFF39': 'Y',
2659 '\u1EF2': 'Y',
2660 '\u00DD': 'Y',
2661 '\u0176': 'Y',
2662 '\u1EF8': 'Y',
2663 '\u0232': 'Y',
2664 '\u1E8E': 'Y',
2665 '\u0178': 'Y',
2666 '\u1EF6': 'Y',
2667 '\u1EF4': 'Y',
2668 '\u01B3': 'Y',
2669 '\u024E': 'Y',
2670 '\u1EFE': 'Y',
2671 '\u24CF': 'Z',
2672 '\uFF3A': 'Z',
2673 '\u0179': 'Z',
2674 '\u1E90': 'Z',
2675 '\u017B': 'Z',
2676 '\u017D': 'Z',
2677 '\u1E92': 'Z',
2678 '\u1E94': 'Z',
2679 '\u01B5': 'Z',
2680 '\u0224': 'Z',
2681 '\u2C7F': 'Z',
2682 '\u2C6B': 'Z',
2683 '\uA762': 'Z',
2684 '\u24D0': 'a',
2685 '\uFF41': 'a',
2686 '\u1E9A': 'a',
2687 '\u00E0': 'a',
2688 '\u00E1': 'a',
2689 '\u00E2': 'a',
2690 '\u1EA7': 'a',
2691 '\u1EA5': 'a',
2692 '\u1EAB': 'a',
2693 '\u1EA9': 'a',
2694 '\u00E3': 'a',
2695 '\u0101': 'a',
2696 '\u0103': 'a',
2697 '\u1EB1': 'a',
2698 '\u1EAF': 'a',
2699 '\u1EB5': 'a',
2700 '\u1EB3': 'a',
2701 '\u0227': 'a',
2702 '\u01E1': 'a',
2703 '\u00E4': 'a',
2704 '\u01DF': 'a',
2705 '\u1EA3': 'a',
2706 '\u00E5': 'a',
2707 '\u01FB': 'a',
2708 '\u01CE': 'a',
2709 '\u0201': 'a',
2710 '\u0203': 'a',
2711 '\u1EA1': 'a',
2712 '\u1EAD': 'a',
2713 '\u1EB7': 'a',
2714 '\u1E01': 'a',
2715 '\u0105': 'a',
2716 '\u2C65': 'a',
2717 '\u0250': 'a',
2718 '\uA733': 'aa',
2719 '\u00E6': 'ae',
2720 '\u01FD': 'ae',
2721 '\u01E3': 'ae',
2722 '\uA735': 'ao',
2723 '\uA737': 'au',
2724 '\uA739': 'av',
2725 '\uA73B': 'av',
2726 '\uA73D': 'ay',
2727 '\u24D1': 'b',
2728 '\uFF42': 'b',
2729 '\u1E03': 'b',
2730 '\u1E05': 'b',
2731 '\u1E07': 'b',
2732 '\u0180': 'b',
2733 '\u0183': 'b',
2734 '\u0253': 'b',
2735 '\u24D2': 'c',
2736 '\uFF43': 'c',
2737 '\u0107': 'c',
2738 '\u0109': 'c',
2739 '\u010B': 'c',
2740 '\u010D': 'c',
2741 '\u00E7': 'c',
2742 '\u1E09': 'c',
2743 '\u0188': 'c',
2744 '\u023C': 'c',
2745 '\uA73F': 'c',
2746 '\u2184': 'c',
2747 '\u24D3': 'd',
2748 '\uFF44': 'd',
2749 '\u1E0B': 'd',
2750 '\u010F': 'd',
2751 '\u1E0D': 'd',
2752 '\u1E11': 'd',
2753 '\u1E13': 'd',
2754 '\u1E0F': 'd',
2755 '\u0111': 'd',
2756 '\u018C': 'd',
2757 '\u0256': 'd',
2758 '\u0257': 'd',
2759 '\uA77A': 'd',
2760 '\u01F3': 'dz',
2761 '\u01C6': 'dz',
2762 '\u24D4': 'e',
2763 '\uFF45': 'e',
2764 '\u00E8': 'e',
2765 '\u00E9': 'e',
2766 '\u00EA': 'e',
2767 '\u1EC1': 'e',
2768 '\u1EBF': 'e',
2769 '\u1EC5': 'e',
2770 '\u1EC3': 'e',
2771 '\u1EBD': 'e',
2772 '\u0113': 'e',
2773 '\u1E15': 'e',
2774 '\u1E17': 'e',
2775 '\u0115': 'e',
2776 '\u0117': 'e',
2777 '\u00EB': 'e',
2778 '\u1EBB': 'e',
2779 '\u011B': 'e',
2780 '\u0205': 'e',
2781 '\u0207': 'e',
2782 '\u1EB9': 'e',
2783 '\u1EC7': 'e',
2784 '\u0229': 'e',
2785 '\u1E1D': 'e',
2786 '\u0119': 'e',
2787 '\u1E19': 'e',
2788 '\u1E1B': 'e',
2789 '\u0247': 'e',
2790 '\u025B': 'e',
2791 '\u01DD': 'e',
2792 '\u24D5': 'f',
2793 '\uFF46': 'f',
2794 '\u1E1F': 'f',
2795 '\u0192': 'f',
2796 '\uA77C': 'f',
2797 '\u24D6': 'g',
2798 '\uFF47': 'g',
2799 '\u01F5': 'g',
2800 '\u011D': 'g',
2801 '\u1E21': 'g',
2802 '\u011F': 'g',
2803 '\u0121': 'g',
2804 '\u01E7': 'g',
2805 '\u0123': 'g',
2806 '\u01E5': 'g',
2807 '\u0260': 'g',
2808 '\uA7A1': 'g',
2809 '\u1D79': 'g',
2810 '\uA77F': 'g',
2811 '\u24D7': 'h',
2812 '\uFF48': 'h',
2813 '\u0125': 'h',
2814 '\u1E23': 'h',
2815 '\u1E27': 'h',
2816 '\u021F': 'h',
2817 '\u1E25': 'h',
2818 '\u1E29': 'h',
2819 '\u1E2B': 'h',
2820 '\u1E96': 'h',
2821 '\u0127': 'h',
2822 '\u2C68': 'h',
2823 '\u2C76': 'h',
2824 '\u0265': 'h',
2825 '\u0195': 'hv',
2826 '\u24D8': 'i',
2827 '\uFF49': 'i',
2828 '\u00EC': 'i',
2829 '\u00ED': 'i',
2830 '\u00EE': 'i',
2831 '\u0129': 'i',
2832 '\u012B': 'i',
2833 '\u012D': 'i',
2834 '\u00EF': 'i',
2835 '\u1E2F': 'i',
2836 '\u1EC9': 'i',
2837 '\u01D0': 'i',
2838 '\u0209': 'i',
2839 '\u020B': 'i',
2840 '\u1ECB': 'i',
2841 '\u012F': 'i',
2842 '\u1E2D': 'i',
2843 '\u0268': 'i',
2844 '\u0131': 'i',
2845 '\u24D9': 'j',
2846 '\uFF4A': 'j',
2847 '\u0135': 'j',
2848 '\u01F0': 'j',
2849 '\u0249': 'j',
2850 '\u24DA': 'k',
2851 '\uFF4B': 'k',
2852 '\u1E31': 'k',
2853 '\u01E9': 'k',
2854 '\u1E33': 'k',
2855 '\u0137': 'k',
2856 '\u1E35': 'k',
2857 '\u0199': 'k',
2858 '\u2C6A': 'k',
2859 '\uA741': 'k',
2860 '\uA743': 'k',
2861 '\uA745': 'k',
2862 '\uA7A3': 'k',
2863 '\u24DB': 'l',
2864 '\uFF4C': 'l',
2865 '\u0140': 'l',
2866 '\u013A': 'l',
2867 '\u013E': 'l',
2868 '\u1E37': 'l',
2869 '\u1E39': 'l',
2870 '\u013C': 'l',
2871 '\u1E3D': 'l',
2872 '\u1E3B': 'l',
2873 '\u017F': 'l',
2874 '\u0142': 'l',
2875 '\u019A': 'l',
2876 '\u026B': 'l',
2877 '\u2C61': 'l',
2878 '\uA749': 'l',
2879 '\uA781': 'l',
2880 '\uA747': 'l',
2881 '\u01C9': 'lj',
2882 '\u24DC': 'm',
2883 '\uFF4D': 'm',
2884 '\u1E3F': 'm',
2885 '\u1E41': 'm',
2886 '\u1E43': 'm',
2887 '\u0271': 'm',
2888 '\u026F': 'm',
2889 '\u24DD': 'n',
2890 '\uFF4E': 'n',
2891 '\u01F9': 'n',
2892 '\u0144': 'n',
2893 '\u00F1': 'n',
2894 '\u1E45': 'n',
2895 '\u0148': 'n',
2896 '\u1E47': 'n',
2897 '\u0146': 'n',
2898 '\u1E4B': 'n',
2899 '\u1E49': 'n',
2900 '\u019E': 'n',
2901 '\u0272': 'n',
2902 '\u0149': 'n',
2903 '\uA791': 'n',
2904 '\uA7A5': 'n',
2905 '\u01CC': 'nj',
2906 '\u24DE': 'o',
2907 '\uFF4F': 'o',
2908 '\u00F2': 'o',
2909 '\u00F3': 'o',
2910 '\u00F4': 'o',
2911 '\u1ED3': 'o',
2912 '\u1ED1': 'o',
2913 '\u1ED7': 'o',
2914 '\u1ED5': 'o',
2915 '\u00F5': 'o',
2916 '\u1E4D': 'o',
2917 '\u022D': 'o',
2918 '\u1E4F': 'o',
2919 '\u014D': 'o',
2920 '\u1E51': 'o',
2921 '\u1E53': 'o',
2922 '\u014F': 'o',
2923 '\u022F': 'o',
2924 '\u0231': 'o',
2925 '\u00F6': 'o',
2926 '\u022B': 'o',
2927 '\u1ECF': 'o',
2928 '\u0151': 'o',
2929 '\u01D2': 'o',
2930 '\u020D': 'o',
2931 '\u020F': 'o',
2932 '\u01A1': 'o',
2933 '\u1EDD': 'o',
2934 '\u1EDB': 'o',
2935 '\u1EE1': 'o',
2936 '\u1EDF': 'o',
2937 '\u1EE3': 'o',
2938 '\u1ECD': 'o',
2939 '\u1ED9': 'o',
2940 '\u01EB': 'o',
2941 '\u01ED': 'o',
2942 '\u00F8': 'o',
2943 '\u01FF': 'o',
2944 '\u0254': 'o',
2945 '\uA74B': 'o',
2946 '\uA74D': 'o',
2947 '\u0275': 'o',
2948 '\u0153': 'oe',
2949 '\u01A3': 'oi',
2950 '\u0223': 'ou',
2951 '\uA74F': 'oo',
2952 '\u24DF': 'p',
2953 '\uFF50': 'p',
2954 '\u1E55': 'p',
2955 '\u1E57': 'p',
2956 '\u01A5': 'p',
2957 '\u1D7D': 'p',
2958 '\uA751': 'p',
2959 '\uA753': 'p',
2960 '\uA755': 'p',
2961 '\u24E0': 'q',
2962 '\uFF51': 'q',
2963 '\u024B': 'q',
2964 '\uA757': 'q',
2965 '\uA759': 'q',
2966 '\u24E1': 'r',
2967 '\uFF52': 'r',
2968 '\u0155': 'r',
2969 '\u1E59': 'r',
2970 '\u0159': 'r',
2971 '\u0211': 'r',
2972 '\u0213': 'r',
2973 '\u1E5B': 'r',
2974 '\u1E5D': 'r',
2975 '\u0157': 'r',
2976 '\u1E5F': 'r',
2977 '\u024D': 'r',
2978 '\u027D': 'r',
2979 '\uA75B': 'r',
2980 '\uA7A7': 'r',
2981 '\uA783': 'r',
2982 '\u24E2': 's',
2983 '\uFF53': 's',
2984 '\u00DF': 's',
2985 '\u015B': 's',
2986 '\u1E65': 's',
2987 '\u015D': 's',
2988 '\u1E61': 's',
2989 '\u0161': 's',
2990 '\u1E67': 's',
2991 '\u1E63': 's',
2992 '\u1E69': 's',
2993 '\u0219': 's',
2994 '\u015F': 's',
2995 '\u023F': 's',
2996 '\uA7A9': 's',
2997 '\uA785': 's',
2998 '\u1E9B': 's',
2999 '\u24E3': 't',
3000 '\uFF54': 't',
3001 '\u1E6B': 't',
3002 '\u1E97': 't',
3003 '\u0165': 't',
3004 '\u1E6D': 't',
3005 '\u021B': 't',
3006 '\u0163': 't',
3007 '\u1E71': 't',
3008 '\u1E6F': 't',
3009 '\u0167': 't',
3010 '\u01AD': 't',
3011 '\u0288': 't',
3012 '\u2C66': 't',
3013 '\uA787': 't',
3014 '\uA729': 'tz',
3015 '\u24E4': 'u',
3016 '\uFF55': 'u',
3017 '\u00F9': 'u',
3018 '\u00FA': 'u',
3019 '\u00FB': 'u',
3020 '\u0169': 'u',
3021 '\u1E79': 'u',
3022 '\u016B': 'u',
3023 '\u1E7B': 'u',
3024 '\u016D': 'u',
3025 '\u00FC': 'u',
3026 '\u01DC': 'u',
3027 '\u01D8': 'u',
3028 '\u01D6': 'u',
3029 '\u01DA': 'u',
3030 '\u1EE7': 'u',
3031 '\u016F': 'u',
3032 '\u0171': 'u',
3033 '\u01D4': 'u',
3034 '\u0215': 'u',
3035 '\u0217': 'u',
3036 '\u01B0': 'u',
3037 '\u1EEB': 'u',
3038 '\u1EE9': 'u',
3039 '\u1EEF': 'u',
3040 '\u1EED': 'u',
3041 '\u1EF1': 'u',
3042 '\u1EE5': 'u',
3043 '\u1E73': 'u',
3044 '\u0173': 'u',
3045 '\u1E77': 'u',
3046 '\u1E75': 'u',
3047 '\u0289': 'u',
3048 '\u24E5': 'v',
3049 '\uFF56': 'v',
3050 '\u1E7D': 'v',
3051 '\u1E7F': 'v',
3052 '\u028B': 'v',
3053 '\uA75F': 'v',
3054 '\u028C': 'v',
3055 '\uA761': 'vy',
3056 '\u24E6': 'w',
3057 '\uFF57': 'w',
3058 '\u1E81': 'w',
3059 '\u1E83': 'w',
3060 '\u0175': 'w',
3061 '\u1E87': 'w',
3062 '\u1E85': 'w',
3063 '\u1E98': 'w',
3064 '\u1E89': 'w',
3065 '\u2C73': 'w',
3066 '\u24E7': 'x',
3067 '\uFF58': 'x',
3068 '\u1E8B': 'x',
3069 '\u1E8D': 'x',
3070 '\u24E8': 'y',
3071 '\uFF59': 'y',
3072 '\u1EF3': 'y',
3073 '\u00FD': 'y',
3074 '\u0177': 'y',
3075 '\u1EF9': 'y',
3076 '\u0233': 'y',
3077 '\u1E8F': 'y',
3078 '\u00FF': 'y',
3079 '\u1EF7': 'y',
3080 '\u1E99': 'y',
3081 '\u1EF5': 'y',
3082 '\u01B4': 'y',
3083 '\u024F': 'y',
3084 '\u1EFF': 'y',
3085 '\u24E9': 'z',
3086 '\uFF5A': 'z',
3087 '\u017A': 'z',
3088 '\u1E91': 'z',
3089 '\u017C': 'z',
3090 '\u017E': 'z',
3091 '\u1E93': 'z',
3092 '\u1E95': 'z',
3093 '\u01B6': 'z',
3094 '\u0225': 'z',
3095 '\u0240': 'z',
3096 '\u2C6C': 'z',
3097 '\uA763': 'z',
3098 '\u0386': '\u0391',
3099 '\u0388': '\u0395',
3100 '\u0389': '\u0397',
3101 '\u038A': '\u0399',
3102 '\u03AA': '\u0399',
3103 '\u038C': '\u039F',
3104 '\u038E': '\u03A5',
3105 '\u03AB': '\u03A5',
3106 '\u038F': '\u03A9',
3107 '\u03AC': '\u03B1',
3108 '\u03AD': '\u03B5',
3109 '\u03AE': '\u03B7',
3110 '\u03AF': '\u03B9',
3111 '\u03CA': '\u03B9',
3112 '\u0390': '\u03B9',
3113 '\u03CC': '\u03BF',
3114 '\u03CD': '\u03C5',
3115 '\u03CB': '\u03C5',
3116 '\u03B0': '\u03C5',
3117 '\u03CE': '\u03C9',
3118 '\u03C2': '\u03C3',
3119 '\u2019': '\''
3120 };
3121
3122 return diacritics;
3123 });
3124
3125 S2.define('select2/data/base',[
3126 '../utils'
3127 ], function (Utils) {
3128 function BaseAdapter ($element, options) {
3129 BaseAdapter.__super__.constructor.call(this);
3130 }
3131
3132 Utils.Extend(BaseAdapter, Utils.Observable);
3133
3134 BaseAdapter.prototype.current = function (callback) {
3135 throw new Error('The `current` method must be defined in child classes.');
3136 };
3137
3138 BaseAdapter.prototype.query = function (params, callback) {
3139 throw new Error('The `query` method must be defined in child classes.');
3140 };
3141
3142 BaseAdapter.prototype.bind = function (container, $container) {
3143 // Can be implemented in subclasses
3144 };
3145
3146 BaseAdapter.prototype.destroy = function () {
3147 // Can be implemented in subclasses
3148 };
3149
3150 BaseAdapter.prototype.generateResultId = function (container, data) {
3151 var id = container.id + '-result-';
3152
3153 id += Utils.generateChars(4);
3154
3155 if (data.id != null) {
3156 id += '-' + data.id.toString();
3157 } else {
3158 id += '-' + Utils.generateChars(4);
3159 }
3160 return id;
3161 };
3162
3163 return BaseAdapter;
3164 });
3165
3166 S2.define('select2/data/select',[
3167 './base',
3168 '../utils',
3169 'jquery'
3170 ], function (BaseAdapter, Utils, $) {
3171 function SelectAdapter ($element, options) {
3172 this.$element = $element;
3173 this.options = options;
3174
3175 SelectAdapter.__super__.constructor.call(this);
3176 }
3177
3178 Utils.Extend(SelectAdapter, BaseAdapter);
3179
3180 SelectAdapter.prototype.current = function (callback) {
3181 var data = [];
3182 var self = this;
3183
3184 this.$element.find(':selected').each(function () {
3185 var $option = $(this);
3186
3187 var option = self.item($option);
3188
3189 data.push(option);
3190 });
3191
3192 callback(data);
3193 };
3194
3195 SelectAdapter.prototype.select = function (data) {
3196 var self = this;
3197
3198 data.selected = true;
3199
3200 // If data.element is a DOM node, use it instead
3201 if ($(data.element).is('option')) {
3202 data.element.selected = true;
3203
3204 this.$element.trigger('change');
3205
3206 return;
3207 }
3208
3209 if (this.$element.prop('multiple')) {
3210 this.current(function (currentData) {
3211 var val = [];
3212
3213 data = [data];
3214 data.push.apply(data, currentData);
3215
3216 for (var d = 0; d < data.length; d++) {
3217 var id = data[d].id;
3218
3219 if ($.inArray(id, val) === -1) {
3220 val.push(id);
3221 }
3222 }
3223
3224 self.$element.val(val);
3225 self.$element.trigger('change');
3226 });
3227 } else {
3228 var val = data.id;
3229
3230 this.$element.val(val);
3231 this.$element.trigger('change');
3232 }
3233 };
3234
3235 SelectAdapter.prototype.unselect = function (data) {
3236 var self = this;
3237
3238 if (!this.$element.prop('multiple')) {
3239 return;
3240 }
3241
3242 data.selected = false;
3243
3244 if ($(data.element).is('option')) {
3245 data.element.selected = false;
3246
3247 this.$element.trigger('change');
3248
3249 return;
3250 }
3251
3252 this.current(function (currentData) {
3253 var val = [];
3254
3255 for (var d = 0; d < currentData.length; d++) {
3256 var id = currentData[d].id;
3257
3258 if (id !== data.id && $.inArray(id, val) === -1) {
3259 val.push(id);
3260 }
3261 }
3262
3263 self.$element.val(val);
3264
3265 self.$element.trigger('change');
3266 });
3267 };
3268
3269 SelectAdapter.prototype.bind = function (container, $container) {
3270 var self = this;
3271
3272 this.container = container;
3273
3274 container.on('select', function (params) {
3275 self.select(params.data);
3276 });
3277
3278 container.on('unselect', function (params) {
3279 self.unselect(params.data);
3280 });
3281 };
3282
3283 SelectAdapter.prototype.destroy = function () {
3284 // Remove anything added to child elements
3285 this.$element.find('*').each(function () {
3286 // Remove any custom data set by Select2
3287 Utils.RemoveData(this);
3288 });
3289 };
3290
3291 SelectAdapter.prototype.query = function (params, callback) {
3292 var data = [];
3293 var self = this;
3294
3295 var $options = this.$element.children();
3296
3297 $options.each(function () {
3298 var $option = $(this);
3299
3300 if (!$option.is('option') && !$option.is('optgroup')) {
3301 return;
3302 }
3303
3304 var option = self.item($option);
3305
3306 var matches = self.matches(params, option);
3307
3308 if (matches !== null) {
3309 data.push(matches);
3310 }
3311 });
3312
3313 callback({
3314 results: data
3315 });
3316 };
3317
3318 SelectAdapter.prototype.addOptions = function ($options) {
3319 Utils.appendMany(this.$element, $options);
3320 };
3321
3322 SelectAdapter.prototype.option = function (data) {
3323 var option;
3324
3325 if (data.children) {
3326 option = document.createElement('optgroup');
3327 option.label = data.text;
3328 } else {
3329 option = document.createElement('option');
3330
3331 if (option.textContent !== undefined) {
3332 option.textContent = data.text;
3333 } else {
3334 option.innerText = data.text;
3335 }
3336 }
3337
3338 if (data.id !== undefined) {
3339 option.value = data.id;
3340 }
3341
3342 if (data.disabled) {
3343 option.disabled = true;
3344 }
3345
3346 if (data.selected) {
3347 option.selected = true;
3348 }
3349
3350 if (data.title) {
3351 option.title = data.title;
3352 }
3353
3354 var $option = $(option);
3355
3356 var normalizedData = this._normalizeItem(data);
3357 normalizedData.element = option;
3358
3359 // Override the option's data with the combined data
3360 Utils.StoreData(option, 'data', normalizedData);
3361
3362 return $option;
3363 };
3364
3365 SelectAdapter.prototype.item = function ($option) {
3366 var data = {};
3367
3368 data = Utils.GetData($option[0], 'data');
3369
3370 if (data != null) {
3371 return data;
3372 }
3373
3374 if ($option.is('option')) {
3375 data = {
3376 id: $option.val(),
3377 text: $option.text(),
3378 disabled: $option.prop('disabled'),
3379 selected: $option.prop('selected'),
3380 title: $option.prop('title')
3381 };
3382 } else if ($option.is('optgroup')) {
3383 data = {
3384 text: $option.prop('label'),
3385 children: [],
3386 title: $option.prop('title')
3387 };
3388
3389 var $children = $option.children('option');
3390 var children = [];
3391
3392 for (var c = 0; c < $children.length; c++) {
3393 var $child = $($children[c]);
3394
3395 var child = this.item($child);
3396
3397 children.push(child);
3398 }
3399
3400 data.children = children;
3401 }
3402
3403 data = this._normalizeItem(data);
3404 data.element = $option[0];
3405
3406 Utils.StoreData($option[0], 'data', data);
3407
3408 return data;
3409 };
3410
3411 SelectAdapter.prototype._normalizeItem = function (item) {
3412 if (item !== Object(item)) {
3413 item = {
3414 id: item,
3415 text: item
3416 };
3417 }
3418
3419 item = $.extend({}, {
3420 text: ''
3421 }, item);
3422
3423 var defaults = {
3424 selected: false,
3425 disabled: false
3426 };
3427
3428 if (item.id != null) {
3429 item.id = item.id.toString();
3430 }
3431
3432 if (item.text != null) {
3433 item.text = item.text.toString();
3434 }
3435
3436 if (item._resultId == null && item.id && this.container != null) {
3437 item._resultId = this.generateResultId(this.container, item);
3438 }
3439
3440 return $.extend({}, defaults, item);
3441 };
3442
3443 SelectAdapter.prototype.matches = function (params, data) {
3444 var matcher = this.options.get('matcher');
3445
3446 return matcher(params, data);
3447 };
3448
3449 return SelectAdapter;
3450 });
3451
3452 S2.define('select2/data/array',[
3453 './select',
3454 '../utils',
3455 'jquery'
3456 ], function (SelectAdapter, Utils, $) {
3457 function ArrayAdapter ($element, options) {
3458 this._dataToConvert = options.get('data') || [];
3459
3460 ArrayAdapter.__super__.constructor.call(this, $element, options);
3461 }
3462
3463 Utils.Extend(ArrayAdapter, SelectAdapter);
3464
3465 ArrayAdapter.prototype.bind = function (container, $container) {
3466 ArrayAdapter.__super__.bind.call(this, container, $container);
3467
3468 this.addOptions(this.convertToOptions(this._dataToConvert));
3469 };
3470
3471 ArrayAdapter.prototype.select = function (data) {
3472 var $option = this.$element.find('option').filter(function (i, elm) {
3473 return elm.value == data.id.toString();
3474 });
3475
3476 if ($option.length === 0) {
3477 $option = this.option(data);
3478
3479 this.addOptions($option);
3480 }
3481
3482 ArrayAdapter.__super__.select.call(this, data);
3483 };
3484
3485 ArrayAdapter.prototype.convertToOptions = function (data) {
3486 var self = this;
3487
3488 var $existing = this.$element.find('option');
3489 var existingIds = $existing.map(function () {
3490 return self.item($(this)).id;
3491 }).get();
3492
3493 var $options = [];
3494
3495 // Filter out all items except for the one passed in the argument
3496 function onlyItem (item) {
3497 return function () {
3498 return $(this).val() == item.id;
3499 };
3500 }
3501
3502 for (var d = 0; d < data.length; d++) {
3503 var item = this._normalizeItem(data[d]);
3504
3505 // Skip items which were pre-loaded, only merge the data
3506 if ($.inArray(item.id, existingIds) >= 0) {
3507 var $existingOption = $existing.filter(onlyItem(item));
3508
3509 var existingData = this.item($existingOption);
3510 var newData = $.extend(true, {}, item, existingData);
3511
3512 var $newOption = this.option(newData);
3513
3514 $existingOption.replaceWith($newOption);
3515
3516 continue;
3517 }
3518
3519 var $option = this.option(item);
3520
3521 if (item.children) {
3522 var $children = this.convertToOptions(item.children);
3523
3524 Utils.appendMany($option, $children);
3525 }
3526
3527 $options.push($option);
3528 }
3529
3530 return $options;
3531 };
3532
3533 return ArrayAdapter;
3534 });
3535
3536 S2.define('select2/data/ajax',[
3537 './array',
3538 '../utils',
3539 'jquery'
3540 ], function (ArrayAdapter, Utils, $) {
3541 function AjaxAdapter ($element, options) {
3542 this.ajaxOptions = this._applyDefaults(options.get('ajax'));
3543
3544 if (this.ajaxOptions.processResults != null) {
3545 this.processResults = this.ajaxOptions.processResults;
3546 }
3547
3548 AjaxAdapter.__super__.constructor.call(this, $element, options);
3549 }
3550
3551 Utils.Extend(AjaxAdapter, ArrayAdapter);
3552
3553 AjaxAdapter.prototype._applyDefaults = function (options) {
3554 var defaults = {
3555 data: function (params) {
3556 return $.extend({}, params, {
3557 q: params.term
3558 });
3559 },
3560 transport: function (params, success, failure) {
3561 var $request = $.ajax(params);
3562
3563 $request.then(success);
3564 $request.fail(failure);
3565
3566 return $request;
3567 }
3568 };
3569
3570 return $.extend({}, defaults, options, true);
3571 };
3572
3573 AjaxAdapter.prototype.processResults = function (results) {
3574 return results;
3575 };
3576
3577 AjaxAdapter.prototype.query = function (params, callback) {
3578 var matches = [];
3579 var self = this;
3580
3581 if (this._request != null) {
3582 // JSONP requests cannot always be aborted
3583 if ($.isFunction(this._request.abort)) {
3584 this._request.abort();
3585 }
3586
3587 this._request = null;
3588 }
3589
3590 var options = $.extend({
3591 type: 'GET'
3592 }, this.ajaxOptions);
3593
3594 if (typeof options.url === 'function') {
3595 options.url = options.url.call(this.$element, params);
3596 }
3597
3598 if (typeof options.data === 'function') {
3599 options.data = options.data.call(this.$element, params);
3600 }
3601
3602 function request () {
3603 var $request = options.transport(options, function (data) {
3604 var results = self.processResults(data, params);
3605
3606 if (self.options.get('debug') && window.console && console.error) {
3607 // Check to make sure that the response included a `results` key.
3608 if (!results || !results.results || !$.isArray(results.results)) {
3609 console.error(
3610 'Select2: The AJAX results did not return an array in the ' +
3611 '`results` key of the response.'
3612 );
3613 }
3614 }
3615
3616 callback(results);
3617 }, function () {
3618 // Attempt to detect if a request was aborted
3619 // Only works if the transport exposes a status property
3620 if ('status' in $request &&
3621 ($request.status === 0 || $request.status === '0')) {
3622 return;
3623 }
3624
3625 self.trigger('results:message', {
3626 message: 'errorLoading'
3627 });
3628 });
3629
3630 self._request = $request;
3631 }
3632
3633 if (this.ajaxOptions.delay && params.term != null) {
3634 if (this._queryTimeout) {
3635 window.clearTimeout(this._queryTimeout);
3636 }
3637
3638 this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay);
3639 } else {
3640 request();
3641 }
3642 };
3643
3644 return AjaxAdapter;
3645 });
3646
3647 S2.define('select2/data/tags',[
3648 'jquery'
3649 ], function ($) {
3650 function Tags (decorated, $element, options) {
3651 var tags = options.get('tags');
3652
3653 var createTag = options.get('createTag');
3654
3655 if (createTag !== undefined) {
3656 this.createTag = createTag;
3657 }
3658
3659 var insertTag = options.get('insertTag');
3660
3661 if (insertTag !== undefined) {
3662 this.insertTag = insertTag;
3663 }
3664
3665 decorated.call(this, $element, options);
3666
3667 if ($.isArray(tags)) {
3668 for (var t = 0; t < tags.length; t++) {
3669 var tag = tags[t];
3670 var item = this._normalizeItem(tag);
3671
3672 var $option = this.option(item);
3673
3674 this.$element.append($option);
3675 }
3676 }
3677 }
3678
3679 Tags.prototype.query = function (decorated, params, callback) {
3680 var self = this;
3681
3682 this._removeOldTags();
3683
3684 if (params.term == null || params.page != null) {
3685 decorated.call(this, params, callback);
3686 return;
3687 }
3688
3689 function wrapper (obj, child) {
3690 var data = obj.results;
3691
3692 for (var i = 0; i < data.length; i++) {
3693 var option = data[i];
3694
3695 var checkChildren = (
3696 option.children != null &&
3697 !wrapper({
3698 results: option.children
3699 }, true)
3700 );
3701
3702 var optionText = (option.text || '').toUpperCase();
3703 var paramsTerm = (params.term || '').toUpperCase();
3704
3705 var checkText = optionText === paramsTerm;
3706
3707 if (checkText || checkChildren) {
3708 if (child) {
3709 return false;
3710 }
3711
3712 obj.data = data;
3713 callback(obj);
3714
3715 return;
3716 }
3717 }
3718
3719 if (child) {
3720 return true;
3721 }
3722
3723 var tag = self.createTag(params);
3724
3725 if (tag != null) {
3726 var $option = self.option(tag);
3727 $option.attr('data-select2-tag', true);
3728
3729 self.addOptions([$option]);
3730
3731 self.insertTag(data, tag);
3732 }
3733
3734 obj.results = data;
3735
3736 callback(obj);
3737 }
3738
3739 decorated.call(this, params, wrapper);
3740 };
3741
3742 Tags.prototype.createTag = function (decorated, params) {
3743 var term = $.trim(params.term);
3744
3745 if (term === '') {
3746 return null;
3747 }
3748
3749 return {
3750 id: term,
3751 text: term
3752 };
3753 };
3754
3755 Tags.prototype.insertTag = function (_, data, tag) {
3756 data.unshift(tag);
3757 };
3758
3759 Tags.prototype._removeOldTags = function (_) {
3760 var $options = this.$element.find('option[data-select2-tag]');
3761
3762 $options.each(function () {
3763 if (this.selected) {
3764 return;
3765 }
3766
3767 $(this).remove();
3768 });
3769 };
3770
3771 return Tags;
3772 });
3773
3774 S2.define('select2/data/tokenizer',[
3775 'jquery'
3776 ], function ($) {
3777 function Tokenizer (decorated, $element, options) {
3778 var tokenizer = options.get('tokenizer');
3779
3780 if (tokenizer !== undefined) {
3781 this.tokenizer = tokenizer;
3782 }
3783
3784 decorated.call(this, $element, options);
3785 }
3786
3787 Tokenizer.prototype.bind = function (decorated, container, $container) {
3788 decorated.call(this, container, $container);
3789
3790 this.$search = container.dropdown.$search || container.selection.$search ||
3791 $container.find('.select2-search__field');
3792 };
3793
3794 Tokenizer.prototype.query = function (decorated, params, callback) {
3795 var self = this;
3796
3797 function createAndSelect (data) {
3798 // Normalize the data object so we can use it for checks
3799 var item = self._normalizeItem(data);
3800
3801 // Check if the data object already exists as a tag
3802 // Select it if it doesn't
3803 var $existingOptions = self.$element.find('option').filter(function () {
3804 return $(this).val() === item.id;
3805 });
3806
3807 // If an existing option wasn't found for it, create the option
3808 if (!$existingOptions.length) {
3809 var $option = self.option(item);
3810 $option.attr('data-select2-tag', true);
3811
3812 self._removeOldTags();
3813 self.addOptions([$option]);
3814 }
3815
3816 // Select the item, now that we know there is an option for it
3817 select(item);
3818 }
3819
3820 function select (data) {
3821 self.trigger('select', {
3822 data: data
3823 });
3824 }
3825
3826 params.term = params.term || '';
3827
3828 var tokenData = this.tokenizer(params, this.options, createAndSelect);
3829
3830 if (tokenData.term !== params.term) {
3831 // Replace the search term if we have the search box
3832 if (this.$search.length) {
3833 this.$search.val(tokenData.term);
3834 this.$search.trigger('focus');
3835 }
3836
3837 params.term = tokenData.term;
3838 }
3839
3840 decorated.call(this, params, callback);
3841 };
3842
3843 Tokenizer.prototype.tokenizer = function (_, params, options, callback) {
3844 var separators = options.get('tokenSeparators') || [];
3845 var term = params.term;
3846 var i = 0;
3847
3848 var createTag = this.createTag || function (params) {
3849 return {
3850 id: params.term,
3851 text: params.term
3852 };
3853 };
3854
3855 while (i < term.length) {
3856 var termChar = term[i];
3857
3858 if ($.inArray(termChar, separators) === -1) {
3859 i++;
3860
3861 continue;
3862 }
3863
3864 var part = term.substr(0, i);
3865 var partParams = $.extend({}, params, {
3866 term: part
3867 });
3868
3869 var data = createTag(partParams);
3870
3871 if (data == null) {
3872 i++;
3873 continue;
3874 }
3875
3876 callback(data);
3877
3878 // Reset the term to not include the tokenized portion
3879 term = term.substr(i + 1) || '';
3880 i = 0;
3881 }
3882
3883 return {
3884 term: term
3885 };
3886 };
3887
3888 return Tokenizer;
3889 });
3890
3891 S2.define('select2/data/minimumInputLength',[
3892
3893 ], function () {
3894 function MinimumInputLength (decorated, $e, options) {
3895 this.minimumInputLength = options.get('minimumInputLength');
3896
3897 decorated.call(this, $e, options);
3898 }
3899
3900 MinimumInputLength.prototype.query = function (decorated, params, callback) {
3901 params.term = params.term || '';
3902
3903 if (params.term.length < this.minimumInputLength) {
3904 this.trigger('results:message', {
3905 message: 'inputTooShort',
3906 args: {
3907 minimum: this.minimumInputLength,
3908 input: params.term,
3909 params: params
3910 }
3911 });
3912
3913 return;
3914 }
3915
3916 decorated.call(this, params, callback);
3917 };
3918
3919 return MinimumInputLength;
3920 });
3921
3922 S2.define('select2/data/maximumInputLength',[
3923
3924 ], function () {
3925 function MaximumInputLength (decorated, $e, options) {
3926 this.maximumInputLength = options.get('maximumInputLength');
3927
3928 decorated.call(this, $e, options);
3929 }
3930
3931 MaximumInputLength.prototype.query = function (decorated, params, callback) {
3932 params.term = params.term || '';
3933
3934 if (this.maximumInputLength > 0 &&
3935 params.term.length > this.maximumInputLength) {
3936 this.trigger('results:message', {
3937 message: 'inputTooLong',
3938 args: {
3939 maximum: this.maximumInputLength,
3940 input: params.term,
3941 params: params
3942 }
3943 });
3944
3945 return;
3946 }
3947
3948 decorated.call(this, params, callback);
3949 };
3950
3951 return MaximumInputLength;
3952 });
3953
3954 S2.define('select2/data/maximumSelectionLength',[
3955
3956 ], function (){
3957 function MaximumSelectionLength (decorated, $e, options) {
3958 this.maximumSelectionLength = options.get('maximumSelectionLength');
3959
3960 decorated.call(this, $e, options);
3961 }
3962
3963 MaximumSelectionLength.prototype.bind =
3964 function (decorated, container, $container) {
3965 var self = this;
3966
3967 decorated.call(this, container, $container);
3968
3969 container.on('select', function () {
3970 self._checkIfMaximumSelected();
3971 });
3972 };
3973
3974 MaximumSelectionLength.prototype.query =
3975 function (decorated, params, callback) {
3976 var self = this;
3977
3978 this._checkIfMaximumSelected(function () {
3979 decorated.call(self, params, callback);
3980 });
3981 };
3982
3983 MaximumSelectionLength.prototype._checkIfMaximumSelected =
3984 function (_, successCallback) {
3985 var self = this;
3986
3987 this.current(function (currentData) {
3988 var count = currentData != null ? currentData.length : 0;
3989 if (self.maximumSelectionLength > 0 &&
3990 count >= self.maximumSelectionLength) {
3991 self.trigger('results:message', {
3992 message: 'maximumSelected',
3993 args: {
3994 maximum: self.maximumSelectionLength
3995 }
3996 });
3997 return;
3998 }
3999
4000 if (successCallback) {
4001 successCallback();
4002 }
4003 });
4004 };
4005
4006 return MaximumSelectionLength;
4007 });
4008
4009 S2.define('select2/dropdown',[
4010 'jquery',
4011 './utils'
4012 ], function ($, Utils) {
4013 function Dropdown ($element, options) {
4014 this.$element = $element;
4015 this.options = options;
4016
4017 Dropdown.__super__.constructor.call(this);
4018 }
4019
4020 Utils.Extend(Dropdown, Utils.Observable);
4021
4022 Dropdown.prototype.render = function () {
4023 var $dropdown = $(
4024 '<span class="select2-dropdown">' +
4025 '<span class="select2-results"></span>' +
4026 '</span>'
4027 );
4028
4029 $dropdown.attr('dir', this.options.get('dir'));
4030
4031 this.$dropdown = $dropdown;
4032
4033 return $dropdown;
4034 };
4035
4036 Dropdown.prototype.bind = function () {
4037 // Should be implemented in subclasses
4038 };
4039
4040 Dropdown.prototype.position = function ($dropdown, $container) {
4041 // Should be implemented in subclasses
4042 };
4043
4044 Dropdown.prototype.destroy = function () {
4045 // Remove the dropdown from the DOM
4046 this.$dropdown.remove();
4047 };
4048
4049 return Dropdown;
4050 });
4051
4052 S2.define('select2/dropdown/search',[
4053 'jquery',
4054 '../utils'
4055 ], function ($, Utils) {
4056 function Search () { }
4057
4058 Search.prototype.render = function (decorated) {
4059 var $rendered = decorated.call(this);
4060
4061 var $search = $(
4062 '<span class="select2-search select2-search--dropdown">' +
4063 '<input class="select2-search__field" type="search" tabindex="-1"' +
4064 ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
4065 ' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
4066 '</span>'
4067 );
4068
4069 this.$searchContainer = $search;
4070 this.$search = $search.find('input');
4071
4072 $rendered.prepend($search);
4073
4074 return $rendered;
4075 };
4076
4077 Search.prototype.bind = function (decorated, container, $container) {
4078 var self = this;
4079
4080 var resultsId = container.id + '-results';
4081
4082 decorated.call(this, container, $container);
4083
4084 this.$search.on('keydown', function (evt) {
4085 self.trigger('keypress', evt);
4086
4087 self._keyUpPrevented = evt.isDefaultPrevented();
4088 });
4089
4090 // Workaround for browsers which do not support the `input` event
4091 // This will prevent double-triggering of events for browsers which support
4092 // both the `keyup` and `input` events.
4093 this.$search.on('input', function (evt) {
4094 // Unbind the duplicated `keyup` event
4095 $(this).off('keyup');
4096 });
4097
4098 this.$search.on('keyup input', function (evt) {
4099 self.handleSearch(evt);
4100 });
4101
4102 container.on('open', function () {
4103 self.$search.attr('tabindex', 0);
4104 self.$search.attr('aria-controls', resultsId);
4105
4106 self.$search.trigger('focus');
4107
4108 window.setTimeout(function () {
4109 self.$search.trigger('focus');
4110 }, 0);
4111 });
4112
4113 container.on('close', function () {
4114 self.$search.attr('tabindex', -1);
4115 self.$search.removeAttr('aria-controls');
4116 self.$search.removeAttr('aria-activedescendant');
4117
4118 self.$search.val('');
4119 self.$search.trigger('blur');
4120 });
4121
4122 container.on('focus', function () {
4123 if (!container.isOpen()) {
4124 self.$search.trigger('focus');
4125 }
4126 });
4127
4128 container.on('results:all', function (params) {
4129 if (params.query.term == null || params.query.term === '') {
4130 var showSearch = self.showSearch(params);
4131
4132 if (showSearch) {
4133 self.$searchContainer.removeClass('select2-search--hide');
4134 } else {
4135 self.$searchContainer.addClass('select2-search--hide');
4136 }
4137 }
4138 });
4139
4140 container.on('results:focus', function (params) {
4141 if (params.data._resultId) {
4142 self.$search.attr('aria-activedescendant', params.data._resultId);
4143 } else {
4144 self.$search.removeAttr('aria-activedescendant');
4145 }
4146 });
4147 };
4148
4149 Search.prototype.handleSearch = function (evt) {
4150 if (!this._keyUpPrevented) {
4151 var input = this.$search.val();
4152
4153 this.trigger('query', {
4154 term: input
4155 });
4156 }
4157
4158 this._keyUpPrevented = false;
4159 };
4160
4161 Search.prototype.showSearch = function (_, params) {
4162 return true;
4163 };
4164
4165 return Search;
4166 });
4167
4168 S2.define('select2/dropdown/hidePlaceholder',[
4169
4170 ], function () {
4171 function HidePlaceholder (decorated, $element, options, dataAdapter) {
4172 this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
4173
4174 decorated.call(this, $element, options, dataAdapter);
4175 }
4176
4177 HidePlaceholder.prototype.append = function (decorated, data) {
4178 data.results = this.removePlaceholder(data.results);
4179
4180 decorated.call(this, data);
4181 };
4182
4183 HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) {
4184 if (typeof placeholder === 'string') {
4185 placeholder = {
4186 id: '',
4187 text: placeholder
4188 };
4189 }
4190
4191 return placeholder;
4192 };
4193
4194 HidePlaceholder.prototype.removePlaceholder = function (_, data) {
4195 var modifiedData = data.slice(0);
4196
4197 for (var d = data.length - 1; d >= 0; d--) {
4198 var item = data[d];
4199
4200 if (this.placeholder.id === item.id) {
4201 modifiedData.splice(d, 1);
4202 }
4203 }
4204
4205 return modifiedData;
4206 };
4207
4208 return HidePlaceholder;
4209 });
4210
4211 S2.define('select2/dropdown/infiniteScroll',[
4212 'jquery'
4213 ], function ($) {
4214 function InfiniteScroll (decorated, $element, options, dataAdapter) {
4215 this.lastParams = {};
4216
4217 decorated.call(this, $element, options, dataAdapter);
4218
4219 this.$loadingMore = this.createLoadingMore();
4220 this.loading = false;
4221 }
4222
4223 InfiniteScroll.prototype.append = function (decorated, data) {
4224 this.$loadingMore.remove();
4225 this.loading = false;
4226
4227 decorated.call(this, data);
4228
4229 if (this.showLoadingMore(data)) {
4230 this.$results.append(this.$loadingMore);
4231 this.loadMoreIfNeeded();
4232 }
4233 };
4234
4235 InfiniteScroll.prototype.bind = function (decorated, container, $container) {
4236 var self = this;
4237
4238 decorated.call(this, container, $container);
4239
4240 container.on('query', function (params) {
4241 self.lastParams = params;
4242 self.loading = true;
4243 });
4244
4245 container.on('query:append', function (params) {
4246 self.lastParams = params;
4247 self.loading = true;
4248 });
4249
4250 this.$results.on('scroll', this.loadMoreIfNeeded.bind(this));
4251 };
4252
4253 InfiniteScroll.prototype.loadMoreIfNeeded = function () {
4254 var isLoadMoreVisible = $.contains(
4255 document.documentElement,
4256 this.$loadingMore[0]
4257 );
4258
4259 if (this.loading || !isLoadMoreVisible) {
4260 return;
4261 }
4262
4263 var currentOffset = this.$results.offset().top +
4264 this.$results.outerHeight(false);
4265 var loadingMoreOffset = this.$loadingMore.offset().top +
4266 this.$loadingMore.outerHeight(false);
4267
4268 if (currentOffset + 50 >= loadingMoreOffset) {
4269 this.loadMore();
4270 }
4271 };
4272
4273 InfiniteScroll.prototype.loadMore = function () {
4274 this.loading = true;
4275
4276 var params = $.extend({}, {page: 1}, this.lastParams);
4277
4278 params.page++;
4279
4280 this.trigger('query:append', params);
4281 };
4282
4283 InfiniteScroll.prototype.showLoadingMore = function (_, data) {
4284 return data.pagination && data.pagination.more;
4285 };
4286
4287 InfiniteScroll.prototype.createLoadingMore = function () {
4288 var $option = $(
4289 '<li ' +
4290 'class="select2-results__option select2-results__option--load-more"' +
4291 'role="option" aria-disabled="true"></li>'
4292 );
4293
4294 var message = this.options.get('translations').get('loadingMore');
4295
4296 $option.html(message(this.lastParams));
4297
4298 return $option;
4299 };
4300
4301 return InfiniteScroll;
4302 });
4303
4304 S2.define('select2/dropdown/attachBody',[
4305 'jquery',
4306 '../utils'
4307 ], function ($, Utils) {
4308 function AttachBody (decorated, $element, options) {
4309 this.$dropdownParent = $(options.get('dropdownParent') || document.body);
4310
4311 decorated.call(this, $element, options);
4312 }
4313
4314 AttachBody.prototype.bind = function (decorated, container, $container) {
4315 var self = this;
4316
4317 decorated.call(this, container, $container);
4318
4319 container.on('open', function () {
4320 self._showDropdown();
4321 self._attachPositioningHandler(container);
4322
4323 // Must bind after the results handlers to ensure correct sizing
4324 self._bindContainerResultHandlers(container);
4325 });
4326
4327 container.on('close', function () {
4328 self._hideDropdown();
4329 self._detachPositioningHandler(container);
4330 });
4331
4332 this.$dropdownContainer.on('mousedown', function (evt) {
4333 evt.stopPropagation();
4334 });
4335 };
4336
4337 AttachBody.prototype.destroy = function (decorated) {
4338 decorated.call(this);
4339
4340 this.$dropdownContainer.remove();
4341 };
4342
4343 AttachBody.prototype.position = function (decorated, $dropdown, $container) {
4344 // Clone all of the container classes
4345 $dropdown.attr('class', $container.attr('class'));
4346
4347 $dropdown.removeClass('select2');
4348 $dropdown.addClass('select2-container--open');
4349
4350 $dropdown.css({
4351 position: 'absolute',
4352 top: -999999
4353 });
4354
4355 this.$container = $container;
4356 };
4357
4358 AttachBody.prototype.render = function (decorated) {
4359 var $container = $('<span></span>');
4360
4361 var $dropdown = decorated.call(this);
4362 $container.append($dropdown);
4363
4364 this.$dropdownContainer = $container;
4365
4366 return $container;
4367 };
4368
4369 AttachBody.prototype._hideDropdown = function (decorated) {
4370 this.$dropdownContainer.detach();
4371 };
4372
4373 AttachBody.prototype._bindContainerResultHandlers =
4374 function (decorated, container) {
4375
4376 // These should only be bound once
4377 if (this._containerResultsHandlersBound) {
4378 return;
4379 }
4380
4381 var self = this;
4382
4383 container.on('results:all', function () {
4384 self._positionDropdown();
4385 self._resizeDropdown();
4386 });
4387
4388 container.on('results:append', function () {
4389 self._positionDropdown();
4390 self._resizeDropdown();
4391 });
4392
4393 container.on('results:message', function () {
4394 self._positionDropdown();
4395 self._resizeDropdown();
4396 });
4397
4398 container.on('select', function () {
4399 self._positionDropdown();
4400 self._resizeDropdown();
4401 });
4402
4403 container.on('unselect', function () {
4404 self._positionDropdown();
4405 self._resizeDropdown();
4406 });
4407
4408 this._containerResultsHandlersBound = true;
4409 };
4410
4411 AttachBody.prototype._attachPositioningHandler =
4412 function (decorated, container) {
4413 var self = this;
4414
4415 var scrollEvent = 'scroll.select2.' + container.id;
4416 var resizeEvent = 'resize.select2.' + container.id;
4417 var orientationEvent = 'orientationchange.select2.' + container.id;
4418
4419 var $watchers = this.$container.parents().filter(Utils.hasScroll);
4420 $watchers.each(function () {
4421 Utils.StoreData(this, 'select2-scroll-position', {
4422 x: $(this).scrollLeft(),
4423 y: $(this).scrollTop()
4424 });
4425 });
4426
4427 $watchers.on(scrollEvent, function (ev) {
4428 var position = Utils.GetData(this, 'select2-scroll-position');
4429 $(this).scrollTop(position.y);
4430 });
4431
4432 $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent,
4433 function (e) {
4434 self._positionDropdown();
4435 self._resizeDropdown();
4436 });
4437 };
4438
4439 AttachBody.prototype._detachPositioningHandler =
4440 function (decorated, container) {
4441 var scrollEvent = 'scroll.select2.' + container.id;
4442 var resizeEvent = 'resize.select2.' + container.id;
4443 var orientationEvent = 'orientationchange.select2.' + container.id;
4444
4445 var $watchers = this.$container.parents().filter(Utils.hasScroll);
4446 $watchers.off(scrollEvent);
4447
4448 $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent);
4449 };
4450
4451 AttachBody.prototype._positionDropdown = function () {
4452 var $window = $(window);
4453
4454 var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above');
4455 var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below');
4456
4457 var newDirection = null;
4458
4459 var offset = this.$container.offset();
4460
4461 offset.bottom = offset.top + this.$container.outerHeight(false);
4462
4463 var container = {
4464 height: this.$container.outerHeight(false)
4465 };
4466
4467 container.top = offset.top;
4468 container.bottom = offset.top + container.height;
4469
4470 var dropdown = {
4471 height: this.$dropdown.outerHeight(false)
4472 };
4473
4474 var viewport = {
4475 top: $window.scrollTop(),
4476 bottom: $window.scrollTop() + $window.height()
4477 };
4478
4479 var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);
4480 var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);
4481
4482 var css = {
4483 left: offset.left,
4484 top: container.bottom
4485 };
4486
4487 // Determine what the parent element is to use for calculating the offset
4488 var $offsetParent = this.$dropdownParent;
4489
4490 // For statically positioned elements, we need to get the element
4491 // that is determining the offset
4492 if ($offsetParent.css('position') === 'static') {
4493 $offsetParent = $offsetParent.offsetParent();
4494 }
4495
4496 var parentOffset = {
4497 top: 0,
4498 left: 0
4499 };
4500
4501 if ($.contains(document.body, $offsetParent[0])) {
4502 parentOffset = $offsetParent.offset();
4503 }
4504
4505 css.top -= parentOffset.top;
4506 css.left -= parentOffset.left;
4507
4508 if (!isCurrentlyAbove && !isCurrentlyBelow) {
4509 newDirection = 'below';
4510 }
4511
4512 if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {
4513 newDirection = 'above';
4514 } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {
4515 newDirection = 'below';
4516 }
4517
4518 if (newDirection == 'above' ||
4519 (isCurrentlyAbove && newDirection !== 'below')) {
4520 css.top = container.top - parentOffset.top - dropdown.height;
4521 }
4522
4523 if (newDirection != null) {
4524 this.$dropdown
4525 .removeClass('select2-dropdown--below select2-dropdown--above')
4526 .addClass('select2-dropdown--' + newDirection);
4527 this.$container
4528 .removeClass('select2-container--below select2-container--above')
4529 .addClass('select2-container--' + newDirection);
4530 }
4531
4532 this.$dropdownContainer.css(css);
4533 };
4534
4535 AttachBody.prototype._resizeDropdown = function () {
4536 var css = {
4537 width: this.$container.outerWidth(false) + 'px'
4538 };
4539
4540 if (this.options.get('dropdownAutoWidth')) {
4541 css.minWidth = css.width;
4542 css.position = 'relative';
4543 css.width = 'auto';
4544 }
4545
4546 this.$dropdown.css(css);
4547 };
4548
4549 AttachBody.prototype._showDropdown = function (decorated) {
4550 this.$dropdownContainer.appendTo(this.$dropdownParent);
4551
4552 this._positionDropdown();
4553 this._resizeDropdown();
4554 };
4555
4556 return AttachBody;
4557 });
4558
4559 S2.define('select2/dropdown/minimumResultsForSearch',[
4560
4561 ], function () {
4562 function countResults (data) {
4563 var count = 0;
4564
4565 for (var d = 0; d < data.length; d++) {
4566 var item = data[d];
4567
4568 if (item.children) {
4569 count += countResults(item.children);
4570 } else {
4571 count++;
4572 }
4573 }
4574
4575 return count;
4576 }
4577
4578 function MinimumResultsForSearch (decorated, $element, options, dataAdapter) {
4579 this.minimumResultsForSearch = options.get('minimumResultsForSearch');
4580
4581 if (this.minimumResultsForSearch < 0) {
4582 this.minimumResultsForSearch = Infinity;
4583 }
4584
4585 decorated.call(this, $element, options, dataAdapter);
4586 }
4587
4588 MinimumResultsForSearch.prototype.showSearch = function (decorated, params) {
4589 if (countResults(params.data.results) < this.minimumResultsForSearch) {
4590 return false;
4591 }
4592
4593 return decorated.call(this, params);
4594 };
4595
4596 return MinimumResultsForSearch;
4597 });
4598
4599 S2.define('select2/dropdown/selectOnClose',[
4600 '../utils'
4601 ], function (Utils) {
4602 function SelectOnClose () { }
4603
4604 SelectOnClose.prototype.bind = function (decorated, container, $container) {
4605 var self = this;
4606
4607 decorated.call(this, container, $container);
4608
4609 container.on('close', function (params) {
4610 self._handleSelectOnClose(params);
4611 });
4612 };
4613
4614 SelectOnClose.prototype._handleSelectOnClose = function (_, params) {
4615 if (params && params.originalSelect2Event != null) {
4616 var event = params.originalSelect2Event;
4617
4618 // Don't select an item if the close event was triggered from a select or
4619 // unselect event
4620 if (event._type === 'select' || event._type === 'unselect') {
4621 return;
4622 }
4623 }
4624
4625 var $highlightedResults = this.getHighlightedResults();
4626
4627 // Only select highlighted results
4628 if ($highlightedResults.length < 1) {
4629 return;
4630 }
4631
4632 var data = Utils.GetData($highlightedResults[0], 'data');
4633
4634 // Don't re-select already selected resulte
4635 if (
4636 (data.element != null && data.element.selected) ||
4637 (data.element == null && data.selected)
4638 ) {
4639 return;
4640 }
4641
4642 this.trigger('select', {
4643 data: data
4644 });
4645 };
4646
4647 return SelectOnClose;
4648 });
4649
4650 S2.define('select2/dropdown/closeOnSelect',[
4651
4652 ], function () {
4653 function CloseOnSelect () { }
4654
4655 CloseOnSelect.prototype.bind = function (decorated, container, $container) {
4656 var self = this;
4657
4658 decorated.call(this, container, $container);
4659
4660 container.on('select', function (evt) {
4661 self._selectTriggered(evt);
4662 });
4663
4664 container.on('unselect', function (evt) {
4665 self._selectTriggered(evt);
4666 });
4667 };
4668
4669 CloseOnSelect.prototype._selectTriggered = function (_, evt) {
4670 var originalEvent = evt.originalEvent;
4671
4672 // Don't close if the control key is being held
4673 if (originalEvent && (originalEvent.ctrlKey || originalEvent.metaKey)) {
4674 return;
4675 }
4676
4677 this.trigger('close', {
4678 originalEvent: originalEvent,
4679 originalSelect2Event: evt
4680 });
4681 };
4682
4683 return CloseOnSelect;
4684 });
4685
4686 S2.define('select2/i18n/en',[],function () {
4687 // English
4688 return {
4689 errorLoading: function () {
4690 return 'The results could not be loaded.';
4691 },
4692 inputTooLong: function (args) {
4693 var overChars = args.input.length - args.maximum;
4694
4695 var message = 'Please delete ' + overChars + ' character';
4696
4697 if (overChars != 1) {
4698 message += 's';
4699 }
4700
4701 return message;
4702 },
4703 inputTooShort: function (args) {
4704 var remainingChars = args.minimum - args.input.length;
4705
4706 var message = 'Please enter ' + remainingChars + ' or more characters';
4707
4708 return message;
4709 },
4710 loadingMore: function () {
4711 return 'Loading more results…';
4712 },
4713 maximumSelected: function (args) {
4714 var message = 'You can only select ' + args.maximum + ' item';
4715
4716 if (args.maximum != 1) {
4717 message += 's';
4718 }
4719
4720 return message;
4721 },
4722 noResults: function () {
4723 return 'No results found';
4724 },
4725 searching: function () {
4726 return 'Searching…';
4727 },
4728 removeAllItems: function () {
4729 return 'Remove all items';
4730 }
4731 };
4732 });
4733
4734 S2.define('select2/defaults',[
4735 'jquery',
4736 'require',
4737
4738 './results',
4739
4740 './selection/single',
4741 './selection/multiple',
4742 './selection/placeholder',
4743 './selection/allowClear',
4744 './selection/search',
4745 './selection/eventRelay',
4746
4747 './utils',
4748 './translation',
4749 './diacritics',
4750
4751 './data/select',
4752 './data/array',
4753 './data/ajax',
4754 './data/tags',
4755 './data/tokenizer',
4756 './data/minimumInputLength',
4757 './data/maximumInputLength',
4758 './data/maximumSelectionLength',
4759
4760 './dropdown',
4761 './dropdown/search',
4762 './dropdown/hidePlaceholder',
4763 './dropdown/infiniteScroll',
4764 './dropdown/attachBody',
4765 './dropdown/minimumResultsForSearch',
4766 './dropdown/selectOnClose',
4767 './dropdown/closeOnSelect',
4768
4769 './i18n/en'
4770 ], function ($, require,
4771
4772 ResultsList,
4773
4774 SingleSelection, MultipleSelection, Placeholder, AllowClear,
4775 SelectionSearch, EventRelay,
4776
4777 Utils, Translation, DIACRITICS,
4778
4779 SelectData, ArrayData, AjaxData, Tags, Tokenizer,
4780 MinimumInputLength, MaximumInputLength, MaximumSelectionLength,
4781
4782 Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
4783 AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect,
4784
4785 EnglishTranslation) {
4786 function Defaults () {
4787 this.reset();
4788 }
4789
4790 Defaults.prototype.apply = function (options) {
4791 options = $.extend(true, {}, this.defaults, options);
4792
4793 if (options.dataAdapter == null) {
4794 if (options.ajax != null) {
4795 options.dataAdapter = AjaxData;
4796 } else if (options.data != null) {
4797 options.dataAdapter = ArrayData;
4798 } else {
4799 options.dataAdapter = SelectData;
4800 }
4801
4802 if (options.minimumInputLength > 0) {
4803 options.dataAdapter = Utils.Decorate(
4804 options.dataAdapter,
4805 MinimumInputLength
4806 );
4807 }
4808
4809 if (options.maximumInputLength > 0) {
4810 options.dataAdapter = Utils.Decorate(
4811 options.dataAdapter,
4812 MaximumInputLength
4813 );
4814 }
4815
4816 if (options.maximumSelectionLength > 0) {
4817 options.dataAdapter = Utils.Decorate(
4818 options.dataAdapter,
4819 MaximumSelectionLength
4820 );
4821 }
4822
4823 if (options.tags) {
4824 options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
4825 }
4826
4827 if (options.tokenSeparators != null || options.tokenizer != null) {
4828 options.dataAdapter = Utils.Decorate(
4829 options.dataAdapter,
4830 Tokenizer
4831 );
4832 }
4833
4834 if (options.query != null) {
4835 var Query = require(options.amdBase + 'compat/query');
4836
4837 options.dataAdapter = Utils.Decorate(
4838 options.dataAdapter,
4839 Query
4840 );
4841 }
4842
4843 if (options.initSelection != null) {
4844 var InitSelection = require(options.amdBase + 'compat/initSelection');
4845
4846 options.dataAdapter = Utils.Decorate(
4847 options.dataAdapter,
4848 InitSelection
4849 );
4850 }
4851 }
4852
4853 if (options.resultsAdapter == null) {
4854 options.resultsAdapter = ResultsList;
4855
4856 if (options.ajax != null) {
4857 options.resultsAdapter = Utils.Decorate(
4858 options.resultsAdapter,
4859 InfiniteScroll
4860 );
4861 }
4862
4863 if (options.placeholder != null) {
4864 options.resultsAdapter = Utils.Decorate(
4865 options.resultsAdapter,
4866 HidePlaceholder
4867 );
4868 }
4869
4870 if (options.selectOnClose) {
4871 options.resultsAdapter = Utils.Decorate(
4872 options.resultsAdapter,
4873 SelectOnClose
4874 );
4875 }
4876 }
4877
4878 if (options.dropdownAdapter == null) {
4879 if (options.multiple) {
4880 options.dropdownAdapter = Dropdown;
4881 } else {
4882 var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);
4883
4884 options.dropdownAdapter = SearchableDropdown;
4885 }
4886
4887 if (options.minimumResultsForSearch !== 0) {
4888 options.dropdownAdapter = Utils.Decorate(
4889 options.dropdownAdapter,
4890 MinimumResultsForSearch
4891 );
4892 }
4893
4894 if (options.closeOnSelect) {
4895 options.dropdownAdapter = Utils.Decorate(
4896 options.dropdownAdapter,
4897 CloseOnSelect
4898 );
4899 }
4900
4901 if (
4902 options.dropdownCssClass != null ||
4903 options.dropdownCss != null ||
4904 options.adaptDropdownCssClass != null
4905 ) {
4906 var DropdownCSS = require(options.amdBase + 'compat/dropdownCss');
4907
4908 options.dropdownAdapter = Utils.Decorate(
4909 options.dropdownAdapter,
4910 DropdownCSS
4911 );
4912 }
4913
4914 options.dropdownAdapter = Utils.Decorate(
4915 options.dropdownAdapter,
4916 AttachBody
4917 );
4918 }
4919
4920 if (options.selectionAdapter == null) {
4921 if (options.multiple) {
4922 options.selectionAdapter = MultipleSelection;
4923 } else {
4924 options.selectionAdapter = SingleSelection;
4925 }
4926
4927 // Add the placeholder mixin if a placeholder was specified
4928 if (options.placeholder != null) {
4929 options.selectionAdapter = Utils.Decorate(
4930 options.selectionAdapter,
4931 Placeholder
4932 );
4933 }
4934
4935 if (options.allowClear) {
4936 options.selectionAdapter = Utils.Decorate(
4937 options.selectionAdapter,
4938 AllowClear
4939 );
4940 }
4941
4942 if (options.multiple) {
4943 options.selectionAdapter = Utils.Decorate(
4944 options.selectionAdapter,
4945 SelectionSearch
4946 );
4947 }
4948
4949 if (
4950 options.containerCssClass != null ||
4951 options.containerCss != null ||
4952 options.adaptContainerCssClass != null
4953 ) {
4954 var ContainerCSS = require(options.amdBase + 'compat/containerCss');
4955
4956 options.selectionAdapter = Utils.Decorate(
4957 options.selectionAdapter,
4958 ContainerCSS
4959 );
4960 }
4961
4962 options.selectionAdapter = Utils.Decorate(
4963 options.selectionAdapter,
4964 EventRelay
4965 );
4966 }
4967
4968 // If the defaults were not previously applied from an element, it is
4969 // possible for the language option to have not been resolved
4970 options.language = this._resolveLanguage(options.language);
4971
4972 // Always fall back to English since it will always be complete
4973 options.language.push('en');
4974
4975 var uniqueLanguages = [];
4976
4977 for (var l = 0; l < options.language.length; l++) {
4978 var language = options.language[l];
4979
4980 if (uniqueLanguages.indexOf(language) === -1) {
4981 uniqueLanguages.push(language);
4982 }
4983 }
4984
4985 options.language = uniqueLanguages;
4986
4987 options.translations = this._processTranslations(
4988 options.language,
4989 options.debug
4990 );
4991
4992 return options;
4993 };
4994
4995 Defaults.prototype.reset = function () {
4996 function stripDiacritics (text) {
4997 // Used 'uni range + named function' from http://jsperf.com/diacritics/18
4998 function match(a) {
4999 return DIACRITICS[a] || a;
5000 }
5001
5002 return text.replace(/[^\u0000-\u007E]/g, match);
5003 }
5004
5005 function matcher (params, data) {
5006 // Always return the object if there is nothing to compare
5007 if ($.trim(params.term) === '') {
5008 return data;
5009 }
5010
5011 // Do a recursive check for options with children
5012 if (data.children && data.children.length > 0) {
5013 // Clone the data object if there are children
5014 // This is required as we modify the object to remove any non-matches
5015 var match = $.extend(true, {}, data);
5016
5017 // Check each child of the option
5018 for (var c = data.children.length - 1; c >= 0; c--) {
5019 var child = data.children[c];
5020
5021 var matches = matcher(params, child);
5022
5023 // If there wasn't a match, remove the object in the array
5024 if (matches == null) {
5025 match.children.splice(c, 1);
5026 }
5027 }
5028
5029 // If any children matched, return the new object
5030 if (match.children.length > 0) {
5031 return match;
5032 }
5033
5034 // If there were no matching children, check just the plain object
5035 return matcher(params, match);
5036 }
5037
5038 var original = stripDiacritics(data.text).toUpperCase();
5039 var term = stripDiacritics(params.term).toUpperCase();
5040
5041 // Check if the text contains the term
5042 if (original.indexOf(term) > -1) {
5043 return data;
5044 }
5045
5046 // If it doesn't contain the term, don't return anything
5047 return null;
5048 }
5049
5050 this.defaults = {
5051 amdBase: './',
5052 amdLanguageBase: './i18n/',
5053 closeOnSelect: true,
5054 debug: false,
5055 dropdownAutoWidth: false,
5056 escapeMarkup: Utils.escapeMarkup,
5057 language: {},
5058 matcher: matcher,
5059 minimumInputLength: 0,
5060 maximumInputLength: 0,
5061 maximumSelectionLength: 0,
5062 minimumResultsForSearch: 0,
5063 selectOnClose: false,
5064 scrollAfterSelect: false,
5065 sorter: function (data) {
5066 return data;
5067 },
5068 templateResult: function (result) {
5069 return result.text;
5070 },
5071 templateSelection: function (selection) {
5072 return selection.text;
5073 },
5074 theme: 'default',
5075 width: 'resolve'
5076 };
5077 };
5078
5079 Defaults.prototype.applyFromElement = function (options, $element) {
5080 var optionLanguage = options.language;
5081 var defaultLanguage = this.defaults.language;
5082 var elementLanguage = $element.prop('lang');
5083 var parentLanguage = $element.closest('[lang]').prop('lang');
5084
5085 var languages = Array.prototype.concat.call(
5086 this._resolveLanguage(elementLanguage),
5087 this._resolveLanguage(optionLanguage),
5088 this._resolveLanguage(defaultLanguage),
5089 this._resolveLanguage(parentLanguage)
5090 );
5091
5092 options.language = languages;
5093
5094 return options;
5095 };
5096
5097 Defaults.prototype._resolveLanguage = function (language) {
5098 if (!language) {
5099 return [];
5100 }
5101
5102 if ($.isEmptyObject(language)) {
5103 return [];
5104 }
5105
5106 if ($.isPlainObject(language)) {
5107 return [language];
5108 }
5109
5110 var languages;
5111
5112 if (!$.isArray(language)) {
5113 languages = [language];
5114 } else {
5115 languages = language;
5116 }
5117
5118 var resolvedLanguages = [];
5119
5120 for (var l = 0; l < languages.length; l++) {
5121 resolvedLanguages.push(languages[l]);
5122
5123 if (typeof languages[l] === 'string' && languages[l].indexOf('-') > 0) {
5124 // Extract the region information if it is included
5125 var languageParts = languages[l].split('-');
5126 var baseLanguage = languageParts[0];
5127
5128 resolvedLanguages.push(baseLanguage);
5129 }
5130 }
5131
5132 return resolvedLanguages;
5133 };
5134
5135 Defaults.prototype._processTranslations = function (languages, debug) {
5136 var translations = new Translation();
5137
5138 for (var l = 0; l < languages.length; l++) {
5139 var languageData = new Translation();
5140
5141 var language = languages[l];
5142
5143 if (typeof language === 'string') {
5144 try {
5145 // Try to load it with the original name
5146 languageData = Translation.loadPath(language);
5147 } catch (e) {
5148 try {
5149 // If we couldn't load it, check if it wasn't the full path
5150 language = this.defaults.amdLanguageBase + language;
5151 languageData = Translation.loadPath(language);
5152 } catch (ex) {
5153 // The translation could not be loaded at all. Sometimes this is
5154 // because of a configuration problem, other times this can be
5155 // because of how Select2 helps load all possible translation files
5156 if (debug && window.console && console.warn) {
5157 console.warn(
5158 'Select2: The language file for "' + language + '" could ' +
5159 'not be automatically loaded. A fallback will be used instead.'
5160 );
5161 }
5162 }
5163 }
5164 } else if ($.isPlainObject(language)) {
5165 languageData = new Translation(language);
5166 } else {
5167 languageData = language;
5168 }
5169
5170 translations.extend(languageData);
5171 }
5172
5173 return translations;
5174 };
5175
5176 Defaults.prototype.set = function (key, value) {
5177 var camelKey = $.camelCase(key);
5178
5179 var data = {};
5180 data[camelKey] = value;
5181
5182 var convertedData = Utils._convertData(data);
5183
5184 $.extend(true, this.defaults, convertedData);
5185 };
5186
5187 var defaults = new Defaults();
5188
5189 return defaults;
5190 });
5191
5192 S2.define('select2/options',[
5193 'require',
5194 'jquery',
5195 './defaults',
5196 './utils'
5197 ], function (require, $, Defaults, Utils) {
5198 function Options (options, $element) {
5199 this.options = options;
5200
5201 if ($element != null) {
5202 this.fromElement($element);
5203 }
5204
5205 if ($element != null) {
5206 this.options = Defaults.applyFromElement(this.options, $element);
5207 }
5208
5209 this.options = Defaults.apply(this.options);
5210
5211 if ($element && $element.is('input')) {
5212 var InputCompat = require(this.get('amdBase') + 'compat/inputData');
5213
5214 this.options.dataAdapter = Utils.Decorate(
5215 this.options.dataAdapter,
5216 InputCompat
5217 );
5218 }
5219 }
5220
5221 Options.prototype.fromElement = function ($e) {
5222 var excludedData = ['select2'];
5223
5224 if (this.options.multiple == null) {
5225 this.options.multiple = $e.prop('multiple');
5226 }
5227
5228 if (this.options.disabled == null) {
5229 this.options.disabled = $e.prop('disabled');
5230 }
5231
5232 if (this.options.dir == null) {
5233 if ($e.prop('dir')) {
5234 this.options.dir = $e.prop('dir');
5235 } else if ($e.closest('[dir]').prop('dir')) {
5236 this.options.dir = $e.closest('[dir]').prop('dir');
5237 } else {
5238 this.options.dir = 'ltr';
5239 }
5240 }
5241
5242 $e.prop('disabled', this.options.disabled);
5243 $e.prop('multiple', this.options.multiple);
5244
5245 if (Utils.GetData($e[0], 'select2Tags')) {
5246 if (this.options.debug && window.console && console.warn) {
5247 console.warn(
5248 'Select2: The `data-select2-tags` attribute has been changed to ' +
5249 'use the `data-data` and `data-tags="true"` attributes and will be ' +
5250 'removed in future versions of Select2.'
5251 );
5252 }
5253
5254 Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags'));
5255 Utils.StoreData($e[0], 'tags', true);
5256 }
5257
5258 if (Utils.GetData($e[0], 'ajaxUrl')) {
5259 if (this.options.debug && window.console && console.warn) {
5260 console.warn(
5261 'Select2: The `data-ajax-url` attribute has been changed to ' +
5262 '`data-ajax--url` and support for the old attribute will be removed' +
5263 ' in future versions of Select2.'
5264 );
5265 }
5266
5267 $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl'));
5268 Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl'));
5269 }
5270
5271 var dataset = {};
5272
5273 function upperCaseLetter(_, letter) {
5274 return letter.toUpperCase();
5275 }
5276
5277 // Pre-load all of the attributes which are prefixed with `data-`
5278 for (var attr = 0; attr < $e[0].attributes.length; attr++) {
5279 var attributeName = $e[0].attributes[attr].name;
5280 var prefix = 'data-';
5281
5282 if (attributeName.substr(0, prefix.length) == prefix) {
5283 // Get the contents of the attribute after `data-`
5284 var dataName = attributeName.substring(prefix.length);
5285
5286 // Get the data contents from the consistent source
5287 // This is more than likely the jQuery data helper
5288 var dataValue = Utils.GetData($e[0], dataName);
5289
5290 // camelCase the attribute name to match the spec
5291 var camelDataName = dataName.replace(/-([a-z])/g, upperCaseLetter);
5292
5293 // Store the data attribute contents into the dataset since
5294 dataset[camelDataName] = dataValue;
5295 }
5296 }
5297
5298 // Prefer the element's `dataset` attribute if it exists
5299 // jQuery 1.x does not correctly handle data attributes with multiple dashes
5300 if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {
5301 dataset = $.extend(true, {}, $e[0].dataset, dataset);
5302 }
5303
5304 // Prefer our internal data cache if it exists
5305 var data = $.extend(true, {}, Utils.GetData($e[0]), dataset);
5306
5307 data = Utils._convertData(data);
5308
5309 for (var key in data) {
5310 if ($.inArray(key, excludedData) > -1) {
5311 continue;
5312 }
5313
5314 if ($.isPlainObject(this.options[key])) {
5315 $.extend(this.options[key], data[key]);
5316 } else {
5317 this.options[key] = data[key];
5318 }
5319 }
5320
5321 return this;
5322 };
5323
5324 Options.prototype.get = function (key) {
5325 return this.options[key];
5326 };
5327
5328 Options.prototype.set = function (key, val) {
5329 this.options[key] = val;
5330 };
5331
5332 return Options;
5333 });
5334
5335 S2.define('select2/core',[
5336 'jquery',
5337 './options',
5338 './utils',
5339 './keys'
5340 ], function ($, Options, Utils, KEYS) {
5341 var Select2 = function ($element, options) {
5342 if (Utils.GetData($element[0], 'select2') != null) {
5343 Utils.GetData($element[0], 'select2').destroy();
5344 }
5345
5346 this.$element = $element;
5347
5348 this.id = this._generateId($element);
5349
5350 options = options || {};
5351
5352 this.options = new Options(options, $element);
5353
5354 Select2.__super__.constructor.call(this);
5355
5356 // Set up the tabindex
5357
5358 var tabindex = $element.attr('tabindex') || 0;
5359 Utils.StoreData($element[0], 'old-tabindex', tabindex);
5360 $element.attr('tabindex', '-1');
5361
5362 // Set up containers and adapters
5363
5364 var DataAdapter = this.options.get('dataAdapter');
5365 this.dataAdapter = new DataAdapter($element, this.options);
5366
5367 var $container = this.render();
5368
5369 this._placeContainer($container);
5370
5371 var SelectionAdapter = this.options.get('selectionAdapter');
5372 this.selection = new SelectionAdapter($element, this.options);
5373 this.$selection = this.selection.render();
5374
5375 this.selection.position(this.$selection, $container);
5376
5377 var DropdownAdapter = this.options.get('dropdownAdapter');
5378 this.dropdown = new DropdownAdapter($element, this.options);
5379 this.$dropdown = this.dropdown.render();
5380
5381 this.dropdown.position(this.$dropdown, $container);
5382
5383 var ResultsAdapter = this.options.get('resultsAdapter');
5384 this.results = new ResultsAdapter($element, this.options, this.dataAdapter);
5385 this.$results = this.results.render();
5386
5387 this.results.position(this.$results, this.$dropdown);
5388
5389 // Bind events
5390
5391 var self = this;
5392
5393 // Bind the container to all of the adapters
5394 this._bindAdapters();
5395
5396 // Register any DOM event handlers
5397 this._registerDomEvents();
5398
5399 // Register any internal event handlers
5400 this._registerDataEvents();
5401 this._registerSelectionEvents();
5402 this._registerDropdownEvents();
5403 this._registerResultsEvents();
5404 this._registerEvents();
5405
5406 // Set the initial state
5407 this.dataAdapter.current(function (initialData) {
5408 self.trigger('selection:update', {
5409 data: initialData
5410 });
5411 });
5412
5413 // Hide the original select
5414 $element.addClass('select2-hidden-accessible');
5415 $element.attr('aria-hidden', 'true');
5416
5417 // Synchronize any monitored attributes
5418 this._syncAttributes();
5419
5420 Utils.StoreData($element[0], 'select2', this);
5421
5422 // Ensure backwards compatibility with $element.data('select2').
5423 $element.data('select2', this);
5424 };
5425
5426 Utils.Extend(Select2, Utils.Observable);
5427
5428 Select2.prototype._generateId = function ($element) {
5429 var id = '';
5430
5431 if ($element.attr('id') != null) {
5432 id = $element.attr('id');
5433 } else if ($element.attr('name') != null) {
5434 id = $element.attr('name') + '-' + Utils.generateChars(2);
5435 } else {
5436 id = Utils.generateChars(4);
5437 }
5438
5439 id = id.replace(/(:|\.|\[|\]|,)/g, '');
5440 id = 'select2-' + id;
5441
5442 return id;
5443 };
5444
5445 Select2.prototype._placeContainer = function ($container) {
5446 $container.insertAfter(this.$element);
5447
5448 var width = this._resolveWidth(this.$element, this.options.get('width'));
5449
5450 if (width != null) {
5451 $container.css('width', width);
5452 }
5453 };
5454
5455 Select2.prototype._resolveWidth = function ($element, method) {
5456 var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;
5457
5458 if (method == 'resolve') {
5459 var styleWidth = this._resolveWidth($element, 'style');
5460
5461 if (styleWidth != null) {
5462 return styleWidth;
5463 }
5464
5465 return this._resolveWidth($element, 'element');
5466 }
5467
5468 if (method == 'element') {
5469 var elementWidth = $element.outerWidth(false);
5470
5471 if (elementWidth <= 0) {
5472 return 'auto';
5473 }
5474
5475 return elementWidth + 'px';
5476 }
5477
5478 if (method == 'style') {
5479 var style = $element.attr('style');
5480
5481 if (typeof(style) !== 'string') {
5482 return null;
5483 }
5484
5485 var attrs = style.split(';');
5486
5487 for (var i = 0, l = attrs.length; i < l; i = i + 1) {
5488 var attr = attrs[i].replace(/\s/g, '');
5489 var matches = attr.match(WIDTH);
5490
5491 if (matches !== null && matches.length >= 1) {
5492 return matches[1];
5493 }
5494 }
5495
5496 return null;
5497 }
5498
5499 if (method == 'computedstyle') {
5500 var computedStyle = window.getComputedStyle($element[0]);
5501
5502 return computedStyle.width;
5503 }
5504
5505 return method;
5506 };
5507
5508 Select2.prototype._bindAdapters = function () {
5509 this.dataAdapter.bind(this, this.$container);
5510 this.selection.bind(this, this.$container);
5511
5512 this.dropdown.bind(this, this.$container);
5513 this.results.bind(this, this.$container);
5514 };
5515
5516 Select2.prototype._registerDomEvents = function () {
5517 var self = this;
5518
5519 this.$element.on('change.select2', function () {
5520 self.dataAdapter.current(function (data) {
5521 self.trigger('selection:update', {
5522 data: data
5523 });
5524 });
5525 });
5526
5527 this.$element.on('focus.select2', function (evt) {
5528 self.trigger('focus', evt);
5529 });
5530
5531 this._syncA = Utils.bind(this._syncAttributes, this);
5532 this._syncS = Utils.bind(this._syncSubtree, this);
5533
5534 if (this.$element[0].attachEvent) {
5535 this.$element[0].attachEvent('onpropertychange', this._syncA);
5536 }
5537
5538 var observer = window.MutationObserver ||
5539 window.WebKitMutationObserver ||
5540 window.MozMutationObserver
5541 ;
5542
5543 if (observer != null) {
5544 this._observer = new observer(function (mutations) {
5545 $.each(mutations, self._syncA);
5546 $.each(mutations, self._syncS);
5547 });
5548 this._observer.observe(this.$element[0], {
5549 attributes: true,
5550 childList: true,
5551 subtree: false
5552 });
5553 } else if (this.$element[0].addEventListener) {
5554 this.$element[0].addEventListener(
5555 'DOMAttrModified',
5556 self._syncA,
5557 false
5558 );
5559 this.$element[0].addEventListener(
5560 'DOMNodeInserted',
5561 self._syncS,
5562 false
5563 );
5564 this.$element[0].addEventListener(
5565 'DOMNodeRemoved',
5566 self._syncS,
5567 false
5568 );
5569 }
5570 };
5571
5572 Select2.prototype._registerDataEvents = function () {
5573 var self = this;
5574
5575 this.dataAdapter.on('*', function (name, params) {
5576 self.trigger(name, params);
5577 });
5578 };
5579
5580 Select2.prototype._registerSelectionEvents = function () {
5581 var self = this;
5582 var nonRelayEvents = ['toggle', 'focus'];
5583
5584 this.selection.on('toggle', function () {
5585 self.toggleDropdown();
5586 });
5587
5588 this.selection.on('focus', function (params) {
5589 self.focus(params);
5590 });
5591
5592 this.selection.on('*', function (name, params) {
5593 if ($.inArray(name, nonRelayEvents) !== -1) {
5594 return;
5595 }
5596
5597 self.trigger(name, params);
5598 });
5599 };
5600
5601 Select2.prototype._registerDropdownEvents = function () {
5602 var self = this;
5603
5604 this.dropdown.on('*', function (name, params) {
5605 self.trigger(name, params);
5606 });
5607 };
5608
5609 Select2.prototype._registerResultsEvents = function () {
5610 var self = this;
5611
5612 this.results.on('*', function (name, params) {
5613 self.trigger(name, params);
5614 });
5615 };
5616
5617 Select2.prototype._registerEvents = function () {
5618 var self = this;
5619
5620 this.on('open', function () {
5621 self.$container.addClass('select2-container--open');
5622 });
5623
5624 this.on('close', function () {
5625 self.$container.removeClass('select2-container--open');
5626 });
5627
5628 this.on('enable', function () {
5629 self.$container.removeClass('select2-container--disabled');
5630 });
5631
5632 this.on('disable', function () {
5633 self.$container.addClass('select2-container--disabled');
5634 });
5635
5636 this.on('blur', function () {
5637 self.$container.removeClass('select2-container--focus');
5638 });
5639
5640 this.on('query', function (params) {
5641 if (!self.isOpen()) {
5642 self.trigger('open', {});
5643 }
5644
5645 this.dataAdapter.query(params, function (data) {
5646 self.trigger('results:all', {
5647 data: data,
5648 query: params
5649 });
5650 });
5651 });
5652
5653 this.on('query:append', function (params) {
5654 this.dataAdapter.query(params, function (data) {
5655 self.trigger('results:append', {
5656 data: data,
5657 query: params
5658 });
5659 });
5660 });
5661
5662 this.on('keypress', function (evt) {
5663 var key = evt.which;
5664
5665 if (self.isOpen()) {
5666 if (key === KEYS.ESC || key === KEYS.TAB ||
5667 (key === KEYS.UP && evt.altKey)) {
5668 self.close();
5669
5670 evt.preventDefault();
5671 } else if (key === KEYS.ENTER) {
5672 self.trigger('results:select', {});
5673
5674 evt.preventDefault();
5675 } else if ((key === KEYS.SPACE && evt.ctrlKey)) {
5676 self.trigger('results:toggle', {});
5677
5678 evt.preventDefault();
5679 } else if (key === KEYS.UP) {
5680 self.trigger('results:previous', {});
5681
5682 evt.preventDefault();
5683 } else if (key === KEYS.DOWN) {
5684 self.trigger('results:next', {});
5685
5686 evt.preventDefault();
5687 }
5688 } else {
5689 if (key === KEYS.ENTER || key === KEYS.SPACE ||
5690 (key === KEYS.DOWN && evt.altKey)) {
5691 self.open();
5692
5693 evt.preventDefault();
5694 }
5695 }
5696 });
5697 };
5698
5699 Select2.prototype._syncAttributes = function () {
5700 this.options.set('disabled', this.$element.prop('disabled'));
5701
5702 if (this.options.get('disabled')) {
5703 if (this.isOpen()) {
5704 this.close();
5705 }
5706
5707 this.trigger('disable', {});
5708 } else {
5709 this.trigger('enable', {});
5710 }
5711 };
5712
5713 Select2.prototype._syncSubtree = function (evt, mutations) {
5714 var changed = false;
5715 var self = this;
5716
5717 // Ignore any mutation events raised for elements that aren't options or
5718 // optgroups. This handles the case when the select element is destroyed
5719 if (
5720 evt && evt.target && (
5721 evt.target.nodeName !== 'OPTION' && evt.target.nodeName !== 'OPTGROUP'
5722 )
5723 ) {
5724 return;
5725 }
5726
5727 if (!mutations) {
5728 // If mutation events aren't supported, then we can only assume that the
5729 // change affected the selections
5730 changed = true;
5731 } else if (mutations.addedNodes && mutations.addedNodes.length > 0) {
5732 for (var n = 0; n < mutations.addedNodes.length; n++) {
5733 var node = mutations.addedNodes[n];
5734
5735 if (node.selected) {
5736 changed = true;
5737 }
5738 }
5739 } else if (mutations.removedNodes && mutations.removedNodes.length > 0) {
5740 changed = true;
5741 }
5742
5743 // Only re-pull the data if we think there is a change
5744 if (changed) {
5745 this.dataAdapter.current(function (currentData) {
5746 self.trigger('selection:update', {
5747 data: currentData
5748 });
5749 });
5750 }
5751 };
5752
5753 /**
5754 * Override the trigger method to automatically trigger pre-events when
5755 * there are events that can be prevented.
5756 */
5757 Select2.prototype.trigger = function (name, args) {
5758 var actualTrigger = Select2.__super__.trigger;
5759 var preTriggerMap = {
5760 'open': 'opening',
5761 'close': 'closing',
5762 'select': 'selecting',
5763 'unselect': 'unselecting',
5764 'clear': 'clearing'
5765 };
5766
5767 if (args === undefined) {
5768 args = {};
5769 }
5770
5771 if (name in preTriggerMap) {
5772 var preTriggerName = preTriggerMap[name];
5773 var preTriggerArgs = {
5774 prevented: false,
5775 name: name,
5776 args: args
5777 };
5778
5779 actualTrigger.call(this, preTriggerName, preTriggerArgs);
5780
5781 if (preTriggerArgs.prevented) {
5782 args.prevented = true;
5783
5784 return;
5785 }
5786 }
5787
5788 actualTrigger.call(this, name, args);
5789 };
5790
5791 Select2.prototype.toggleDropdown = function () {
5792 if (this.options.get('disabled')) {
5793 return;
5794 }
5795
5796 if (this.isOpen()) {
5797 this.close();
5798 } else {
5799 this.open();
5800 }
5801 };
5802
5803 Select2.prototype.open = function () {
5804 if (this.isOpen()) {
5805 return;
5806 }
5807
5808 this.trigger('query', {});
5809 };
5810
5811 Select2.prototype.close = function () {
5812 if (!this.isOpen()) {
5813 return;
5814 }
5815
5816 this.trigger('close', {});
5817 };
5818
5819 Select2.prototype.isOpen = function () {
5820 return this.$container.hasClass('select2-container--open');
5821 };
5822
5823 Select2.prototype.hasFocus = function () {
5824 return this.$container.hasClass('select2-container--focus');
5825 };
5826
5827 Select2.prototype.focus = function (data) {
5828 // No need to re-trigger focus events if we are already focused
5829 if (this.hasFocus()) {
5830 return;
5831 }
5832
5833 this.$container.addClass('select2-container--focus');
5834 this.trigger('focus', {});
5835 };
5836
5837 Select2.prototype.enable = function (args) {
5838 if (this.options.get('debug') && window.console && console.warn) {
5839 console.warn(
5840 'Select2: The `select2("enable")` method has been deprecated and will' +
5841 ' be removed in later Select2 versions. Use $element.prop("disabled")' +
5842 ' instead.'
5843 );
5844 }
5845
5846 if (args == null || args.length === 0) {
5847 args = [true];
5848 }
5849
5850 var disabled = !args[0];
5851
5852 this.$element.prop('disabled', disabled);
5853 };
5854
5855 Select2.prototype.data = function () {
5856 if (this.options.get('debug') &&
5857 arguments.length > 0 && window.console && console.warn) {
5858 console.warn(
5859 'Select2: Data can no longer be set using `select2("data")`. You ' +
5860 'should consider setting the value instead using `$element.val()`.'
5861 );
5862 }
5863
5864 var data = [];
5865
5866 this.dataAdapter.current(function (currentData) {
5867 data = currentData;
5868 });
5869
5870 return data;
5871 };
5872
5873 Select2.prototype.val = function (args) {
5874 if (this.options.get('debug') && window.console && console.warn) {
5875 console.warn(
5876 'Select2: The `select2("val")` method has been deprecated and will be' +
5877 ' removed in later Select2 versions. Use $element.val() instead.'
5878 );
5879 }
5880
5881 if (args == null || args.length === 0) {
5882 return this.$element.val();
5883 }
5884
5885 var newVal = args[0];
5886
5887 if ($.isArray(newVal)) {
5888 newVal = $.map(newVal, function (obj) {
5889 return obj.toString();
5890 });
5891 }
5892
5893 this.$element.val(newVal).trigger('change');
5894 };
5895
5896 Select2.prototype.destroy = function () {
5897 this.$container.remove();
5898
5899 if (this.$element[0].detachEvent) {
5900 this.$element[0].detachEvent('onpropertychange', this._syncA);
5901 }
5902
5903 if (this._observer != null) {
5904 this._observer.disconnect();
5905 this._observer = null;
5906 } else if (this.$element[0].removeEventListener) {
5907 this.$element[0]
5908 .removeEventListener('DOMAttrModified', this._syncA, false);
5909 this.$element[0]
5910 .removeEventListener('DOMNodeInserted', this._syncS, false);
5911 this.$element[0]
5912 .removeEventListener('DOMNodeRemoved', this._syncS, false);
5913 }
5914
5915 this._syncA = null;
5916 this._syncS = null;
5917
5918 this.$element.off('.select2');
5919 this.$element.attr('tabindex',
5920 Utils.GetData(this.$element[0], 'old-tabindex'));
5921
5922 this.$element.removeClass('select2-hidden-accessible');
5923 this.$element.attr('aria-hidden', 'false');
5924 Utils.RemoveData(this.$element[0]);
5925 this.$element.removeData('select2');
5926
5927 this.dataAdapter.destroy();
5928 this.selection.destroy();
5929 this.dropdown.destroy();
5930 this.results.destroy();
5931
5932 this.dataAdapter = null;
5933 this.selection = null;
5934 this.dropdown = null;
5935 this.results = null;
5936 };
5937
5938 Select2.prototype.render = function () {
5939 var $container = $(
5940 '<span class="select2 select2-container">' +
5941 '<span class="selection"></span>' +
5942 '<span class="dropdown-wrapper" aria-hidden="true"></span>' +
5943 '</span>'
5944 );
5945
5946 $container.attr('dir', this.options.get('dir'));
5947
5948 this.$container = $container;
5949
5950 this.$container.addClass('select2-container--' + this.options.get('theme'));
5951
5952 Utils.StoreData($container[0], 'element', this.$element);
5953
5954 return $container;
5955 };
5956
5957 return Select2;
5958 });
5959
5960 S2.define('jquery-mousewheel',[
5961 'jquery'
5962 ], function ($) {
5963 // Used to shim jQuery.mousewheel for non-full builds.
5964 return $;
5965 });
5966
5967 S2.define('jquery.select2',[
5968 'jquery',
5969 'jquery-mousewheel',
5970
5971 './select2/core',
5972 './select2/defaults',
5973 './select2/utils'
5974 ], function ($, _, Select2, Defaults, Utils) {
5975 if ($.fn.select2 == null) {
5976 // All methods that should return the element
5977 var thisMethods = ['open', 'close', 'destroy'];
5978
5979 $.fn.select2 = function (options) {
5980 options = options || {};
5981
5982 if (typeof options === 'object') {
5983 this.each(function () {
5984 var instanceOptions = $.extend(true, {}, options);
5985
5986 var instance = new Select2($(this), instanceOptions);
5987 });
5988
5989 return this;
5990 } else if (typeof options === 'string') {
5991 var ret;
5992 var args = Array.prototype.slice.call(arguments, 1);
5993
5994 this.each(function () {
5995 var instance = Utils.GetData(this, 'select2');
5996
5997 if (instance == null && window.console && console.error) {
5998 console.error(
5999 'The select2(\'' + options + '\') method was called on an ' +
6000 'element that is not using Select2.'
6001 );
6002 }
6003
6004 ret = instance[options].apply(instance, args);
6005 });
6006
6007 // Check if we should be returning `this`
6008 if ($.inArray(options, thisMethods) > -1) {
6009 return this;
6010 }
6011
6012 return ret;
6013 } else {
6014 throw new Error('Invalid arguments for Select2: ' + options);
6015 }
6016 };
6017 }
6018
6019 if ($.fn.select2.defaults == null) {
6020 $.fn.select2.defaults = Defaults;
6021 }
6022
6023 return Select2;
6024 });
6025
6026 // Return the AMD loader configuration so it can be used outside of this file
6027 return {
6028 define: S2.define,
6029 require: S2.require
6030 };
6031 }());
6032
6033 // Autoload the jQuery bindings
6034 // We know that all of the modules exist above this, so we're safe
6035 var select2 = S2.require('jquery.select2');
6036
6037 // Hold the AMD module references on the jQuery function that was just loaded
6038 // This allows Select2 to use the internal loader outside of this file, such
6039 // as in the language files.
6040 jQuery.fn.select2.amd = S2;
6041
6042 // Return the Select2 instance for anyone who is importing it.
6043 return select2;
6044 }));
6045