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