PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.6.8
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.6.8
1.8.12.3 1.8.12.2 1.8.12.1 1.8.12 1.8.11.3 1.8.11.2 1.8.11.1 1.8.11 1.6.6 1.6.60 1.6.7 1.6.8 1.6.9 1.7.0 1.7.0.1 1.7.0.11 1.7.0.12 1.7.0.14 1.7.0.2 1.7.0.3 1.7.0.5 1.7.0.6 1.7.0.7 1.7.0.9 1.8.0 All 210 releases
charitable / assets / js / libraries / select2.js

select2.js in Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) 1.6.8, at assets/js/libraries/select2.js

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