PluginProbe
CBX Map for Google Map & OpenStreetMap / 1.1.11
CBX Map for Google Map & OpenStreetMap v1.1.11
trunk 1.1.10 1.1.11 1.1.12 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5
cbxgooglemap / assets / select2 / js / select2.full.js

select2.full.js in CBX Map for Google Map & OpenStreetMap 1.1.11, at assets/select2/js/select2.full.js

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