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