PluginProbe
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder / 51.1.83
King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder v51.1.83
51.1.83 51.1.82 51.1.81 51.1.79 51.1.78 51.1.77 51.1.76 51.1.74 51.1.75 51.1.65 51.1.64 51.1.63 trunk 51.1.14 51.1.2 51.1.35 51.1.36 51.1.37 51.1.38 51.1.39 51.1.44 51.1.45 51.1.46 51.1.47 51.1.49 All 37 releases
king-addons / includes / extensions / Header_Footer_Builder / select2.js

select2.js in King Addons for Elementor – 80+ Elementor Widgets, 4 000+ Elementor Templates, WooCommerce, Mega Menu, Popup Builder 51.1.83, at includes/extensions/Header_Footer_Builder/select2.js

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