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