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