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