FossilRepo

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

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button