PluginProbe
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI / 7.9.8
GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI v7.9.8
8.0.4 8.0.3 8.0.1 8.0.2 8.0.0 7.9.9.7 7.9.9.6 7.9.9.5 7.9.9.4 7.9.9.3 7.9.9.2 7.9.9.1 7.9.9 7.9.8 7.9.7 7.9.6 7.9.5 7.9.4 7.9.3 7.9.2 7.9.1 7.9.0 7.8.9 7.8.8 7.8.7 All 46 releases
gamipress / assets / js / gamipress-select2.js

gamipress-select2.js in GamiPress – Gamification plugin to reward points, badges & ranks in WordPress, now with AI 7.9.8, at assets/js/gamipress-select2.js

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