| /*! |
| * Select2 4.0.6-rc.1 |
| * https://select2.github.io |
| * |
| * Released under the MIT license |
| * https://github.com/select2/select2/blob/master/LICENSE.md |
| */ |
| ;(function (factory) { |
| if (typeof define === 'function' && define.amd) { |
| // AMD. Register as an anonymous module. |
| define(['jquery'], factory); |
| } else if (typeof module === 'object' && module.exports) { |
| // Node/CommonJS |
| module.exports = function (root, jQuery) { |
| if (jQuery === undefined) { |
| // require('jQuery') returns a factory that requires window to |
| // build a jQuery instance, we normalize how we use modules |
| // that require this pattern but the window provided is a noop |
| // if it's defined (how jquery works) |
| if (typeof window !== 'undefined') { |
| jQuery = require('jquery'); |
| } |
| else { |
| jQuery = require('jquery')(root); |
| } |
| } |
| factory(jQuery); |
| return jQuery; |
| }; |
| } else { |
| // Browser globals |
| factory(jQuery); |
| } |
| } (function (jQuery) { |
| // This is needed so we can catch the AMD loader configuration and use it |
| // The inner file should be wrapped (by `banner.start.js`) in a function that |
| // returns the AMD loader references. |
| var S2 =(function () { |
| // Restore the Select2 AMD loader so it can be used |
| // Needed mostly in the language files, where the loader is not inserted |
| if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) { |
| var S2 = jQuery.fn.select2.amd; |
| } |
| var S2;(function () { if (!S2 || !S2.requirejs) { |
| if (!S2) { S2 = {}; } else { require = S2; } |
| /** |
| * @license almond 0.3.3 Copyright jQuery Foundation and other contributors. |
| * Released under MIT license, http://github.com/requirejs/almond/LICENSE |
| */ |
| //Going sloppy to avoid 'use strict' string cost, but strict practices should |
| //be followed. |
| /*global setTimeout: false */ |
| |
| var requirejs, require, define; |
| (function (undef) { |
| var main, req, makeMap, handlers, |
| defined = {}, |
| waiting = {}, |
| config = {}, |
| defining = {}, |
| hasOwn = Object.prototype.hasOwnProperty, |
| aps = [].slice, |
| jsSuffixRegExp = /\.js$/; |
| |
| function hasProp(obj, prop) { |
| return hasOwn.call(obj, prop); |
| } |
| |
| /** |
| * Given a relative module name, like ./something, normalize it to |
| * a real name that can be mapped to a path. |
| * @param {String} name the relative name |
| * @param {String} baseName a real name that the name arg is relative |
| * to. |
| * @returns {String} normalized name |
| */ |
| function normalize(name, baseName) { |
| var nameParts, nameSegment, mapValue, foundMap, lastIndex, |
| foundI, foundStarMap, starI, i, j, part, normalizedBaseParts, |
| baseParts = baseName && baseName.split("/"), |
| map = config.map, |
| starMap = (map && map['*']) || {}; |
| |
| //Adjust any relative paths. |
| if (name) { |
| name = name.split('/'); |
| lastIndex = name.length - 1; |
| |
| // If wanting node ID compatibility, strip .js from end |
| // of IDs. Have to do this here, and not in nameToUrl |
| // because node allows either .js or non .js to map |
| // to same file. |
| if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) { |
| name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, ''); |
| } |
| |
| // Starts with a '.' so need the baseName |
| if (name[0].charAt(0) === '.' && baseParts) { |
| //Convert baseName to array, and lop off the last part, |
| //so that . matches that 'directory' and not name of the baseName's |
| //module. For instance, baseName of 'one/two/three', maps to |
| //'one/two/three.js', but we want the directory, 'one/two' for |
| //this normalization. |
| normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); |
| name = normalizedBaseParts.concat(name); |
| } |
| |
| //start trimDots |
| for (i = 0; i < name.length; i++) { |
| part = name[i]; |
| if (part === '.') { |
| name.splice(i, 1); |
| i -= 1; |
| } else if (part === '..') { |
| // If at the start, or previous value is still .., |
| // keep them so that when converted to a path it may |
| // still work when converted to a path, even though |
| // as an ID it is less than ideal. In larger point |
| // releases, may be better to just kick out an error. |
| if (i === 0 || (i === 1 && name[2] === '..') || name[i - 1] === '..') { |
| continue; |
| } else if (i > 0) { |
| name.splice(i - 1, 2); |
| i -= 2; |
| } |
| } |
| } |
| //end trimDots |
| |
| name = name.join('/'); |
| } |
| |
| //Apply map config if available. |
| if ((baseParts || starMap) && map) { |
| nameParts = name.split('/'); |
| |
| for (i = nameParts.length; i > 0; i -= 1) { |
| nameSegment = nameParts.slice(0, i).join("/"); |
| |
| if (baseParts) { |
| //Find the longest baseName segment match in the config. |
| //So, do joins on the biggest to smallest lengths of baseParts. |
| for (j = baseParts.length; j > 0; j -= 1) { |
| mapValue = map[baseParts.slice(0, j).join('/')]; |
| |
| //baseName segment has config, find if it has one for |
| //this name. |
| if (mapValue) { |
| mapValue = mapValue[nameSegment]; |
| if (mapValue) { |
| //Match, update name to the new value. |
| foundMap = mapValue; |
| foundI = i; |
| break; |
| } |
| } |
| } |
| } |
| |
| if (foundMap) { |
| break; |
| } |
| |
| //Check for a star map match, but just hold on to it, |
| //if there is a shorter segment match later in a matching |
| //config, then favor over this star map. |
| if (!foundStarMap && starMap && starMap[nameSegment]) { |
| foundStarMap = starMap[nameSegment]; |
| starI = i; |
| } |
| } |
| |
| if (!foundMap && foundStarMap) { |
| foundMap = foundStarMap; |
| foundI = starI; |
| } |
| |
| if (foundMap) { |
| nameParts.splice(0, foundI, foundMap); |
| name = nameParts.join('/'); |
| } |
| } |
| |
| return name; |
| } |
| |
| function makeRequire(relName, forceSync) { |
| return function () { |
| //A version of a require function that passes a moduleName |
| //value for items that may need to |
| //look up paths relative to the moduleName |
| var args = aps.call(arguments, 0); |
| |
| //If first arg is not require('string'), and there is only |
| //one arg, it is the array form without a callback. Insert |
| //a null so that the following concat is correct. |
| if (typeof args[0] !== 'string' && args.length === 1) { |
| args.push(null); |
| } |
| return req.apply(undef, args.concat([relName, forceSync])); |
| }; |
| } |
| |
| function makeNormalize(relName) { |
| return function (name) { |
| return normalize(name, relName); |
| }; |
| } |
| |
| function makeLoad(depName) { |
| return function (value) { |
| defined[depName] = value; |
| }; |
| } |
| |
| function callDep(name) { |
| if (hasProp(waiting, name)) { |
| var args = waiting[name]; |
| delete waiting[name]; |
| defining[name] = true; |
| main.apply(undef, args); |
| } |
| |
| if (!hasProp(defined, name) && !hasProp(defining, name)) { |
| throw new Error('No ' + name); |
| } |
| return defined[name]; |
| } |
| |
| //Turns a plugin!resource to [plugin, resource] |
| //with the plugin being undefined if the name |
| //did not have a plugin prefix. |
| function splitPrefix(name) { |
| var prefix, |
| index = name ? name.indexOf('!') : -1; |
| if (index > -1) { |
| prefix = name.substring(0, index); |
| name = name.substring(index + 1, name.length); |
| } |
| return [prefix, name]; |
| } |
| |
| //Creates a parts array for a relName where first part is plugin ID, |
| //second part is resource ID. Assumes relName has already been normalized. |
| function makeRelParts(relName) { |
| return relName ? splitPrefix(relName) : []; |
| } |
| |
| /** |
| * Makes a name map, normalizing the name, and using a plugin |
| * for normalization if necessary. Grabs a ref to plugin |
| * too, as an optimization. |
| */ |
| makeMap = function (name, relParts) { |
| var plugin, |
| parts = splitPrefix(name), |
| prefix = parts[0], |
| relResourceName = relParts[1]; |
| |
| name = parts[1]; |
| |
| if (prefix) { |
| prefix = normalize(prefix, relResourceName); |
| plugin = callDep(prefix); |
| } |
| |
| //Normalize according |
| if (prefix) { |
| if (plugin && plugin.normalize) { |
| name = plugin.normalize(name, makeNormalize(relResourceName)); |
| } else { |
| name = normalize(name, relResourceName); |
| } |
| } else { |
| name = normalize(name, relResourceName); |
| parts = splitPrefix(name); |
| prefix = parts[0]; |
| name = parts[1]; |
| if (prefix) { |
| plugin = callDep(prefix); |
| } |
| } |
| |
| //Using ridiculous property names for space reasons |
| return { |
| f: prefix ? prefix + '!' + name : name, //fullName |
| n: name, |
| pr: prefix, |
| p: plugin |
| }; |
| }; |
| |
| function makeConfig(name) { |
| return function () { |
| return (config && config.config && config.config[name]) || {}; |
| }; |
| } |
| |
| handlers = { |
| require: function (name) { |
| return makeRequire(name); |
| }, |
| exports: function (name) { |
| var e = defined[name]; |
| if (typeof e !== 'undefined') { |
| return e; |
| } else { |
| return (defined[name] = {}); |
| } |
| }, |
| module: function (name) { |
| return { |
| id: name, |
| uri: '', |
| exports: defined[name], |
| config: makeConfig(name) |
| }; |
| } |
| }; |
| |
| main = function (name, deps, callback, relName) { |
| var cjsModule, depName, ret, map, i, relParts, |
| args = [], |
| callbackType = typeof callback, |
| usingExports; |
| |
| //Use name if no relName |
| relName = relName || name; |
| relParts = makeRelParts(relName); |
| |
| //Call the callback to define the module, if necessary. |
| if (callbackType === 'undefined' || callbackType === 'function') { |
| //Pull out the defined dependencies and pass the ordered |
| //values to the callback. |
| //Default to [require, exports, module] if no deps |
| deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps; |
| for (i = 0; i < deps.length; i += 1) { |
| map = makeMap(deps[i], relParts); |
| depName = map.f; |
| |
| //Fast path CommonJS standard dependencies. |
| if (depName === "require") { |
| args[i] = handlers.require(name); |
| } else if (depName === "exports") { |
| //CommonJS module spec 1.1 |
| args[i] = handlers.exports(name); |
| usingExports = true; |
| } else if (depName === "module") { |
| //CommonJS module spec 1.1 |
| cjsModule = args[i] = handlers.module(name); |
| } else if (hasProp(defined, depName) || |
| hasProp(waiting, depName) || |
| hasProp(defining, depName)) { |
| args[i] = callDep(depName); |
| } else if (map.p) { |
| map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {}); |
| args[i] = defined[depName]; |
| } else { |
| throw new Error(name + ' missing ' + depName); |
| } |
| } |
| |
| ret = callback ? callback.apply(defined[name], args) : undefined; |
| |
| if (name) { |
| //If setting exports via "module" is in play, |
| //favor that over return value and exports. After that, |
| //favor a non-undefined return value over exports use. |
| if (cjsModule && cjsModule.exports !== undef && |
| cjsModule.exports !== defined[name]) { |
| defined[name] = cjsModule.exports; |
| } else if (ret !== undef || !usingExports) { |
| //Use the return value from the function. |
| defined[name] = ret; |
| } |
| } |
| } else if (name) { |
| //May just be an object definition for the module. Only |
| //worry about defining if have a module name. |
| defined[name] = callback; |
| } |
| }; |
| |
| requirejs = require = req = function (deps, callback, relName, forceSync, alt) { |
| if (typeof deps === "string") { |
| if (handlers[deps]) { |
| //callback in this case is really relName |
| return handlers[deps](callback); |
| } |
| //Just return the module wanted. In this scenario, the |
| //deps arg is the module name, and second arg (if passed) |
| //is just the relName. |
| //Normalize module name, if it contains . or .. |
| return callDep(makeMap(deps, makeRelParts(callback)).f); |
| } else if (!deps.splice) { |
| //deps is a config object, not an array. |
| config = deps; |
| if (config.deps) { |
| req(config.deps, config.callback); |
| } |
| if (!callback) { |
| return; |
| } |
| |
| if (callback.splice) { |
| //callback is an array, which means it is a dependency list. |
| //Adjust args if there are dependencies |
| deps = callback; |
| callback = relName; |
| relName = null; |
| } else { |
| deps = undef; |
| } |
| } |
| |
| //Support require(['a']) |
| callback = callback || function () {}; |
| |
| //If relName is a function, it is an errback handler, |
| //so remove it. |
| if (typeof relName === 'function') { |
| relName = forceSync; |
| forceSync = alt; |
| } |
| |
| //Simulate async callback; |
| if (forceSync) { |
| main(undef, deps, callback, relName); |
| } else { |
| //Using a non-zero value because of concern for what old browsers |
| //do, and latest browsers "upgrade" to 4 if lower value is used: |
| //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout: |
| //If want a value immediately, use require('id') instead -- something |
| //that works in almond on the global level, but not guaranteed and |
| //unlikely to work in other AMD implementations. |
| setTimeout(function () { |
| main(undef, deps, callback, relName); |
| }, 4); |
| } |
| |
| return req; |
| }; |
| |
| /** |
| * Just drops the config on the floor, but returns req in case |
| * the config return value is used. |
| */ |
| req.config = function (cfg) { |
| return req(cfg); |
| }; |
| |
| /** |
| * Expose module registry for debugging and tooling |
| */ |
| requirejs._defined = defined; |
| |
| define = function (name, deps, callback) { |
| if (typeof name !== 'string') { |
| throw new Error('See almond README: incorrect module build, no module name'); |
| } |
| |
| //This module may not have dependencies |
| if (!deps.splice) { |
| //deps is not an array, so probably means |
| //an object literal or factory function for |
| //the value. Adjust args. |
| callback = deps; |
| deps = []; |
| } |
| |
| if (!hasProp(defined, name) && !hasProp(waiting, name)) { |
| waiting[name] = [name, deps, callback]; |
| } |
| }; |
| |
| define.amd = { |
| jQuery: true |
| }; |
| }()); |
| |
| S2.requirejs = requirejs;S2.require = require;S2.define = define; |
| } |
| }()); |
| S2.define("almond", function(){}); |
| |
| /* global jQuery:false, $:false */ |
| S2.define('jquery',[],function () { |
| var _$ = jQuery || $; |
| |
| if (_$ == null && console && console.error) { |
| console.error( |
| 'Select2: An instance of jQuery or a jQuery-compatible library was not ' + |
| 'found. Make sure that you are including jQuery before Select2 on your ' + |
| 'web page.' |
| ); |
| } |
| |
| return _$; |
| }); |
| |
| S2.define('select2/utils',[ |
| 'jquery' |
| ], function ($) { |
| var Utils = {}; |
| |
| Utils.Extend = function (ChildClass, SuperClass) { |
| var __hasProp = {}.hasOwnProperty; |
| |
| function BaseConstructor () { |
| this.constructor = ChildClass; |
| } |
| |
| for (var key in SuperClass) { |
| if (__hasProp.call(SuperClass, key)) { |
| ChildClass[key] = SuperClass[key]; |
| } |
| } |
| |
| BaseConstructor.prototype = SuperClass.prototype; |
| ChildClass.prototype = new BaseConstructor(); |
| ChildClass.__super__ = SuperClass.prototype; |
| |
| return ChildClass; |
| }; |
| |
| function getMethods (theClass) { |
| var proto = theClass.prototype; |
| |
| var methods = []; |
| |
| for (var methodName in proto) { |
| var m = proto[methodName]; |
| |
| if (typeof m !== 'function') { |
| continue; |
| } |
| |
| if (methodName === 'constructor') { |
| continue; |
| } |
| |
| methods.push(methodName); |
| } |
| |
| return methods; |
| } |
| |
| Utils.Decorate = function (SuperClass, DecoratorClass) { |
| var decoratedMethods = getMethods(DecoratorClass); |
| var superMethods = getMethods(SuperClass); |
| |
| function DecoratedClass () { |
| var unshift = Array.prototype.unshift; |
| |
| var argCount = DecoratorClass.prototype.constructor.length; |
| |
| var calledConstructor = SuperClass.prototype.constructor; |
| |
| if (argCount > 0) { |
| unshift.call(arguments, SuperClass.prototype.constructor); |
| |
| calledConstructor = DecoratorClass.prototype.constructor; |
| } |
| |
| calledConstructor.apply(this, arguments); |
| } |
| |
| DecoratorClass.displayName = SuperClass.displayName; |
| |
| function ctr () { |
| this.constructor = DecoratedClass; |
| } |
| |
| DecoratedClass.prototype = new ctr(); |
| |
| for (var m = 0; m < superMethods.length; m++) { |
| var superMethod = superMethods[m]; |
| |
| DecoratedClass.prototype[superMethod] = |
| SuperClass.prototype[superMethod]; |
| } |
| |
| var calledMethod = function (methodName) { |
| // Stub out the original method if it's not decorating an actual method |
| var originalMethod = function () {}; |
| |
| if (methodName in DecoratedClass.prototype) { |
| originalMethod = DecoratedClass.prototype[methodName]; |
| } |
| |
| var decoratedMethod = DecoratorClass.prototype[methodName]; |
| |
| return function () { |
| var unshift = Array.prototype.unshift; |
| |
| unshift.call(arguments, originalMethod); |
| |
| return decoratedMethod.apply(this, arguments); |
| }; |
| }; |
| |
| for (var d = 0; d < decoratedMethods.length; d++) { |
| var decoratedMethod = decoratedMethods[d]; |
| |
| DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod); |
| } |
| |
| return DecoratedClass; |
| }; |
| |
| var Observable = function () { |
| this.listeners = {}; |
| }; |
| |
| Observable.prototype.on = function (event, callback) { |
| this.listeners = this.listeners || {}; |
| |
| if (event in this.listeners) { |
| this.listeners[event].push(callback); |
| } else { |
| this.listeners[event] = [callback]; |
| } |
| }; |
| |
| Observable.prototype.trigger = function (event) { |
| var slice = Array.prototype.slice; |
| var params = slice.call(arguments, 1); |
| |
| this.listeners = this.listeners || {}; |
| |
| // Params should always come in as an array |
| if (params == null) { |
| params = []; |
| } |
| |
| // If there are no arguments to the event, use a temporary object |
| if (params.length === 0) { |
| params.push({}); |
| } |
| |
| // Set the `_type` of the first object to the event |
| params[0]._type = event; |
| |
| if (event in this.listeners) { |
| this.invoke(this.listeners[event], slice.call(arguments, 1)); |
| } |
| |
| if ('*' in this.listeners) { |
| this.invoke(this.listeners['*'], arguments); |
| } |
| }; |
| |
| Observable.prototype.invoke = function (listeners, params) { |
| for (var i = 0, len = listeners.length; i < len; i++) { |
| listeners[i].apply(this, params); |
| } |
| }; |
| |
| Utils.Observable = Observable; |
| |
| Utils.generateChars = function (length) { |
| var chars = ''; |
| |
| for (var i = 0; i < length; i++) { |
| var randomChar = Math.floor(Math.random() * 36); |
| chars += randomChar.toString(36); |
| } |
| |
| return chars; |
| }; |
| |
| Utils.bind = function (func, context) { |
| return function () { |
| func.apply(context, arguments); |
| }; |
| }; |
| |
| Utils._convertData = function (data) { |
| for (var originalKey in data) { |
| var keys = originalKey.split('-'); |
| |
| var dataLevel = data; |
| |
| if (keys.length === 1) { |
| continue; |
| } |
| |
| for (var k = 0; k < keys.length; k++) { |
| var key = keys[k]; |
| |
| // Lowercase the first letter |
| // By default, dash-separated becomes camelCase |
| key = key.substring(0, 1).toLowerCase() + key.substring(1); |
| |
| if (!(key in dataLevel)) { |
| dataLevel[key] = {}; |
| } |
| |
| if (k == keys.length - 1) { |
| dataLevel[key] = data[originalKey]; |
| } |
| |
| dataLevel = dataLevel[key]; |
| } |
| |
| delete data[originalKey]; |
| } |
| |
| return data; |
| }; |
| |
| Utils.hasScroll = function (index, el) { |
| // Adapted from the function created by @ShadowScripter |
| // and adapted by @BillBarry on the Stack Exchange Code Review website. |
| // The original code can be found at |
| // http://codereview.stackexchange.com/q/13338 |
| // and was designed to be used with the Sizzle selector engine. |
| |
| var $el = $(el); |
| var overflowX = el.style.overflowX; |
| var overflowY = el.style.overflowY; |
| |
| //Check both x and y declarations |
| if (overflowX === overflowY && |
| (overflowY === 'hidden' || overflowY === 'visible')) { |
| return false; |
| } |
| |
| if (overflowX === 'scroll' || overflowY === 'scroll') { |
| return true; |
| } |
| |
| return ($el.innerHeight() < el.scrollHeight || |
| $el.innerWidth() < el.scrollWidth); |
| }; |
| |
| Utils.escapeMarkup = function (markup) { |
| var replaceMap = { |
| '\\': '\', |
| '&': '&', |
| '<': '<', |
| '>': '>', |
| '"': '"', |
| '\'': ''', |
| '/': '/' |
| }; |
| |
| // Do not try to escape the markup if it's not a string |
| if (typeof markup !== 'string') { |
| return markup; |
| } |
| |
| return String(markup).replace(/[&<>"'\/\\]/g, function (match) { |
| return replaceMap[match]; |
| }); |
| }; |
| |
| // Append an array of jQuery nodes to a given element. |
| Utils.appendMany = function ($element, $nodes) { |
| // jQuery 1.7.x does not support $.fn.append() with an array |
| // Fall back to a jQuery object collection using $.fn.add() |
| if ($.fn.jquery.substr(0, 3) === '1.7') { |
| var $jqNodes = $(); |
| |
| $.map($nodes, function (node) { |
| $jqNodes = $jqNodes.add(node); |
| }); |
| |
| $nodes = $jqNodes; |
| } |
| |
| $element.append($nodes); |
| }; |
| |
| // Cache objects in Utils.__cache instead of $.data (see #4346) |
| Utils.__cache = {}; |
| |
| var id = 0; |
| Utils.GetUniqueElementId = function (element) { |
| // Get a unique element Id. If element has no id, |
| // creates a new unique number, stores it in the id |
| // attribute and returns the new id. |
| // If an id already exists, it simply returns it. |
| |
| var select2Id = element.getAttribute('data-select2-id'); |
| if (select2Id == null) { |
| // If element has id, use it. |
| if (element.id) { |
| select2Id = element.id; |
| element.setAttribute('data-select2-id', select2Id); |
| } else { |
| element.setAttribute('data-select2-id', ++id); |
| select2Id = id.toString(); |
| } |
| } |
| return select2Id; |
| }; |
| |
| Utils.StoreData = function (element, name, value) { |
| // Stores an item in the cache for a specified element. |
| // name is the cache key. |
| var id = Utils.GetUniqueElementId(element); |
| if (!Utils.__cache[id]) { |
| Utils.__cache[id] = {}; |
| } |
| |
| Utils.__cache[id][name] = value; |
| }; |
| |
| Utils.GetData = function (element, name) { |
| // Retrieves a value from the cache by its key (name) |
| // name is optional. If no name specified, return |
| // all cache items for the specified element. |
| // and for a specified element. |
| var id = Utils.GetUniqueElementId(element); |
| if (name) { |
| if (Utils.__cache[id]) { |
| return Utils.__cache[id][name] != null ? |
| Utils.__cache[id][name]: |
| $(element).data(name); // Fallback to HTML5 data attribs. |
| } |
| return $(element).data(name); // Fallback to HTML5 data attribs. |
| } else { |
| return Utils.__cache[id]; |
| } |
| }; |
| |
| Utils.RemoveData = function (element) { |
| // Removes all cached items for a specified element. |
| var id = Utils.GetUniqueElementId(element); |
| if (Utils.__cache[id] != null) { |
| delete Utils.__cache[id]; |
| } |
| }; |
| |
| return Utils; |
| }); |
| |
| S2.define('select2/results',[ |
| 'jquery', |
| './utils' |
| ], function ($, Utils) { |
| function Results ($element, options, dataAdapter) { |
| this.$element = $element; |
| this.data = dataAdapter; |
| this.options = options; |
| |
| Results.__super__.constructor.call(this); |
| } |
| |
| Utils.Extend(Results, Utils.Observable); |
| |
| Results.prototype.render = function () { |
| var $results = $( |
| '<ul class="select2-results__options" role="tree"></ul>' |
| ); |
| |
| if (this.options.get('multiple')) { |
| $results.attr('aria-multiselectable', 'true'); |
| } |
| |
| this.$results = $results; |
| |
| return $results; |
| }; |
| |
| Results.prototype.clear = function () { |
| this.$results.empty(); |
| }; |
| |
| Results.prototype.displayMessage = function (params) { |
| var escapeMarkup = this.options.get('escapeMarkup'); |
| |
| this.clear(); |
| this.hideLoading(); |
| |
| var $message = $( |
| '<li role="treeitem" aria-live="assertive"' + |
| ' class="select2-results__option"></li>' |
| ); |
| |
| var message = this.options.get('translations').get(params.message); |
| |
| $message.append( |
| escapeMarkup( |
| message(params.args) |
| ) |
| ); |
| |
| $message[0].className += ' select2-results__message'; |
| |
| this.$results.append($message); |
| }; |
| |
| Results.prototype.hideMessages = function () { |
| this.$results.find('.select2-results__message').remove(); |
| }; |
| |
| Results.prototype.append = function (data) { |
| this.hideLoading(); |
| |
| var $options = []; |
| |
| if (data.results == null || data.results.length === 0) { |
| if (this.$results.children().length === 0) { |
| this.trigger('results:message', { |
| message: 'noResults' |
| }); |
| } |
| |
| return; |
| } |
| |
| data.results = this.sort(data.results); |
| |
| for (var d = 0; d < data.results.length; d++) { |
| var item = data.results[d]; |
| |
| var $option = this.option(item); |
| |
| $options.push($option); |
| } |
| |
| this.$results.append($options); |
| }; |
| |
| Results.prototype.position = function ($results, $dropdown) { |
| var $resultsContainer = $dropdown.find('.select2-results'); |
| $resultsContainer.append($results); |
| }; |
| |
| Results.prototype.sort = function (data) { |
| var sorter = this.options.get('sorter'); |
| |
| return sorter(data); |
| }; |
| |
| Results.prototype.highlightFirstItem = function () { |
| var $options = this.$results |
| .find('.select2-results__option[aria-selected]'); |
| |
| var $selected = $options.filter('[aria-selected=true]'); |
| |
| // Check if there are any selected options |
| if ($selected.length > 0) { |
| // If there are selected options, highlight the first |
| $selected.first().trigger('mouseenter'); |
| } else { |
| // If there are no selected options, highlight the first option |
| // in the dropdown |
| $options.first().trigger('mouseenter'); |
| } |
| |
| this.ensureHighlightVisible(); |
| }; |
| |
| Results.prototype.setClasses = function () { |
| var self = this; |
| |
| this.data.current(function (selected) { |
| var selectedIds = $.map(selected, function (s) { |
| return s.id.toString(); |
| }); |
| |
| var $options = self.$results |
| .find('.select2-results__option[aria-selected]'); |
| |
| $options.each(function () { |
| var $option = $(this); |
| |
| var item = Utils.GetData(this, 'data'); |
| |
| // id needs to be converted to a string when comparing |
| var id = '' + item.id; |
| |
| if ((item.element != null && item.element.selected) || |
| (item.element == null && $.inArray(id, selectedIds) > -1)) { |
| $option.attr('aria-selected', 'true'); |
| } else { |
| $option.attr('aria-selected', 'false'); |
| } |
| }); |
| |
| }); |
| }; |
| |
| Results.prototype.showLoading = function (params) { |
| this.hideLoading(); |
| |
| var loadingMore = this.options.get('translations').get('searching'); |
| |
| var loading = { |
| disabled: true, |
| loading: true, |
| text: loadingMore(params) |
| }; |
| var $loading = this.option(loading); |
| $loading.className += ' loading-results'; |
| |
| this.$results.prepend($loading); |
| }; |
| |
| Results.prototype.hideLoading = function () { |
| this.$results.find('.loading-results').remove(); |
| }; |
| |
| Results.prototype.option = function (data) { |
| var option = document.createElement('li'); |
| option.className = 'select2-results__option'; |
| |
| var attrs = { |
| 'role': 'treeitem', |
| 'aria-selected': 'false' |
| }; |
| |
| if (data.disabled) { |
| delete attrs['aria-selected']; |
| attrs['aria-disabled'] = 'true'; |
| } |
| |
| if (data.id == null) { |
| delete attrs['aria-selected']; |
| } |
| |
| if (data._resultId != null) { |
| option.id = data._resultId; |
| } |
| |
| if (data.title) { |
| option.title = data.title; |
| } |
| |
| if (data.children) { |
| attrs.role = 'group'; |
| attrs['aria-label'] = data.text; |
| delete attrs['aria-selected']; |
| } |
| |
| for (var attr in attrs) { |
| var val = attrs[attr]; |
| |
| option.setAttribute(attr, val); |
| } |
| |
| if (data.children) { |
| var $option = $(option); |
| |
| var label = document.createElement('strong'); |
| label.className = 'select2-results__group'; |
| |
| var $label = $(label); |
| this.template(data, label); |
| |
| var $children = []; |
| |
| for (var c = 0; c < data.children.length; c++) { |
| var child = data.children[c]; |
| |
| var $child = this.option(child); |
| |
| $children.push($child); |
| } |
| |
| var $childrenContainer = $('<ul></ul>', { |
| 'class': 'select2-results__options select2-results__options--nested' |
| }); |
| |
| $childrenContainer.append($children); |
| |
| $option.append(label); |
| $option.append($childrenContainer); |
| } else { |
| this.template(data, option); |
| } |
| |
| Utils.StoreData(option, 'data', data); |
| |
| return option; |
| }; |
| |
| Results.prototype.bind = function (container, $container) { |
| var self = this; |
| |
| var id = container.id + '-results'; |
| |
| this.$results.attr('id', id); |
| |
| container.on('results:all', function (params) { |
| self.clear(); |
| self.append(params.data); |
| |
| if (container.isOpen()) { |
| self.setClasses(); |
| self.highlightFirstItem(); |
| } |
| }); |
| |
| container.on('results:append', function (params) { |
| self.append(params.data); |
| |
| if (container.isOpen()) { |
| self.setClasses(); |
| } |
| }); |
| |
| container.on('query', function (params) { |
| self.hideMessages(); |
| self.showLoading(params); |
| }); |
| |
| container.on('select', function () { |
| if (!container.isOpen()) { |
| return; |
| } |
| |
| self.setClasses(); |
| self.highlightFirstItem(); |
| }); |
| |
| container.on('unselect', function () { |
| if (!container.isOpen()) { |
| return; |
| } |
| |
| self.setClasses(); |
| self.highlightFirstItem(); |
| }); |
| |
| container.on('open', function () { |
| // When the dropdown is open, aria-expended="true" |
| self.$results.attr('aria-expanded', 'true'); |
| self.$results.attr('aria-hidden', 'false'); |
| |
| self.setClasses(); |
| self.ensureHighlightVisible(); |
| }); |
| |
| container.on('close', function () { |
| // When the dropdown is closed, aria-expended="false" |
| self.$results.attr('aria-expanded', 'false'); |
| self.$results.attr('aria-hidden', 'true'); |
| self.$results.removeAttr('aria-activedescendant'); |
| }); |
| |
| container.on('results:toggle', function () { |
| var $highlighted = self.getHighlightedResults(); |
| |
| if ($highlighted.length === 0) { |
| return; |
| } |
| |
| $highlighted.trigger('mouseup'); |
| }); |
| |
| container.on('results:select', function () { |
| var $highlighted = self.getHighlightedResults(); |
| |
| if ($highlighted.length === 0) { |
| return; |
| } |
| |
| var data = Utils.GetData($highlighted[0], 'data'); |
| |
| if ($highlighted.attr('aria-selected') == 'true') { |
| self.trigger('close', {}); |
| } else { |
| self.trigger('select', { |
| data: data |
| }); |
| } |
| }); |
| |
| container.on('results:previous', function () { |
| var $highlighted = self.getHighlightedResults(); |
| |
| var $options = self.$results.find('[aria-selected]'); |
| |
| var currentIndex = $options.index($highlighted); |
| |
| // If we are already at te top, don't move further |
| // If no options, currentIndex will be -1 |
| if (currentIndex <= 0) { |
| return; |
| } |
| |
| var nextIndex = currentIndex - 1; |
| |
| // If none are highlighted, highlight the first |
| if ($highlighted.length === 0) { |
| nextIndex = 0; |
| } |
| |
| var $next = $options.eq(nextIndex); |
| |
| $next.trigger('mouseenter'); |
| |
| var currentOffset = self.$results.offset().top; |
| var nextTop = $next.offset().top; |
| var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset); |
| |
| if (nextIndex === 0) { |
| self.$results.scrollTop(0); |
| } else if (nextTop - currentOffset < 0) { |
| self.$results.scrollTop(nextOffset); |
| } |
| }); |
| |
| container.on('results:next', function () { |
| var $highlighted = self.getHighlightedResults(); |
| |
| var $options = self.$results.find('[aria-selected]'); |
| |
| var currentIndex = $options.index($highlighted); |
| |
| var nextIndex = currentIndex + 1; |
| |
| // If we are at the last option, stay there |
| if (nextIndex >= $options.length) { |
| return; |
| } |
| |
| var $next = $options.eq(nextIndex); |
| |
| $next.trigger('mouseenter'); |
| |
| var currentOffset = self.$results.offset().top + |
| self.$results.outerHeight(false); |
| var nextBottom = $next.offset().top + $next.outerHeight(false); |
| var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset; |
| |
| if (nextIndex === 0) { |
| self.$results.scrollTop(0); |
| } else if (nextBottom > currentOffset) { |
| self.$results.scrollTop(nextOffset); |
| } |
| }); |
| |
| container.on('results:focus', function (params) { |
| params.element.addClass('select2-results__option--highlighted'); |
| }); |
| |
| container.on('results:message', function (params) { |
| self.displayMessage(params); |
| }); |
| |
| if ($.fn.mousewheel) { |
| this.$results.on('mousewheel', function (e) { |
| var top = self.$results.scrollTop(); |
| |
| var bottom = self.$results.get(0).scrollHeight - top + e.deltaY; |
| |
| var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0; |
| var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height(); |
| |
| if (isAtTop) { |
| self.$results.scrollTop(0); |
| |
| e.preventDefault(); |
| e.stopPropagation(); |
| } else if (isAtBottom) { |
| self.$results.scrollTop( |
| self.$results.get(0).scrollHeight - self.$results.height() |
| ); |
| |
| e.preventDefault(); |
| e.stopPropagation(); |
| } |
| }); |
| } |
| |
| this.$results.on('mouseup', '.select2-results__option[aria-selected]', |
| function (evt) { |
| var $this = $(this); |
| |
| var data = Utils.GetData(this, 'data'); |
| |
| if ($this.attr('aria-selected') === 'true') { |
| if (self.options.get('multiple')) { |
| self.trigger('unselect', { |
| originalEvent: evt, |
| data: data |
| }); |
| } else { |
| self.trigger('close', {}); |
| } |
| |
| return; |
| } |
| |
| self.trigger('select', { |
| originalEvent: evt, |
| data: data |
| }); |
| }); |
| |
| this.$results.on('mouseenter', '.select2-results__option[aria-selected]', |
| function (evt) { |
| var data = Utils.GetData(this, 'data'); |
| |
| self.getHighlightedResults() |
| .removeClass('select2-results__option--highlighted'); |
| |
| self.trigger('results:focus', { |
| data: data, |
| element: $(this) |
| }); |
| }); |
| }; |
| |
| Results.prototype.getHighlightedResults = function () { |
| var $highlighted = this.$results |
| .find('.select2-results__option--highlighted'); |
| |
| return $highlighted; |
| }; |
| |
| Results.prototype.destroy = function () { |
| this.$results.remove(); |
| }; |
| |
| Results.prototype.ensureHighlightVisible = function () { |
| var $highlighted = this.getHighlightedResults(); |
| |
| if ($highlighted.length === 0) { |
| return; |
| } |
| |
| var $options = this.$results.find('[aria-selected]'); |
| |
| var currentIndex = $options.index($highlighted); |
| |
| var currentOffset = this.$results.offset().top; |
| var nextTop = $highlighted.offset().top; |
| var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset); |
| |
| var offsetDelta = nextTop - currentOffset; |
| nextOffset -= $highlighted.outerHeight(false) * 2; |
| |
| if (currentIndex <= 2) { |
| this.$results.scrollTop(0); |
| } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) { |
| this.$results.scrollTop(nextOffset); |
| } |
| }; |
| |
| Results.prototype.template = function (result, container) { |
| var template = this.options.get('templateResult'); |
| var escapeMarkup = this.options.get('escapeMarkup'); |
| |
| var content = template(result, container); |
| |
| if (content == null) { |
| container.style.display = 'none'; |
| } else if (typeof content === 'string') { |
| container.innerHTML = escapeMarkup(content); |
| } else { |
| $(container).append(content); |
| } |
| }; |
| |
| return Results; |
| }); |
| |
| S2.define('select2/keys',[ |
| |
| ], function () { |
| var KEYS = { |
| BACKSPACE: 8, |
| TAB: 9, |
| ENTER: 13, |
| SHIFT: 16, |
| CTRL: 17, |
| ALT: 18, |
| ESC: 27, |
| SPACE: 32, |
| PAGE_UP: 33, |
| PAGE_DOWN: 34, |
| END: 35, |
| HOME: 36, |
| LEFT: 37, |
| UP: 38, |
| RIGHT: 39, |
| DOWN: 40, |
| DELETE: 46 |
| }; |
| |
| return KEYS; |
| }); |
| |
| S2.define('select2/selection/base',[ |
| 'jquery', |
| '../utils', |
| '../keys' |
| ], function ($, Utils, KEYS) { |
| function BaseSelection ($element, options) { |
| this.$element = $element; |
| this.options = options; |
| |
| BaseSelection.__super__.constructor.call(this); |
| } |
| |
| Utils.Extend(BaseSelection, Utils.Observable); |
| |
| BaseSelection.prototype.render = function () { |
| var $selection = $( |
| '<span class="select2-selection" role="combobox" ' + |
| ' aria-haspopup="true" aria-expanded="false">' + |
| '</span>' |
| ); |
| |
| this._tabindex = 0; |
| |
| if (Utils.GetData(this.$element[0], 'old-tabindex') != null) { |
| this._tabindex = Utils.GetData(this.$element[0], 'old-tabindex'); |
| } else if (this.$element.attr('tabindex') != null) { |
| this._tabindex = this.$element.attr('tabindex'); |
| } |
| |
| $selection.attr('title', this.$element.attr('title')); |
| $selection.attr('tabindex', this._tabindex); |
| |
| this.$selection = $selection; |
| |
| return $selection; |
| }; |
| |
| BaseSelection.prototype.bind = function (container, $container) { |
| var self = this; |
| |
| var id = container.id + '-container'; |
| var resultsId = container.id + '-results'; |
| |
| this.container = container; |
| |
| this.$selection.on('focus', function (evt) { |
| self.trigger('focus', evt); |
| }); |
| |
| this.$selection.on('blur', function (evt) { |
| self._handleBlur(evt); |
| }); |
| |
| this.$selection.on('keydown', function (evt) { |
| self.trigger('keypress', evt); |
| |
| if (evt.which === KEYS.SPACE) { |
| evt.preventDefault(); |
| } |
| }); |
| |
| container.on('results:focus', function (params) { |
| self.$selection.attr('aria-activedescendant', params.data._resultId); |
| }); |
| |
| container.on('selection:update', function (params) { |
| self.update(params.data); |
| }); |
| |
| container.on('open', function () { |
| // When the dropdown is open, aria-expanded="true" |
| self.$selection.attr('aria-expanded', 'true'); |
| self.$selection.attr('aria-owns', resultsId); |
| |
| self._attachCloseHandler(container); |
| }); |
| |
| container.on('close', function () { |
| // When the dropdown is closed, aria-expanded="false" |
| self.$selection.attr('aria-expanded', 'false'); |
| self.$selection.removeAttr('aria-activedescendant'); |
| self.$selection.removeAttr('aria-owns'); |
| |
| self.$selection.focus(); |
| window.setTimeout(function () { |
| self.$selection.focus(); |
| }, 0); |
| |
| self._detachCloseHandler(container); |
| }); |
| |
| container.on('enable', function () { |
| self.$selection.attr('tabindex', self._tabindex); |
| }); |
| |
| container.on('disable', function () { |
| self.$selection.attr('tabindex', '-1'); |
| }); |
| }; |
| |
| BaseSelection.prototype._handleBlur = function (evt) { |
| var self = this; |
| |
| // This needs to be delayed as the active element is the body when the tab |
| // key is pressed, possibly along with others. |
| window.setTimeout(function () { |
| // Don't trigger `blur` if the focus is still in the selection |
| if ( |
| (document.activeElement == self.$selection[0]) || |
| ($.contains(self.$selection[0], document.activeElement)) |
| ) { |
| return; |
| } |
| |
| self.trigger('blur', evt); |
| }, 1); |
| }; |
| |
| BaseSelection.prototype._attachCloseHandler = function (container) { |
| var self = this; |
| |
| $(document.body).on('mousedown.select2.' + container.id, function (e) { |
| var $target = $(e.target); |
| |
| var $select = $target.closest('.select2'); |
| |
| var $all = $('.select2.select2-container--open'); |
| |
| $all.each(function () { |
| var $this = $(this); |
| |
| if (this == $select[0]) { |
| return; |
| } |
| |
| var $element = Utils.GetData(this, 'element'); |
| |
| $element.select2('close'); |
| }); |
| }); |
| }; |
| |
| BaseSelection.prototype._detachCloseHandler = function (container) { |
| $(document.body).off('mousedown.select2.' + container.id); |
| }; |
| |
| BaseSelection.prototype.position = function ($selection, $container) { |
| var $selectionContainer = $container.find('.selection'); |
| $selectionContainer.append($selection); |
| }; |
| |
| BaseSelection.prototype.destroy = function () { |
| this._detachCloseHandler(this.container); |
| }; |
| |
| BaseSelection.prototype.update = function (data) { |
| throw new Error('The `update` method must be defined in child classes.'); |
| }; |
| |
| return BaseSelection; |
| }); |
| |
| S2.define('select2/selection/single',[ |
| 'jquery', |
| './base', |
| '../utils', |
| '../keys' |
| ], function ($, BaseSelection, Utils, KEYS) { |
| function SingleSelection () { |
| SingleSelection.__super__.constructor.apply(this, arguments); |
| } |
| |
| Utils.Extend(SingleSelection, BaseSelection); |
| |
| SingleSelection.prototype.render = function () { |
| var $selection = SingleSelection.__super__.render.call(this); |
| |
| $selection.addClass('select2-selection--single'); |
| |
| $selection.html( |
| '<span class="select2-selection__rendered"></span>' + |
| '<span class="select2-selection__arrow" role="presentation">' + |
| '<b role="presentation"></b>' + |
| '</span>' |
| ); |
| |
| return $selection; |
| }; |
| |
| SingleSelection.prototype.bind = function (container, $container) { |
| var self = this; |
| |
| SingleSelection.__super__.bind.apply(this, arguments); |
| |
| var id = container.id + '-container'; |
| |
| this.$selection.find('.select2-selection__rendered') |
| .attr('id', id) |
| .attr('role', 'textbox') |
| .attr('aria-readonly', 'true'); |
| this.$selection.attr('aria-labelledby', id); |
| |
| this.$selection.on('mousedown', function (evt) { |
| // Only respond to left clicks |
| if (evt.which !== 1) { |
| return; |
| } |
| |
| self.trigger('toggle', { |
| originalEvent: evt |
| }); |
| }); |
| |
| this.$selection.on('focus', function (evt) { |
| // User focuses on the container |
| }); |
| |
| this.$selection.on('blur', function (evt) { |
| // User exits the container |
| }); |
| |
| container.on('focus', function (evt) { |
| if (!container.isOpen()) { |
| self.$selection.focus(); |
| } |
| }); |
| }; |
| |
| SingleSelection.prototype.clear = function () { |
| var $rendered = this.$selection.find('.select2-selection__rendered'); |
| $rendered.empty(); |
| $rendered.removeAttr('title'); // clear tooltip on empty |
| }; |
| |
| SingleSelection.prototype.display = function (data, container) { |
| var template = this.options.get('templateSelection'); |
| var escapeMarkup = this.options.get('escapeMarkup'); |
| |
| return escapeMarkup(template(data, container)); |
| }; |
| |
| SingleSelection.prototype.selectionContainer = function () { |
| return $('<span></span>'); |
| }; |
| |
| SingleSelection.prototype.update = function (data) { |
| if (data.length === 0) { |
| this.clear(); |
| return; |
| } |
| |
| var selection = data[0]; |
| |
| var $rendered = this.$selection.find('.select2-selection__rendered'); |
| var formatted = this.display(selection, $rendered); |
| |
| $rendered.empty().append(formatted); |
| $rendered.attr('title', selection.title || selection.text); |
| }; |
| |
| return SingleSelection; |
| }); |
| |
| S2.define('select2/selection/multiple',[ |
| 'jquery', |
| './base', |
| '../utils' |
| ], function ($, BaseSelection, Utils) { |
| function MultipleSelection ($element, options) { |
| MultipleSelection.__super__.constructor.apply(this, arguments); |
| } |
| |
| Utils.Extend(MultipleSelection, BaseSelection); |
| |
| MultipleSelection.prototype.render = function () { |
| var $selection = MultipleSelection.__super__.render.call(this); |
| |
| $selection.addClass('select2-selection--multiple'); |
| |
| $selection.html( |
| '<ul class="select2-selection__rendered"></ul>' |
| ); |
| |
| return $selection; |
| }; |
| |
| MultipleSelection.prototype.bind = function (container, $container) { |
| var self = this; |
| |
| MultipleSelection.__super__.bind.apply(this, arguments); |
| |
| this.$selection.on('click', function (evt) { |
| self.trigger('toggle', { |
| originalEvent: evt |
| }); |
| }); |
| |
| this.$selection.on( |
| 'click', |
| '.select2-selection__choice__remove', |
| function (evt) { |
| // Ignore the event if it is disabled |
| if (self.options.get('disabled')) { |
| return; |
| } |
| |
| var $remove = $(this); |
| var $selection = $remove.parent(); |
| |
| var data = Utils.GetData($selection[0], 'data'); |
| |
| self.trigger('unselect', { |
| originalEvent: evt, |
| data: data |
| }); |
| } |
| ); |
| }; |
| |
| MultipleSelection.prototype.clear = function () { |
| var $rendered = this.$selection.find('.select2-selection__rendered'); |
| $rendered.empty(); |
| $rendered.removeAttr('title'); |
| }; |
| |
| MultipleSelection.prototype.display = function (data, container) { |
| var template = this.options.get('templateSelection'); |
| var escapeMarkup = this.options.get('escapeMarkup'); |
| |
| return escapeMarkup(template(data, container)); |
| }; |
| |
| MultipleSelection.prototype.selectionContainer = function () { |
| var $container = $( |
| '<li class="select2-selection__choice">' + |
| '<span class="select2-selection__choice__remove" role="presentation">' + |
| '×' + |
| '</span>' + |
| '</li>' |
| ); |
| |
| return $container; |
| }; |
| |
| MultipleSelection.prototype.update = function (data) { |
| this.clear(); |
| |
| if (data.length === 0) { |
| return; |
| } |
| |
| var $selections = []; |
| |
| for (var d = 0; d < data.length; d++) { |
| var selection = data[d]; |
| |
| var $selection = this.selectionContainer(); |
| var formatted = this.display(selection, $selection); |
| |
| $selection.append(formatted); |
| $selection.attr('title', selection.title || selection.text); |
| |
| Utils.StoreData($selection[0], 'data', selection); |
| |
| $selections.push($selection); |
| } |
| |
| var $rendered = this.$selection.find('.select2-selection__rendered'); |
| |
| Utils.appendMany($rendered, $selections); |
| }; |
| |
| return MultipleSelection; |
| }); |
| |
| S2.define('select2/selection/placeholder',[ |
| '../utils' |
| ], function (Utils) { |
| function Placeholder (decorated, $element, options) { |
| this.placeholder = this.normalizePlaceholder(options.get('placeholder')); |
| |
| decorated.call(this, $element, options); |
| } |
| |
| Placeholder.prototype.normalizePlaceholder = function (_, placeholder) { |
| if (typeof placeholder === 'string') { |
| placeholder = { |
| id: '', |
| text: placeholder |
| }; |
| } |
| |
| return placeholder; |
| }; |
| |
| Placeholder.prototype.createPlaceholder = function (decorated, placeholder) { |
| var $placeholder = this.selectionContainer(); |
| |
| $placeholder.html(this.display(placeholder)); |
| $placeholder.addClass('select2-selection__placeholder') |
| .removeClass('select2-selection__choice'); |
| |
| return $placeholder; |
| }; |
| |
| Placeholder.prototype.update = function (decorated, data) { |
| var singlePlaceholder = ( |
| data.length == 1 && data[0].id != this.placeholder.id |
| ); |
| var multipleSelections = data.length > 1; |
| |
| if (multipleSelections || singlePlaceholder) { |
| return decorated.call(this, data); |
| } |
| |
| this.clear(); |
| |
| var $placeholder = this.createPlaceholder(this.placeholder); |
| |
| this.$selection.find('.select2-selection__rendered').append($placeholder); |
| }; |
| |
| return Placeholder; |
| }); |
| |
| S2.define('select2/selection/allowClear',[ |
| 'jquery', |
| '../keys', |
| '../utils' |
| ], function ($, KEYS, Utils) { |
| function AllowClear () { } |
| |
| AllowClear.prototype.bind = function (decorated, container, $container) { |
| var self = this; |
| |
| decorated.call(this, container, $container); |
| |
| if (this.placeholder == null) { |
| if (this.options.get('debug') && window.console && console.error) { |
| console.error( |
| 'Select2: The `allowClear` option should be used in combination ' + |
| 'with the `placeholder` option.' |
| ); |
| } |
| } |
| |
| this.$selection.on('mousedown', '.select2-selection__clear', |
| function (evt) { |
| self._handleClear(evt); |
| }); |
| |
| container.on('keypress', function (evt) { |
| self._handleKeyboardClear(evt, container); |
| }); |
| }; |
| |
| AllowClear.prototype._handleClear = function (_, evt) { |
| // Ignore the event if it is disabled |
| if (this.options.get('disabled')) { |
| return; |
| } |
| |
| var $clear = this.$selection.find('.select2-selection__clear'); |
| |
| // Ignore the event if nothing has been selected |
| if ($clear.length === 0) { |
| return; |
| } |
| |
| evt.stopPropagation(); |
| |
| var data = Utils.GetData($clear[0], 'data'); |
| |
| var previousVal = this.$element.val(); |
| this.$element.val(this.placeholder.id); |
| |
| var unselectData = { |
| data: data |
| }; |
| this.trigger('clear', unselectData); |
| if (unselectData.prevented) { |
| this.$element.val(previousVal); |
| return; |
| } |
| |
| for (var d = 0; d < data.length; d++) { |
| unselectData = { |
| data: data[d] |
| }; |
| |
| // Trigger the `unselect` event, so people can prevent it from being |
| // cleared. |
| this.trigger('unselect', unselectData); |
| |
| // If the event was prevented, don't clear it out. |
| if (unselectData.prevented) { |
| this.$element.val(previousVal); |
| return; |
| } |
| } |
| |
| this.$element.trigger('change'); |
| |
| this.trigger('toggle', {}); |
| }; |
| |
| AllowClear.prototype._handleKeyboardClear = function (_, evt, container) { |
| if (container.isOpen()) { |
| return; |
| } |
| |
| if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) { |
| this._handleClear(evt); |
| } |
| }; |
| |
| AllowClear.prototype.update = function (decorated, data) { |
| decorated.call(this, data); |
| |
| if (this.$selection.find('.select2-selection__placeholder').length > 0 || |
| data.length === 0) { |
| return; |
| } |
| |
| var $remove = $( |
| '<span class="select2-selection__clear">' + |
| '×' + |
| '</span>' |
| ); |
| Utils.StoreData($remove[0], 'data', data); |
| |
| this.$selection.find('.select2-selection__rendered').prepend($remove); |
| }; |
| |
| return AllowClear; |
| }); |
| |
| S2.define('select2/selection/search',[ |
| 'jquery', |
| '../utils', |
| '../keys' |
| ], function ($, Utils, KEYS) { |
| function Search (decorated, $element, options) { |
| decorated.call(this, $element, options); |
| } |
| |
| Search.prototype.render = function (decorated) { |
| var $search = $( |
| '<li class="select2-search select2-search--inline">' + |
| '<input class="select2-search__field" type="search" tabindex="-1"' + |
| ' autocomplete="off" autocorrect="off" autocapitalize="none"' + |
| ' spellcheck="false" role="textbox" aria-autocomplete="list" />' + |
| '</li>' |
| ); |
| |
| this.$searchContainer = $search; |
| this.$search = $search.find('input'); |
| |
| var $rendered = decorated.call(this); |
| |
| this._transferTabIndex(); |
| |
| return $rendered; |
| }; |
| |
| Search.prototype.bind = function (decorated, container, $container) { |
| var self = this; |
| |
| decorated.call(this, container, $container); |
| |
| container.on('open', function () { |
| self.$search.trigger('focus'); |
| }); |
| |
| container.on('close', function () { |
| self.$search.val(''); |
| self.$search.removeAttr('aria-activedescendant'); |
| self.$search.trigger('focus'); |
| }); |
| |
| container.on('enable', function () { |
| self.$search.prop('disabled', false); |
| |
| self._transferTabIndex(); |
| }); |
| |
| container.on('disable', function () { |
| self.$search.prop('disabled', true); |
| }); |
| |
| container.on('focus', function (evt) { |
| self.$search.trigger('focus'); |
| }); |
| |
| container.on('results:focus', function (params) { |
| self.$search.attr('aria-activedescendant', params.id); |
| }); |
| |
| this.$selection.on('focusin', '.select2-search--inline', function (evt) { |
| self.trigger('focus', evt); |
| }); |
| |
| this.$selection.on('focusout', '.select2-search--inline', function (evt) { |
| self._handleBlur(evt); |
| }); |
| |
| this.$selection.on('keydown', '.select2-search--inline', function (evt) { |
| evt.stopPropagation(); |
| |
| self.trigger('keypress', evt); |
| |
| self._keyUpPrevented = evt.isDefaultPrevented(); |
| |
| var key = evt.which; |
| |
| if (key === KEYS.BACKSPACE && self.$search.val() === '') { |
| var $previousChoice = self.$searchContainer |
| .prev('.select2-selection__choice'); |
| |
| if ($previousChoice.length > 0) { |
| var item = Utils.GetData($previousChoice[0], 'data'); |
| |
| self.searchRemoveChoice(item); |
| |
| evt.preventDefault(); |
| } |
| } |
| }); |
| |
| // Try to detect the IE version should the `documentMode` property that |
| // is stored on the document. This is only implemented in IE and is |
| // slightly cleaner than doing a user agent check. |
| // This property is not available in Edge, but Edge also doesn't have |
| // this bug. |
| var msie = document.documentMode; |
| var disableInputEvents = msie && msie <= 11; |
| |
| // Workaround for browsers which do not support the `input` event |
| // This will prevent double-triggering of events for browsers which support |
| // both the `keyup` and `input` events. |
| this.$selection.on( |
| 'input.searchcheck', |
| '.select2-search--inline', |
| function (evt) { |
| // IE will trigger the `input` event when a placeholder is used on a |
| // search box. To get around this issue, we are forced to ignore all |
| // `input` events in IE and keep using `keyup`. |
| if (disableInputEvents) { |
| self.$selection.off('input.search input.searchcheck'); |
| return; |
| } |
| |
| // Unbind the duplicated `keyup` event |
| self.$selection.off('keyup.search'); |
| } |
| ); |
| |
| this.$selection.on( |
| 'keyup.search input.search', |
| '.select2-search--inline', |
| function (evt) { |
| // IE will trigger the `input` event when a placeholder is used on a |
| // search box. To get around this issue, we are forced to ignore all |
| // `input` events in IE and keep using `keyup`. |
| if (disableInputEvents && evt.type === 'input') { |
| self.$selection.off('input.search input.searchcheck'); |
| return; |
| } |
| |
| var key = evt.which; |
| |
| // We can freely ignore events from modifier keys |
| if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) { |
| return; |
| } |
| |
| // Tabbing will be handled during the `keydown` phase |
| if (key == KEYS.TAB) { |
| return; |
| } |
| |
| self.handleSearch(evt); |
| } |
| ); |
| }; |
| |
| /** |
| * This method will transfer the tabindex attribute from the rendered |
| * selection to the search box. This allows for the search box to be used as |
| * the primary focus instead of the selection container. |
| * |
| * @private |
| */ |
| Search.prototype._transferTabIndex = function (decorated) { |
| this.$search.attr('tabindex', this.$selection.attr('tabindex')); |
| this.$selection.attr('tabindex', '-1'); |
| }; |
| |
| Search.prototype.createPlaceholder = function (decorated, placeholder) { |
| this.$search.attr('placeholder', placeholder.text); |
| }; |
| |
| Search.prototype.update = function (decorated, data) { |
| var searchHadFocus = this.$search[0] == document.activeElement; |
| |
| this.$search.attr('placeholder', ''); |
| |
| decorated.call(this, data); |
| |
| this.$selection.find('.select2-selection__rendered') |
| .append(this.$searchContainer); |
| |
| this.resizeSearch(); |
| if (searchHadFocus) { |
| var isTagInput = this.$element.find('[data-select2-tag]').length; |
| if (isTagInput) { |
| // fix IE11 bug where tag input lost focus |
| this.$element.focus(); |
| } else { |
| this.$search.focus(); |
| } |
| } |
| }; |
| |
| Search.prototype.handleSearch = function () { |
| this.resizeSearch(); |
| |
| if (!this._keyUpPrevented) { |
| var input = this.$search.val(); |
| |
| this.trigger('query', { |
| term: input |
| }); |
| } |
| |
| this._keyUpPrevented = false; |
| }; |
| |
| Search.prototype.searchRemoveChoice = function (decorated, item) { |
| this.trigger('unselect', { |
| data: item |
| }); |
| |
| this.$search.val(item.text); |
| this.handleSearch(); |
| }; |
| |
| Search.prototype.resizeSearch = function () { |
| this.$search.css('width', '25px'); |
| |
| var width = ''; |
| |
| if (this.$search.attr('placeholder') !== '') { |
| width = this.$selection.find('.select2-selection__rendered').innerWidth(); |
| } else { |
| var minimumWidth = this.$search.val().length + 1; |
| |
| width = (minimumWidth * 0.75) + 'em'; |
| } |
| |
| this.$search.css('width', width); |
| }; |
| |
| return Search; |
| }); |
| |
| S2.define('select2/selection/eventRelay',[ |
| 'jquery' |
| ], function ($) { |
| function EventRelay () { } |
| |
| EventRelay.prototype.bind = function (decorated, container, $container) { |
| var self = this; |
| var relayEvents = [ |
| 'open', 'opening', |
| 'close', 'closing', |
| 'select', 'selecting', |
| 'unselect', 'unselecting', |
| 'clear', 'clearing' |
| ]; |
| |
| var preventableEvents = [ |
| 'opening', 'closing', 'selecting', 'unselecting', 'clearing' |
| ]; |
| |
| decorated.call(this, container, $container); |
| |
| container.on('*', function (name, params) { |
| // Ignore events that should not be relayed |
| if ($.inArray(name, relayEvents) === -1) { |
| return; |
| } |
| |
| // The parameters should always be an object |
| params = params || {}; |
| |
| // Generate the jQuery event for the Select2 event |
| var evt = $.Event('select2:' + name, { |
| params: params |
| }); |
| |
| self.$element.trigger(evt); |
| |
| // Only handle preventable events if it was one |
| if ($.inArray(name, preventableEvents) === -1) { |
| return; |
| } |
| |
| params.prevented = evt.isDefaultPrevented(); |
| }); |
| }; |
| |
| return EventRelay; |
| }); |
| |
| S2.define('select2/translation',[ |
| 'jquery', |
| 'require' |
| ], function ($, require) { |
| function Translation (dict) { |
| this.dict = dict || {}; |
| } |
| |
| Translation.prototype.all = function () { |
| return this.dict; |
| }; |
| |
| Translation.prototype.get = function (key) { |
| return this.dict[key]; |
| }; |
| |
| Translation.prototype.extend = function (translation) { |
| this.dict = $.extend({}, translation.all(), this.dict); |
| }; |
| |
| // Static functions |
| |
| Translation._cache = {}; |
| |
| Translation.loadPath = function (path) { |
| if (!(path in Translation._cache)) { |
| var translations = require(path); |
| |
| Translation._cache[path] = translations; |
| } |
| |
| return new Translation(Translation._cache[path]); |
| }; |
| |
| return Translation; |
| }); |
| |
| S2.define('select2/diacritics',[ |
| |
| ], function () { |
| var diacritics = { |
| '\u24B6': 'A', |
| '\uFF21': 'A', |
| '\u00C0': 'A', |
| '\u00C1': 'A', |
| '\u00C2': 'A', |
| '\u1EA6': 'A', |
| '\u1EA4': 'A', |
| '\u1EAA': 'A', |
| '\u1EA8': 'A', |
| '\u00C3': 'A', |
| '\u0100': 'A', |
| '\u0102': 'A', |
| '\u1EB0': 'A', |
| '\u1EAE': 'A', |
| '\u1EB4': 'A', |
| '\u1EB2': 'A', |
| '\u0226': 'A', |
| '\u01E0': 'A', |
| '\u00C4': 'A', |
| '\u01DE': 'A', |
| '\u1EA2': 'A', |
| '\u00C5': 'A', |
| '\u01FA': 'A', |
| '\u01CD': 'A', |
| '\u0200': 'A', |
| '\u0202': 'A', |
| '\u1EA0': 'A', |
| '\u1EAC': 'A', |
| '\u1EB6': 'A', |
| '\u1E00': 'A', |
| '\u0104': 'A', |
| '\u023A': 'A', |
| '\u2C6F': 'A', |
| '\uA732': 'AA', |
| '\u00C6': 'AE', |
| '\u01FC': 'AE', |
| '\u01E2': 'AE', |
| '\uA734': 'AO', |
| '\uA736': 'AU', |
| '\uA738': 'AV', |
| '\uA73A': 'AV', |
| '\uA73C': 'AY', |
| '\u24B7': 'B', |
| '\uFF22': 'B', |
| '\u1E02': 'B', |
| '\u1E04': 'B', |
| '\u1E06': 'B', |
| '\u0243': 'B', |
| '\u0182': 'B', |
| '\u0181': 'B', |
| '\u24B8': 'C', |
| '\uFF23': 'C', |
| '\u0106': 'C', |
| '\u0108': 'C', |
| '\u010A': 'C', |
| '\u010C': 'C', |
| '\u00C7': 'C', |
| '\u1E08': 'C', |
| '\u0187': 'C', |
| '\u023B': 'C', |
| '\uA73E': 'C', |
| '\u24B9': 'D', |
| '\uFF24': 'D', |
| '\u1E0A': 'D', |
| '\u010E': 'D', |
| '\u1E0C': 'D', |
| '\u1E10': 'D', |
| '\u1E12': 'D', |
| '\u1E0E': 'D', |
| '\u0110': 'D', |
| '\u018B': 'D', |
| '\u018A': 'D', |
| '\u0189': 'D', |
| '\uA779': 'D', |
| '\u01F1': 'DZ', |
| '\u01C4': 'DZ', |
| '\u01F2': 'Dz', |
| '\u01C5': 'Dz', |
| '\u24BA': 'E', |
| '\uFF25': 'E', |
| '\u00C8': 'E', |
| '\u00C9': 'E', |
| '\u00CA': 'E', |
| '\u1EC0': 'E', |
| '\u1EBE': 'E', |
| '\u1EC4': 'E', |
| '\u1EC2': 'E', |
| '\u1EBC': 'E', |
| '\u0112': 'E', |
| '\u1E14': 'E', |
| '\u1E16': 'E', |
| '\u0114': 'E', |
| '\u0116': 'E', |
| '\u00CB': 'E', |
| '\u1EBA': 'E', |
| '\u011A': 'E', |
| '\u0204': 'E', |
| '\u0206': 'E', |
| '\u1EB8': 'E', |
| '\u1EC6': 'E', |
| '\u0228': 'E', |
| '\u1E1C': 'E', |
| '\u0118': 'E', |
| '\u1E18': 'E', |
| '\u1E1A': 'E', |
| '\u0190': 'E', |
| '\u018E': 'E', |
| '\u24BB': 'F', |
| '\uFF26': 'F', |
| '\u1E1E': 'F', |
| '\u0191': 'F', |
| '\uA77B': 'F', |
| '\u24BC': 'G', |
| '\uFF27': 'G', |
| '\u01F4': 'G', |
| '\u011C': 'G', |
| '\u1E20': 'G', |
| '\u011E': 'G', |
| '\u0120': 'G', |
| '\u01E6': 'G', |
| '\u0122': 'G', |
| '\u01E4': 'G', |
| '\u0193': 'G', |
| '\uA7A0': 'G', |
| '\uA77D': 'G', |
| '\uA77E': 'G', |
| '\u24BD': 'H', |
| '\uFF28': 'H', |
| '\u0124': 'H', |
| '\u1E22': 'H', |
| '\u1E26': 'H', |
| '\u021E': 'H', |
| '\u1E24': 'H', |
| '\u1E28': 'H', |
| '\u1E2A': 'H', |
| '\u0126': 'H', |
| '\u2C67': 'H', |
| '\u2C75': 'H', |
| '\uA78D': 'H', |
| '\u24BE': 'I', |
| '\uFF29': 'I', |
| '\u00CC': 'I', |
| '\u00CD': 'I', |
| '\u00CE': 'I', |
| '\u0128': 'I', |
| '\u012A': 'I', |
| '\u012C': 'I', |
| '\u0130': 'I', |
| '\u00CF': 'I', |
| '\u1E2E': 'I', |
| '\u1EC8': 'I', |
| '\u01CF': 'I', |
| '\u0208': 'I', |
| '\u020A': 'I', |
| '\u1ECA': 'I', |
| '\u012E': 'I', |
| '\u1E2C': 'I', |
| '\u0197': 'I', |
| '\u24BF': 'J', |
| '\uFF2A': 'J', |
| '\u0134': 'J', |
| '\u0248': 'J', |
| '\u24C0': 'K', |
| '\uFF2B': 'K', |
| '\u1E30': 'K', |
| '\u01E8': 'K', |
| '\u1E32': 'K', |
| '\u0136': 'K', |
| '\u1E34': 'K', |
| '\u0198': 'K', |
| '\u2C69': 'K', |
| '\uA740': 'K', |
| '\uA742': 'K', |
| '\uA744': 'K', |
| '\uA7A2': 'K', |
| '\u24C1': 'L', |
| '\uFF2C': 'L', |
| '\u013F': 'L', |
| '\u0139': 'L', |
| '\u013D': 'L', |
| '\u1E36': 'L', |
| '\u1E38': 'L', |
| '\u013B': 'L', |
| '\u1E3C': 'L', |
| '\u1E3A': 'L', |
| '\u0141': 'L', |
| '\u023D': 'L', |
| '\u2C62': 'L', |
| '\u2C60': 'L', |
| '\uA748': 'L', |
| '\uA746': 'L', |
| '\uA780': 'L', |
| '\u01C7': 'LJ', |
| '\u01C8': 'Lj', |
| '\u24C2': 'M', |
| '\uFF2D': 'M', |
| '\u1E3E': 'M', |
| '\u1E40': 'M', |
| '\u1E42': 'M', |
| '\u2C6E': 'M', |
| '\u019C': 'M', |
| '\u24C3': 'N', |
| '\uFF2E': 'N', |
| '\u01F8': 'N', |
| '\u0143': 'N', |
| '\u00D1': 'N', |
| '\u1E44': 'N', |
| '\u0147': 'N', |
| '\u1E46': 'N', |
| '\u0145': 'N', |
| '\u1E4A': 'N', |
| '\u1E48': 'N', |
| '\u0220': 'N', |
| '\u019D': 'N', |
| '\uA790': 'N', |
| '\uA7A4': 'N', |
| '\u01CA': 'NJ', |
| '\u01CB': 'Nj', |
| '\u24C4': 'O', |
| '\uFF2F': 'O', |
| '\u00D2': 'O', |
| '\u00D3': 'O', |
| '\u00D4': 'O', |
| '\u1ED2': 'O', |
| '\u1ED0': 'O', |
| '\u1ED6': 'O', |
| '\u1ED4': 'O', |
| '\u00D5': 'O', |
| '\u1E4C': 'O', |
| '\u022C': 'O', |
| '\u1E4E': 'O', |
| '\u014C': 'O', |
| '\u1E50': 'O', |
| '\u1E52': 'O', |
| '\u014E': 'O', |
| '\u022E': 'O', |
| '\u0230': 'O', |
| '\u00D6': 'O', |
| '\u022A': 'O', |
| '\u1ECE': 'O', |
| '\u0150': 'O', |
| '\u01D1': 'O', |
| '\u020C': 'O', |
| '\u020E': 'O', |
| '\u01A0': 'O', |
| '\u1EDC': 'O', |
| '\u1EDA': 'O', |
| '\u1EE0': 'O', |
| '\u1EDE': 'O', |
| '\u1EE2': 'O', |
| '\u1ECC': 'O', |
| '\u1ED8': 'O', |
| '\u01EA': 'O', |
| '\u01EC': 'O', |
| '\u00D8': 'O', |
| '\u01FE': 'O', |
| '\u0186': 'O', |
| '\u019F': 'O', |
| '\uA74A': 'O', |
| '\uA74C': 'O', |
| '\u01A2': 'OI', |
| '\uA74E': 'OO', |
| '\u0222': 'OU', |
| '\u24C5': 'P', |
| '\uFF30': 'P', |
| '\u1E54': 'P', |
| '\u1E56': 'P', |
| '\u01A4': 'P', |
| '\u2C63': 'P', |
| '\uA750': 'P', |
| '\uA752': 'P', |
| '\uA754': 'P', |
| '\u24C6': 'Q', |
| '\uFF31': 'Q', |
| '\uA756': 'Q', |
| '\uA758': 'Q', |
| '\u024A': 'Q', |
| '\u24C7': 'R', |
| '\uFF32': 'R', |
| '\u0154': 'R', |
| '\u1E58': 'R', |
| '\u0158': 'R', |
| '\u0210': 'R', |
| '\u0212': 'R', |
| '\u1E5A': 'R', |
| '\u1E5C': 'R', |
| '\u0156': 'R', |
| '\u1E5E': 'R', |
| '\u024C': 'R', |
| '\u2C64': 'R', |
| '\uA75A': 'R', |
| '\uA7A6': 'R', |
| '\uA782': 'R', |
| '\u24C8': 'S', |
| '\uFF33': 'S', |
| '\u1E9E': 'S', |
| '\u015A': 'S', |
| '\u1E64': 'S', |
| '\u015C': 'S', |
| '\u1E60': 'S', |
| '\u0160': 'S', |
| '\u1E66': 'S', |
| '\u1E62': 'S', |
| '\u1E68': 'S', |
| '\u0218': 'S', |
| '\u015E': 'S', |
| '\u2C7E': 'S', |
| '\uA7A8': 'S', |
| '\uA784': 'S', |
| '\u24C9': 'T', |
| '\uFF34': 'T', |
| '\u1E6A': 'T', |
| '\u0164': 'T', |
| '\u1E6C': 'T', |
| '\u021A': 'T', |
| '\u0162': 'T', |
| '\u1E70': 'T', |
| '\u1E6E': 'T', |
| '\u0166': 'T', |
| '\u01AC': 'T', |
| '\u01AE': 'T', |
| '\u023E': 'T', |
| '\uA786': 'T', |
| '\uA728': 'TZ', |
| '\u24CA': 'U', |
| '\uFF35': 'U', |
| '\u00D9': 'U', |
| '\u00DA': 'U', |
| '\u00DB': 'U', |
| '\u0168': 'U', |
| '\u1E78': 'U', |
| '\u016A': 'U', |
| '\u1E7A': 'U', |
| '\u016C': 'U', |
| '\u00DC': 'U', |
| '\u01DB': 'U', |
| '\u01D7': 'U', |
| '\u01D5': 'U', |
| '\u01D9': 'U', |
| '\u1EE6': 'U', |
| '\u016E': 'U', |
| '\u0170': 'U', |
| '\u01D3': 'U', |
| '\u0214': 'U', |
| '\u0216': 'U', |
| '\u01AF': 'U', |
| '\u1EEA': 'U', |
| '\u1EE8': 'U', |
| '\u1EEE': 'U', |
| '\u1EEC': 'U', |
| '\u1EF0': 'U', |
| '\u1EE4': 'U', |
| '\u1E72': 'U', |
| '\u0172': 'U', |
| '\u1E76': 'U', |
| '\u1E74': 'U', |
| '\u0244': 'U', |
| '\u24CB': 'V', |
| '\uFF36': 'V', |
| '\u1E7C': 'V', |
| '\u1E7E': 'V', |
| '\u01B2': 'V', |
| '\uA75E': 'V', |
| '\u0245': 'V', |
| '\uA760': 'VY', |
| '\u24CC': 'W', |
| '\uFF37': 'W', |
| '\u1E80': 'W', |
| '\u1E82': 'W', |
| '\u0174': 'W', |
| '\u1E86': 'W', |
| '\u1E84': 'W', |
| '\u1E88': 'W', |
| '\u2C72': 'W', |
| '\u24CD': 'X', |
| '\uFF38': 'X', |
| '\u1E8A': 'X', |
| '\u1E8C': 'X', |
| '\u24CE': 'Y', |
| '\uFF39': 'Y', |
| '\u1EF2': 'Y', |
| '\u00DD': 'Y', |
| '\u0176': 'Y', |
| '\u1EF8': 'Y', |
| '\u0232': 'Y', |
| '\u1E8E': 'Y', |
| '\u0178': 'Y', |
| '\u1EF6': 'Y', |
| '\u1EF4': 'Y', |
| '\u01B3': 'Y', |
| '\u024E': 'Y', |
| '\u1EFE': 'Y', |
| '\u24CF': 'Z', |
| '\uFF3A': 'Z', |
| '\u0179': 'Z', |
| '\u1E90': 'Z', |
| '\u017B': 'Z', |
| '\u017D': 'Z', |
| '\u1E92': 'Z', |
| '\u1E94': 'Z', |
| '\u01B5': 'Z', |
| '\u0224': 'Z', |
| '\u2C7F': 'Z', |
| '\u2C6B': 'Z', |
| '\uA762': 'Z', |
| '\u24D0': 'a', |
| '\uFF41': 'a', |
| '\u1E9A': 'a', |
| '\u00E0': 'a', |
| '\u00E1': 'a', |
| '\u00E2': 'a', |
| '\u1EA7': 'a', |
| '\u1EA5': 'a', |
| '\u1EAB': 'a', |
| '\u1EA9': 'a', |
| '\u00E3': 'a', |
| '\u0101': 'a', |
| '\u0103': 'a', |
| '\u1EB1': 'a', |
| '\u1EAF': 'a', |
| '\u1EB5': 'a', |
| '\u1EB3': 'a', |
| '\u0227': 'a', |
| '\u01E1': 'a', |
| '\u00E4': 'a', |
| '\u01DF': 'a', |
| '\u1EA3': 'a', |
| '\u00E5': 'a', |
| '\u01FB': 'a', |
| '\u01CE': 'a', |
| '\u0201': 'a', |
| '\u0203': 'a', |
| '\u1EA1': 'a', |
| '\u1EAD': 'a', |
| '\u1EB7': 'a', |
| '\u1E01': 'a', |
| '\u0105': 'a', |
| '\u2C65': 'a', |
| '\u0250': 'a', |
| '\uA733': 'aa', |
| '\u00E6': 'ae', |
| '\u01FD': 'ae', |
| '\u01E3': 'ae', |
| '\uA735': 'ao', |
| '\uA737': 'au', |
| '\uA739': 'av', |
| '\uA73B': 'av', |
| '\uA73D': 'ay', |
| '\u24D1': 'b', |
| '\uFF42': 'b', |
| '\u1E03': 'b', |
| '\u1E05': 'b', |
| '\u1E07': 'b', |
| '\u0180': 'b', |
| '\u0183': 'b', |
| '\u0253': 'b', |
| '\u24D2': 'c', |
| '\uFF43': 'c', |
| '\u0107': 'c', |
| '\u0109': 'c', |
| '\u010B': 'c', |
| '\u010D': 'c', |
| '\u00E7': 'c', |
| '\u1E09': 'c', |
| '\u0188': 'c', |
| '\u023C': 'c', |
| '\uA73F': 'c', |
| '\u2184': 'c', |
| '\u24D3': 'd', |
| '\uFF44': 'd', |
| '\u1E0B': 'd', |
| '\u010F': 'd', |
| '\u1E0D': 'd', |
| '\u1E11': 'd', |
| '\u1E13': 'd', |
| '\u1E0F': 'd', |
| '\u0111': 'd', |
| '\u018C': 'd', |
| '\u0256': 'd', |
| '\u0257': 'd', |
| '\uA77A': 'd', |
| '\u01F3': 'dz', |
| '\u01C6': 'dz', |
| '\u24D4': 'e', |
| '\uFF45': 'e', |
| '\u00E8': 'e', |
| '\u00E9': 'e', |
| '\u00EA': 'e', |
| '\u1EC1': 'e', |
| '\u1EBF': 'e', |
| '\u1EC5': 'e', |
| '\u1EC3': 'e', |
| '\u1EBD': 'e', |
| '\u0113': 'e', |
| '\u1E15': 'e', |
| '\u1E17': 'e', |
| '\u0115': 'e', |
| '\u0117': 'e', |
| '\u00EB': 'e', |
| '\u1EBB': 'e', |
| '\u011B': 'e', |
| '\u0205': 'e', |
| '\u0207': 'e', |
| '\u1EB9': 'e', |
| '\u1EC7': 'e', |
| '\u0229': 'e', |
| '\u1E1D': 'e', |
| '\u0119': 'e', |
| '\u1E19': 'e', |
| '\u1E1B': 'e', |
| '\u0247': 'e', |
| '\u025B': 'e', |
| '\u01DD': 'e', |
| '\u24D5': 'f', |
| '\uFF46': 'f', |
| '\u1E1F': 'f', |
| '\u0192': 'f', |
| '\uA77C': 'f', |
| '\u24D6': 'g', |
| '\uFF47': 'g', |
| '\u01F5': 'g', |
| '\u011D': 'g', |
| '\u1E21': 'g', |
| '\u011F': 'g', |
| '\u0121': 'g', |
| '\u01E7': 'g', |
| '\u0123': 'g', |
| '\u01E5': 'g', |
| '\u0260': 'g', |
| '\uA7A1': 'g', |
| '\u1D79': 'g', |
| '\uA77F': 'g', |
| '\u24D7': 'h', |
| '\uFF48': 'h', |
| '\u0125': 'h', |
| '\u1E23': 'h', |
| '\u1E27': 'h', |
| '\u021F': 'h', |
| '\u1E25': 'h', |
| '\u1E29': 'h', |
| '\u1E2B': 'h', |
| '\u1E96': 'h', |
| '\u0127': 'h', |
| '\u2C68': 'h', |
| '\u2C76': 'h', |
| '\u0265': 'h', |
| '\u0195': 'hv', |
| '\u24D8': 'i', |
| '\uFF49': 'i', |
| '\u00EC': 'i', |
| '\u00ED': 'i', |
| '\u00EE': 'i', |
| '\u0129': 'i', |
| '\u012B': 'i', |
| '\u012D': 'i', |
| '\u00EF': 'i', |
| '\u1E2F': 'i', |
| '\u1EC9': 'i', |
| '\u01D0': 'i', |
| '\u0209': 'i', |
| '\u020B': 'i', |
| '\u1ECB': 'i', |
| '\u012F': 'i', |
| '\u1E2D': 'i', |
| '\u0268': 'i', |
| '\u0131': 'i', |
| '\u24D9': 'j', |
| '\uFF4A': 'j', |
| '\u0135': 'j', |
| '\u01F0': 'j', |
| '\u0249': 'j', |
| '\u24DA': 'k', |
| '\uFF4B': 'k', |
| '\u1E31': 'k', |
| '\u01E9': 'k', |
| '\u1E33': 'k', |
| '\u0137': 'k', |
| '\u1E35': 'k', |
| '\u0199': 'k', |
| '\u2C6A': 'k', |
| '\uA741': 'k', |
| '\uA743': 'k', |
| '\uA745': 'k', |
| '\uA7A3': 'k', |
| '\u24DB': 'l', |
| '\uFF4C': 'l', |
| '\u0140': 'l', |
| '\u013A': 'l', |
| '\u013E': 'l', |
| '\u1E37': 'l', |
| '\u1E39': 'l', |
| '\u013C': 'l', |
| '\u1E3D': 'l', |
| '\u1E3B': 'l', |
| '\u017F': 'l', |
| '\u0142': 'l', |
| '\u019A': 'l', |
| '\u026B': 'l', |
| '\u2C61': 'l', |
| '\uA749': 'l', |
| '\uA781': 'l', |
| '\uA747': 'l', |
| '\u01C9': 'lj', |
| '\u24DC': 'm', |
| '\uFF4D': 'm', |
| '\u1E3F': 'm', |
| '\u1E41': 'm', |
| '\u1E43': 'm', |
| '\u0271': 'm', |
| '\u026F': 'm', |
| '\u24DD': 'n', |
| '\uFF4E': 'n', |
| '\u01F9': 'n', |
| '\u0144': 'n', |
| '\u00F1': 'n', |
| '\u1E45': 'n', |
| '\u0148': 'n', |
| '\u1E47': 'n', |
| '\u0146': 'n', |
| '\u1E4B': 'n', |
| '\u1E49': 'n', |
| '\u019E': 'n', |
| '\u0272': 'n', |
| '\u0149': 'n', |
| '\uA791': 'n', |
| '\uA7A5': 'n', |
| '\u01CC': 'nj', |
| '\u24DE': 'o', |
| '\uFF4F': 'o', |
| '\u00F2': 'o', |
| '\u00F3': 'o', |
| '\u00F4': 'o', |
| '\u1ED3': 'o', |
| '\u1ED1': 'o', |
| '\u1ED7': 'o', |
| '\u1ED5': 'o', |
| '\u00F5': 'o', |
| '\u1E4D': 'o', |
| '\u022D': 'o', |
| '\u1E4F': 'o', |
| '\u014D': 'o', |
| '\u1E51': 'o', |
| '\u1E53': 'o', |
| '\u014F': 'o', |
| '\u022F': 'o', |
| '\u0231': 'o', |
| '\u00F6': 'o', |
| '\u022B': 'o', |
| '\u1ECF': 'o', |
| '\u0151': 'o', |
| '\u01D2': 'o', |
| '\u020D': 'o', |
| '\u020F': 'o', |
| '\u01A1': 'o', |
| '\u1EDD': 'o', |
| '\u1EDB': 'o', |
| '\u1EE1': 'o', |
| '\u1EDF': 'o', |
| '\u1EE3': 'o', |
| '\u1ECD': 'o', |
| '\u1ED9': 'o', |
| '\u01EB': 'o', |
| '\u01ED': 'o', |
| '\u00F8': 'o', |
| '\u01FF': 'o', |
| '\u0254': 'o', |
| '\uA74B': 'o', |
| '\uA74D': 'o', |
| '\u0275': 'o', |
| '\u01A3': 'oi', |
| '\u0223': 'ou', |
| '\uA74F': 'oo', |
| '\u24DF': 'p', |
| '\uFF50': 'p', |
| '\u1E55': 'p', |
| '\u1E57': 'p', |
| '\u01A5': 'p', |
| '\u1D7D': 'p', |
| '\uA751': 'p', |
| '\uA753': 'p', |
| '\uA755': 'p', |
| '\u24E0': 'q', |
| '\uFF51': 'q', |
| '\u024B': 'q', |
| '\uA757': 'q', |
| '\uA759': 'q', |
| '\u24E1': 'r', |
| '\uFF52': 'r', |
| '\u0155': 'r', |
| '\u1E59': 'r', |
| '\u0159': 'r', |
| '\u0211': 'r', |
| '\u0213': 'r', |
| '\u1E5B': 'r', |
| '\u1E5D': 'r', |
| '\u0157': 'r', |
| '\u1E5F': 'r', |
| '\u024D': 'r', |
| '\u027D': 'r', |
| '\uA75B': 'r', |
| '\uA7A7': 'r', |
| '\uA783': 'r', |
| '\u24E2': 's', |
| '\uFF53': 's', |
| '\u00DF': 's', |
| '\u015B': 's', |
| '\u1E65': 's', |
| '\u015D': 's', |
| '\u1E61': 's', |
| '\u0161': 's', |
| '\u1E67': 's', |
| '\u1E63': 's', |
| '\u1E69': 's', |
| '\u0219': 's', |
| '\u015F': 's', |
| '\u023F': 's', |
| '\uA7A9': 's', |
| '\uA785': 's', |
| '\u1E9B': 's', |
| '\u24E3': 't', |
| '\uFF54': 't', |
| '\u1E6B': 't', |
| '\u1E97': 't', |
| '\u0165': 't', |
| '\u1E6D': 't', |
| '\u021B': 't', |
| '\u0163': 't', |
| '\u1E71': 't', |
| '\u1E6F': 't', |
| '\u0167': 't', |
| '\u01AD': 't', |
| '\u0288': 't', |
| '\u2C66': 't', |
| '\uA787': 't', |
| '\uA729': 'tz', |
| '\u24E4': 'u', |
| '\uFF55': 'u', |
| '\u00F9': 'u', |
| '\u00FA': 'u', |
| '\u00FB': 'u', |
| '\u0169': 'u', |
| '\u1E79': 'u', |
| '\u016B': 'u', |
| '\u1E7B': 'u', |
| '\u016D': 'u', |
| '\u00FC': 'u', |
| '\u01DC': 'u', |
| '\u01D8': 'u', |
| '\u01D6': 'u', |
| '\u01DA': 'u', |
| '\u1EE7': 'u', |
| '\u016F': 'u', |
| '\u0171': 'u', |
| '\u01D4': 'u', |
| '\u0215': 'u', |
| '\u0217': 'u', |
| '\u01B0': 'u', |
| '\u1EEB': 'u', |
| '\u1EE9': 'u', |
| '\u1EEF': 'u', |
| '\u1EED': 'u', |
| '\u1EF1': 'u', |
| '\u1EE5': 'u', |
| '\u1E73': 'u', |
| '\u0173': 'u', |
| '\u1E77': 'u', |
| '\u1E75': 'u', |
| '\u0289': 'u', |
| '\u24E5': 'v', |
| '\uFF56': 'v', |
| '\u1E7D': 'v', |
| '\u1E7F': 'v', |
| '\u028B': 'v', |
| '\uA75F': 'v', |
| '\u028C': 'v', |
| '\uA761': 'vy', |
| '\u24E6': 'w', |
| '\uFF57': 'w', |
| '\u1E81': 'w', |
| '\u1E83': 'w', |
| '\u0175': 'w', |
| '\u1E87': 'w', |
| '\u1E85': 'w', |
| '\u1E98': 'w', |
| '\u1E89': 'w', |
| '\u2C73': 'w', |
| '\u24E7': 'x', |
| '\uFF58': 'x', |
| '\u1E8B': 'x', |
| '\u1E8D': 'x', |
| '\u24E8': 'y', |
| '\uFF59': 'y', |
| '\u1EF3': 'y', |
| '\u00FD': 'y', |
| '\u0177': 'y', |
| '\u1EF9': 'y', |
| '\u0233': 'y', |
| '\u1E8F': 'y', |
| '\u00FF': 'y', |
| '\u1EF7': 'y', |
| '\u1E99': 'y', |
| '\u1EF5': 'y', |
| '\u01B4': 'y', |
| '\u024F': 'y', |
| '\u1EFF': 'y', |
| '\u24E9': 'z', |
| '\uFF5A': 'z', |
| '\u017A': 'z', |
| '\u1E91': 'z', |
| '\u017C': 'z', |
| '\u017E': 'z', |
| '\u1E93': 'z', |
| '\u1E95': 'z', |
| '\u01B6': 'z', |
| '\u0225': 'z', |
| '\u0240': 'z', |
| '\u2C6C': 'z', |
| '\uA763': 'z', |
| '\u0386': '\u0391', |
| '\u0388': '\u0395', |
| '\u0389': '\u0397', |
| '\u038A': '\u0399', |
| '\u03AA': '\u0399', |
| '\u038C': '\u039F', |
| '\u038E': '\u03A5', |
| '\u03AB': '\u03A5', |
| '\u038F': '\u03A9', |
| '\u03AC': '\u03B1', |
| '\u03AD': '\u03B5', |
| '\u03AE': '\u03B7', |
| '\u03AF': '\u03B9', |
| '\u03CA': '\u03B9', |
| '\u0390': '\u03B9', |
| '\u03CC': '\u03BF', |
| '\u03CD': '\u03C5', |
| '\u03CB': '\u03C5', |
| '\u03B0': '\u03C5', |
| '\u03C9': '\u03C9', |
| '\u03C2': '\u03C3' |
| }; |
| |
| return diacritics; |
| }); |
| |
| S2.define('select2/data/base',[ |
| '../utils' |
| ], function (Utils) { |
| function BaseAdapter ($element, options) { |
| BaseAdapter.__super__.constructor.call(this); |
| } |
| |
| Utils.Extend(BaseAdapter, Utils.Observable); |
| |
| BaseAdapter.prototype.current = function (callback) { |
| throw new Error('The `current` method must be defined in child classes.'); |
| }; |
| |
| BaseAdapter.prototype.query = function (params, callback) { |
| throw new Error('The `query` method must be defined in child classes.'); |
| }; |
| |
| BaseAdapter.prototype.bind = function (container, $container) { |
| // Can be implemented in subclasses |
| }; |
| |
| BaseAdapter.prototype.destroy = function () { |
| // Can be implemented in subclasses |
| }; |
| |
| BaseAdapter.prototype.generateResultId = function (container, data) { |
| var id = container.id + '-result-'; |
| |
| id += Utils.generateChars(4); |
| |
| if (data.id != null) { |
| id += '-' + data.id.toString(); |
| } else { |
| id += '-' + Utils.generateChars(4); |
| } |
| return id; |
| }; |
| |
| return BaseAdapter; |
| }); |
| |
| S2.define('select2/data/select',[ |
| './base', |
| '../utils', |
| 'jquery' |
| ], function (BaseAdapter, Utils, $) { |
| function SelectAdapter ($element, options) { |
| this.$element = $element; |
| this.options = options; |
| |
| SelectAdapter.__super__.constructor.call(this); |
| } |
| |
| Utils.Extend(SelectAdapter, BaseAdapter); |
| |
| SelectAdapter.prototype.current = function (callback) { |
| var data = []; |
| var self = this; |
| |
| this.$element.find(':selected').each(function () { |
| var $option = $(this); |
| |
| var option = self.item($option); |
| |
| data.push(option); |
| }); |
| |
| callback(data); |
| }; |
| |
| SelectAdapter.prototype.select = function (data) { |
| var self = this; |
| |
| data.selected = true; |
| |
| // If data.element is a DOM node, use it instead |
| if ($(data.element).is('option')) { |
| data.element.selected = true; |
| |
| this.$element.trigger('change'); |
| |
| return; |
| } |
| |
| if (this.$element.prop('multiple')) { |
| this.current(function (currentData) { |
| var val = []; |
| |
| data = [data]; |
| data.push.apply(data, currentData); |
| |
| for (var d = 0; d < data.length; d++) { |
| var id = data[d].id; |
| |
| if ($.inArray(id, val) === -1) { |
| val.push(id); |
| } |
| } |
| |
| self.$element.val(val); |
| self.$element.trigger('change'); |
| }); |
| } else { |
| var val = data.id; |
| |
| this.$element.val(val); |
| this.$element.trigger('change'); |
| } |
| }; |
| |
| SelectAdapter.prototype.unselect = function (data) { |
| var self = this; |
| |
| if (!this.$element.prop('multiple')) { |
| return; |
| } |
| |
| data.selected = false; |
| |
| if ($(data.element).is('option')) { |
| data.element.selected = false; |
| |
| this.$element.trigger('change'); |
| |
| return; |
| } |
| |
| this.current(function (currentData) { |
| var val = []; |
| |
| for (var d = 0; d < currentData.length; d++) { |
| var id = currentData[d].id; |
| |
| if (id !== data.id && $.inArray(id, val) === -1) { |
| val.push(id); |
| } |
| } |
| |
| self.$element.val(val); |
| |
| self.$element.trigger('change'); |
| }); |
| }; |
| |
| SelectAdapter.prototype.bind = function (container, $container) { |
| var self = this; |
| |
| this.container = container; |
| |
| container.on('select', function (params) { |
| self.select(params.data); |
| }); |
| |
| container.on('unselect', function (params) { |
| self.unselect(params.data); |
| }); |
| }; |
| |
| SelectAdapter.prototype.destroy = function () { |
| // Remove anything added to child elements |
| this.$element.find('*').each(function () { |
| // Remove any custom data set by Select2 |
| Utils.RemoveData(this); |
| }); |
| }; |
| |
| SelectAdapter.prototype.query = function (params, callback) { |
| var data = []; |
| var self = this; |
| |
| var $options = this.$element.children(); |
| |
| $options.each(function () { |
| var $option = $(this); |
| |
| if (!$option.is('option') && !$option.is('optgroup')) { |
| return; |
| } |
| |
| var option = self.item($option); |
| |
| var matches = self.matches(params, option); |
| |
| if (matches !== null) { |
| data.push(matches); |
| } |
| }); |
| |
| callback({ |
| results: data |
| }); |
| }; |
| |
| SelectAdapter.prototype.addOptions = function ($options) { |
| Utils.appendMany(this.$element, $options); |
| }; |
| |
| SelectAdapter.prototype.option = function (data) { |
| var option; |
| |
| if (data.children) { |
| option = document.createElement('optgroup'); |
| option.label = data.text; |
| } else { |
| option = document.createElement('option'); |
| |
| if (option.textContent !== undefined) { |
| option.textContent = data.text; |
| } else { |
| option.innerText = data.text; |
| } |
| } |
| |
| if (data.id !== undefined) { |
| option.value = data.id; |
| } |
| |
| if (data.disabled) { |
| option.disabled = true; |
| } |
| |
| if (data.selected) { |
| option.selected = true; |
| } |
| |
| if (data.title) { |
| option.title = data.title; |
| } |
| |
| var $option = $(option); |
| |
| var normalizedData = this._normalizeItem(data); |
| normalizedData.element = option; |
| |
| // Override the option's data with the combined data |
| Utils.StoreData(option, 'data', normalizedData); |
| |
| return $option; |
| }; |
| |
| SelectAdapter.prototype.item = function ($option) { |
| var data = {}; |
| |
| data = Utils.GetData($option[0], 'data'); |
| |
| if (data != null) { |
| return data; |
| } |
| |
| if ($option.is('option')) { |
| data = { |
| id: $option.val(), |
| text: $option.text(), |
| disabled: $option.prop('disabled'), |
| selected: $option.prop('selected'), |
| title: $option.prop('title') |
| }; |
| } else if ($option.is('optgroup')) { |
| data = { |
| text: $option.prop('label'), |
| children: [], |
| title: $option.prop('title') |
| }; |
| |
| var $children = $option.children('option'); |
| var children = []; |
| |
| for (var c = 0; c < $children.length; c++) { |
| var $child = $($children[c]); |
| |
| var child = this.item($child); |
| |
| children.push(child); |
| } |
| |
| data.children = children; |
| } |
| |
| data = this._normalizeItem(data); |
| data.element = $option[0]; |
| |
| Utils.StoreData($option[0], 'data', data); |
| |
| return data; |
| }; |
| |
| SelectAdapter.prototype._normalizeItem = function (item) { |
| if (item !== Object(item)) { |
| item = { |
| id: item, |
| text: item |
| }; |
| } |
| |
| item = $.extend({}, { |
| text: '' |
| }, item); |
| |
| var defaults = { |
| selected: false, |
| disabled: false |
| }; |
| |
| if (item.id != null) { |
| item.id = item.id.toString(); |
| } |
| |
| if (item.text != null) { |
| item.text = item.text.toString(); |
| } |
| |
| if (item._resultId == null && item.id && this.container != null) { |
| item._resultId = this.generateResultId(this.container, item); |
| } |
| |
| return $.extend({}, defaults, item); |
| }; |
| |
| SelectAdapter.prototype.matches = function (params, data) { |
| var matcher = this.options.get('matcher'); |
| |
| return matcher(params, data); |
| }; |
| |
| return SelectAdapter; |
| }); |
| |
| S2.define('select2/data/array',[ |
| './select', |
| '../utils', |
| 'jquery' |
| ], function (SelectAdapter, Utils, $) { |
| function ArrayAdapter ($element, options) { |
| var data = options.get('data') || []; |
| |
| ArrayAdapter.__super__.constructor.call(this, $element, options); |
| |
| this.addOptions(this.convertToOptions(data)); |
| } |
| |
| Utils.Extend(ArrayAdapter, SelectAdapter); |
| |
| ArrayAdapter.prototype.select = function (data) { |
| var $option = this.$element.find('option').filter(function (i, elm) { |
| return elm.value == data.id.toString(); |
| }); |
| |
| if ($option.length === 0) { |
| $option = this.option(data); |
| |
| this.addOptions($option); |
| } |
| |
| ArrayAdapter.__super__.select.call(this, data); |
| }; |
| |
| ArrayAdapter.prototype.convertToOptions = function (data) { |
| var self = this; |
| |
| var $existing = this.$element.find('option'); |
| var existingIds = $existing.map(function () { |
| return self.item($(this)).id; |
| }).get(); |
| |
| var $options = []; |
| |
| // Filter out all items except for the one passed in the argument |
| function onlyItem (item) { |
| return function () { |
| return $(this).val() == item.id; |
| }; |
| } |
| |
| for (var d = 0; d < data.length; d++) { |
| var item = this._normalizeItem(data[d]); |
| |
| // Skip items which were pre-loaded, only merge the data |
| if ($.inArray(item.id, existingIds) >= 0) { |
| var $existingOption = $existing.filter(onlyItem(item)); |
| |
| var existingData = this.item($existingOption); |
| var newData = $.extend(true, {}, item, existingData); |
| |
| var $newOption = this.option(newData); |
| |
| $existingOption.replaceWith($newOption); |
| |
| continue; |
| } |
| |
| var $option = this.option(item); |
| |
| if (item.children) { |
| var $children = this.convertToOptions(item.children); |
| |
| Utils.appendMany($option, $children); |
| } |
| |
| $options.push($option); |
| } |
| |
| return $options; |
| }; |
| |
| return ArrayAdapter; |
| }); |
| |
| S2.define('select2/data/ajax',[ |
| './array', |
| '../utils', |
| 'jquery' |
| ], function (ArrayAdapter, Utils, $) { |
| function AjaxAdapter ($element, options) { |
| this.ajaxOptions = this._applyDefaults(options.get('ajax')); |
| |
| if (this.ajaxOptions.processResults != null) { |
| this.processResults = this.ajaxOptions.processResults; |
| } |
| |
| AjaxAdapter.__super__.constructor.call(this, $element, options); |
| } |
| |
| Utils.Extend(AjaxAdapter, ArrayAdapter); |
| |
| AjaxAdapter.prototype._applyDefaults = function (options) { |
| var defaults = { |
| data: function (params) { |
| return $.extend({}, params, { |
| q: params.term |
| }); |
| }, |
| transport: function (params, success, failure) { |
| var $request = $.ajax(params); |
| |
| $request.then(success); |
| $request.fail(failure); |
| |
| return $request; |
| } |
| }; |
| |
| return $.extend({}, defaults, options, true); |
| }; |
| |
| AjaxAdapter.prototype.processResults = function (results) { |
| return results; |
| }; |
| |
| AjaxAdapter.prototype.query = function (params, callback) { |
| var matches = []; |
| var self = this; |
| |
| if (this._request != null) { |
| // JSONP requests cannot always be aborted |
| if ($.isFunction(this._request.abort)) { |
| this._request.abort(); |
| } |
| |
| this._request = null; |
| } |
| |
| var options = $.extend({ |
| type: 'GET' |
| }, this.ajaxOptions); |
| |
| if (typeof options.url === 'function') { |
| options.url = options.url.call(this.$element, params); |
| } |
| |
| if (typeof options.data === 'function') { |
| options.data = options.data.call(this.$element, params); |
| } |
| |
| function request () { |
| var $request = options.transport(options, function (data) { |
| var results = self.processResults(data, params); |
| |
| if (self.options.get('debug') && window.console && console.error) { |
| // Check to make sure that the response included a `results` key. |
| if (!results || !results.results || !$.isArray(results.results)) { |
| console.error( |
| 'Select2: The AJAX results did not return an array in the ' + |
| '`results` key of the response.' |
| ); |
| } |
| } |
| |
| callback(results); |
| }, function () { |
| // Attempt to detect if a request was aborted |
| // Only works if the transport exposes a status property |
| if ('status' in $request && |
| ($request.status === 0 || $request.status === '0')) { |
| return; |
| } |
| |
| self.trigger('results:message', { |
| message: 'errorLoading' |
| }); |
| }); |
| |
| self._request = $request; |
| } |
| |
| if (this.ajaxOptions.delay && params.term != null) { |
| if (this._queryTimeout) { |
| window.clearTimeout(this._queryTimeout); |
| } |
| |
| this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay); |
| } else { |
| request(); |
| } |
| }; |
| |
| return AjaxAdapter; |
| }); |
| |
| S2.define('select2/data/tags',[ |
| 'jquery' |
| ], function ($) { |
| function Tags (decorated, $element, options) { |
| var tags = options.get('tags'); |
| |
| var createTag = options.get('createTag'); |
| |
| if (createTag !== undefined) { |
| this.createTag = createTag; |
| } |
| |
| var insertTag = options.get('insertTag'); |
| |
| if (insertTag !== undefined) { |
| this.insertTag = insertTag; |
| } |
| |
| decorated.call(this, $element, options); |
| |
| if ($.isArray(tags)) { |
| for (var t = 0; t < tags.length; t++) { |
| var tag = tags[t]; |
| var item = this._normalizeItem(tag); |
| |
| var $option = this.option(item); |
| |
| this.$element.append($option); |
| } |
| } |
| } |
| |
| Tags.prototype.query = function (decorated, params, callback) { |
| var self = this; |
| |
| this._removeOldTags(); |
| |
| if (params.term == null || params.page != null) { |
| decorated.call(this, params, callback); |
| return; |
| } |
| |
| function wrapper (obj, child) { |
| var data = obj.results; |
| |
| for (var i = 0; i < data.length; i++) { |
| var option = data[i]; |
| |
| var checkChildren = ( |
| option.children != null && |
| !wrapper({ |
| results: option.children |
| }, true) |
| ); |
| |
| var optionText = (option.text || '').toUpperCase(); |
| var paramsTerm = (params.term || '').toUpperCase(); |
| |
| var checkText = optionText === paramsTerm; |
| |
| if (checkText || checkChildren) { |
| if (child) { |
| return false; |
| } |
| |
| obj.data = data; |
| callback(obj); |
| |
| return; |
| } |
| } |
| |
| if (child) { |
| return true; |
| } |
| |
| var tag = self.createTag(params); |
| |
| if (tag != null) { |
| var $option = self.option(tag); |
| $option.attr('data-select2-tag', true); |
| |
| self.addOptions([$option]); |
| |
| self.insertTag(data, tag); |
| } |
| |
| obj.results = data; |
| |
| callback(obj); |
| } |
| |
| decorated.call(this, params, wrapper); |
| }; |
| |
| Tags.prototype.createTag = function (decorated, params) { |
| var term = $.trim(params.term); |
| |
| if (term === '') { |
| return null; |
| } |
| |
| return { |
| id: term, |
| text: term |
| }; |
| }; |
| |
| Tags.prototype.insertTag = function (_, data, tag) { |
| data.unshift(tag); |
| }; |
| |
| Tags.prototype._removeOldTags = function (_) { |
| var tag = this._lastTag; |
| |
| var $options = this.$element.find('option[data-select2-tag]'); |
| |
| $options.each(function () { |
| if (this.selected) { |
| return; |
| } |
| |
| $(this).remove(); |
| }); |
| }; |
| |
| return Tags; |
| }); |
| |
| S2.define('select2/data/tokenizer',[ |
| 'jquery' |
| ], function ($) { |
| function Tokenizer (decorated, $element, options) { |
| var tokenizer = options.get('tokenizer'); |
| |
| if (tokenizer !== undefined) { |
| this.tokenizer = tokenizer; |
| } |
| |
| decorated.call(this, $element, options); |
| } |
| |
| Tokenizer.prototype.bind = function (decorated, container, $container) { |
| decorated.call(this, container, $container); |
| |
| this.$search = container.dropdown.$search || container.selection.$search || |
| $container.find('.select2-search__field'); |
| }; |
| |
| Tokenizer.prototype.query = function (decorated, params, callback) { |
| var self = this; |
| |
| function createAndSelect (data) { |
| // Normalize the data object so we can use it for checks |
| var item = self._normalizeItem(data); |
| |
| // Check if the data object already exists as a tag |
| // Select it if it doesn't |
| var $existingOptions = self.$element.find('option').filter(function () { |
| return $(this).val() === item.id; |
| }); |
| |
| // If an existing option wasn't found for it, create the option |
| if (!$existingOptions.length) { |
| var $option = self.option(item); |
| $option.attr('data-select2-tag', true); |
| |
| self._removeOldTags(); |
| self.addOptions([$option]); |
| } |
| |
| // Select the item, now that we know there is an option for it |
| select(item); |
| } |
| |
| function select (data) { |
| self.trigger('select', { |
| data: data |
| }); |
| } |
| |
| params.term = params.term || ''; |
| |
| var tokenData = this.tokenizer(params, this.options, createAndSelect); |
| |
| if (tokenData.term !== params.term) { |
| // Replace the search term if we have the search box |
| if (this.$search.length) { |
| this.$search.val(tokenData.term); |
| this.$search.focus(); |
| } |
| |
| params.term = tokenData.term; |
| } |
| |
| decorated.call(this, params, callback); |
| }; |
| |
| Tokenizer.prototype.tokenizer = function (_, params, options, callback) { |
| var separators = options.get('tokenSeparators') || []; |
| var term = params.term; |
| var i = 0; |
| |
| var createTag = this.createTag || function (params) { |
| return { |
| id: params.term, |
| text: params.term |
| }; |
| }; |
| |
| while (i < term.length) { |
| var termChar = term[i]; |
| |
| if ($.inArray(termChar, separators) === -1) { |
| i++; |
| |
| continue; |
| } |
| |
| var part = term.substr(0, i); |
| var partParams = $.extend({}, params, { |
| term: part |
| }); |
| |
| var data = createTag(partParams); |
| |
| if (data == null) { |
| i++; |
| continue; |
| } |
| |
| callback(data); |
| |
| // Reset the term to not include the tokenized portion |
| term = term.substr(i + 1) || ''; |
| i = 0; |
| } |
| |
| return { |
| term: term |
| }; |
| }; |
| |
| return Tokenizer; |
| }); |
| |
| S2.define('select2/data/minimumInputLength',[ |
| |
| ], function () { |
| function MinimumInputLength (decorated, $e, options) { |
| this.minimumInputLength = options.get('minimumInputLength'); |
| |
| decorated.call(this, $e, options); |
| } |
| |
| MinimumInputLength.prototype.query = function (decorated, params, callback) { |
| params.term = params.term || ''; |
| |
| if (params.term.length < this.minimumInputLength) { |
| this.trigger('results:message', { |
| message: 'inputTooShort', |
| args: { |
| minimum: this.minimumInputLength, |
| input: params.term, |
| params: params |
| } |
| }); |
| |
| return; |
| } |
| |
| decorated.call(this, params, callback); |
| }; |
| |
| return MinimumInputLength; |
| }); |
| |
| S2.define('select2/data/maximumInputLength',[ |
| |
| ], function () { |
| function MaximumInputLength (decorated, $e, options) { |
| this.maximumInputLength = options.get('maximumInputLength'); |
| |
| decorated.call(this, $e, options); |
| } |
| |
| MaximumInputLength.prototype.query = function (decorated, params, callback) { |
| params.term = params.term || ''; |
| |
| if (this.maximumInputLength > 0 && |
| params.term.length > this.maximumInputLength) { |
| this.trigger('results:message', { |
| message: 'inputTooLong', |
| args: { |
| maximum: this.maximumInputLength, |
| input: params.term, |
| params: params |
| } |
| }); |
| |
| return; |
| } |
| |
| decorated.call(this, params, callback); |
| }; |
| |
| return MaximumInputLength; |
| }); |
| |
| S2.define('select2/data/maximumSelectionLength',[ |
| |
| ], function (){ |
| function MaximumSelectionLength (decorated, $e, options) { |
| this.maximumSelectionLength = options.get('maximumSelectionLength'); |
| |
| decorated.call(this, $e, options); |
| } |
| |
| MaximumSelectionLength.prototype.query = |
| function (decorated, params, callback) { |
| var self = this; |
| |
| this.current(function (currentData) { |
| var count = currentData != null ? currentData.length : 0; |
| if (self.maximumSelectionLength > 0 && |
| count >= self.maximumSelectionLength) { |
| self.trigger('results:message', { |
| message: 'maximumSelected', |
| args: { |
| maximum: self.maximumSelectionLength |
| } |
| }); |
| return; |
| } |
| decorated.call(self, params, callback); |
| }); |
| }; |
| |
| return MaximumSelectionLength; |
| }); |
| |
| S2.define('select2/dropdown',[ |
| 'jquery', |
| './utils' |
| ], function ($, Utils) { |
| function Dropdown ($element, options) { |
| this.$element = $element; |
| this.options = options; |
| |
| Dropdown.__super__.constructor.call(this); |
| } |
| |
| Utils.Extend(Dropdown, Utils.Observable); |
| |
| Dropdown.prototype.render = function () { |
| var $dropdown = $( |
| '<span class="select2-dropdown">' + |
| '<span class="select2-results"></span>' + |
| '</span>' |
| ); |
| |
| $dropdown.attr('dir', this.options.get('dir')); |
| |
| this.$dropdown = $dropdown; |
| |
| return $dropdown; |
| }; |
| |
| Dropdown.prototype.bind = function () { |
| // Should be implemented in subclasses |
| }; |
| |
| Dropdown.prototype.position = function ($dropdown, $container) { |
| // Should be implmented in subclasses |
| }; |
| |
| Dropdown.prototype.destroy = function () { |
| // Remove the dropdown from the DOM |
| this.$dropdown.remove(); |
| }; |
| |
| return Dropdown; |
| }); |
| |
| S2.define('select2/dropdown/search',[ |
| 'jquery', |
| '../utils' |
| ], function ($, Utils) { |
| function Search () { } |
| |
| Search.prototype.render = function (decorated) { |
| var $rendered = decorated.call(this); |
| |
| var $search = $( |
| '<span class="select2-search select2-search--dropdown">' + |
| '<input class="select2-search__field" type="search" tabindex="-1"' + |
| ' autocomplete="off" autocorrect="off" autocapitalize="none"' + |
| ' spellcheck="false" role="textbox" />' + |
| '</span>' |
| ); |
| |
| this.$searchContainer = $search; |
| this.$search = $search.find('input'); |
| |
| $rendered.prepend($search); |
| |
| return $rendered; |
| }; |
| |
| Search.prototype.bind = function (decorated, container, $container) { |
| var self = this; |
| |
| decorated.call(this, container, $container); |
| |
| this.$search.on('keydown', function (evt) { |
| self.trigger('keypress', evt); |
| |
| self._keyUpPrevented = evt.isDefaultPrevented(); |
| }); |
| |
| // Workaround for browsers which do not support the `input` event |
| // This will prevent double-triggering of events for browsers which support |
| // both the `keyup` and `input` events. |
| this.$search.on('input', function (evt) { |
| // Unbind the duplicated `keyup` event |
| $(this).off('keyup'); |
| }); |
| |
| this.$search.on('keyup input', function (evt) { |
| self.handleSearch(evt); |
| }); |
| |
| container.on('open', function () { |
| self.$search.attr('tabindex', 0); |
| |
| self.$search.focus(); |
| |
| window.setTimeout(function () { |
| self.$search.focus(); |
| }, 0); |
| }); |
| |
| container.on('close', function () { |
| self.$search.attr('tabindex', -1); |
| |
| self.$search.val(''); |
| self.$search.blur(); |
| }); |
| |
| container.on('focus', function () { |
| if (!container.isOpen()) { |
| self.$search.focus(); |
| } |
| }); |
| |
| container.on('results:all', function (params) { |
| if (params.query.term == null || params.query.term === '') { |
| var showSearch = self.showSearch(params); |
| |
| if (showSearch) { |
| self.$searchContainer.removeClass('select2-search--hide'); |
| } else { |
| self.$searchContainer.addClass('select2-search--hide'); |
| } |
| } |
| }); |
| }; |
| |
| Search.prototype.handleSearch = function (evt) { |
| if (!this._keyUpPrevented) { |
| var input = this.$search.val(); |
| |
| this.trigger('query', { |
| term: input |
| }); |
| } |
| |
| this._keyUpPrevented = false; |
| }; |
| |
| Search.prototype.showSearch = function (_, params) { |
| return true; |
| }; |
| |
| return Search; |
| }); |
| |
| S2.define('select2/dropdown/hidePlaceholder',[ |
| |
| ], function () { |
| function HidePlaceholder (decorated, $element, options, dataAdapter) { |
| this.placeholder = this.normalizePlaceholder(options.get('placeholder')); |
| |
| decorated.call(this, $element, options, dataAdapter); |
| } |
| |
| HidePlaceholder.prototype.append = function (decorated, data) { |
| data.results = this.removePlaceholder(data.results); |
| |
| decorated.call(this, data); |
| }; |
| |
| HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) { |
| if (typeof placeholder === 'string') { |
| placeholder = { |
| id: '', |
| text: placeholder |
| }; |
| } |
| |
| return placeholder; |
| }; |
| |
| HidePlaceholder.prototype.removePlaceholder = function (_, data) { |
| var modifiedData = data.slice(0); |
| |
| for (var d = data.length - 1; d >= 0; d--) { |
| var item = data[d]; |
| |
| if (this.placeholder.id === item.id) { |
| modifiedData.splice(d, 1); |
| } |
| } |
| |
| return modifiedData; |
| }; |
| |
| return HidePlaceholder; |
| }); |
| |
| S2.define('select2/dropdown/infiniteScroll',[ |
| 'jquery' |
| ], function ($) { |
| function InfiniteScroll (decorated, $element, options, dataAdapter) { |
| this.lastParams = {}; |
| |
| decorated.call(this, $element, options, dataAdapter); |
| |
| this.$loadingMore = this.createLoadingMore(); |
| this.loading = false; |
| } |
| |
| InfiniteScroll.prototype.append = function (decorated, data) { |
| this.$loadingMore.remove(); |
| this.loading = false; |
| |
| decorated.call(this, data); |
| |
| if (this.showLoadingMore(data)) { |
| this.$results.append(this.$loadingMore); |
| } |
| }; |
| |
| InfiniteScroll.prototype.bind = function (decorated, container, $container) { |
| var self = this; |
| |
| decorated.call(this, container, $container); |
| |
| container.on('query', function (params) { |
| self.lastParams = params; |
| self.loading = true; |
| }); |
| |
| container.on('query:append', function (params) { |
| self.lastParams = params; |
| self.loading = true; |
| }); |
| |
| this.$results.on('scroll', function () { |
| var isLoadMoreVisible = $.contains( |
| document.documentElement, |
| self.$loadingMore[0] |
| ); |
| |
| if (self.loading || !isLoadMoreVisible) { |
| return; |
| } |
| |
| var currentOffset = self.$results.offset().top + |
| self.$results.outerHeight(false); |
| var loadingMoreOffset = self.$loadingMore.offset().top + |
| self.$loadingMore.outerHeight(false); |
| |
| if (currentOffset + 50 >= loadingMoreOffset) { |
| self.loadMore(); |
| } |
| }); |
| }; |
| |
| InfiniteScroll.prototype.loadMore = function () { |
| this.loading = true; |
| |
| var params = $.extend({}, {page: 1}, this.lastParams); |
| |
| params.page++; |
| |
| this.trigger('query:append', params); |
| }; |
| |
| InfiniteScroll.prototype.showLoadingMore = function (_, data) { |
| return data.pagination && data.pagination.more; |
| }; |
| |
| InfiniteScroll.prototype.createLoadingMore = function () { |
| var $option = $( |
| '<li ' + |
| 'class="select2-results__option select2-results__option--load-more"' + |
| 'role="treeitem" aria-disabled="true"></li>' |
| ); |
| |
| var message = this.options.get('translations').get('loadingMore'); |
| |
| $option.html(message(this.lastParams)); |
| |
| return $option; |
| }; |
| |
| return InfiniteScroll; |
| }); |
| |
| S2.define('select2/dropdown/attachBody',[ |
| 'jquery', |
| '../utils' |
| ], function ($, Utils) { |
| function AttachBody (decorated, $element, options) { |
| this.$dropdownParent = options.get('dropdownParent') || $(document.body); |
| |
| decorated.call(this, $element, options); |
| } |
| |
| AttachBody.prototype.bind = function (decorated, container, $container) { |
| var self = this; |
| |
| var setupResultsEvents = false; |
| |
| decorated.call(this, container, $container); |
| |
| container.on('open', function () { |
| self._showDropdown(); |
| self._attachPositioningHandler(container); |
| |
| if (!setupResultsEvents) { |
| setupResultsEvents = true; |
| |
| container.on('results:all', function () { |
| self._positionDropdown(); |
| self._resizeDropdown(); |
| }); |
| |
| container.on('results:append', function () { |
| self._positionDropdown(); |
| self._resizeDropdown(); |
| }); |
| } |
| }); |
| |
| container.on('close', function () { |
| self._hideDropdown(); |
| self._detachPositioningHandler(container); |
| }); |
| |
| this.$dropdownContainer.on('mousedown', function (evt) { |
| evt.stopPropagation(); |
| }); |
| }; |
| |
| AttachBody.prototype.destroy = function (decorated) { |
| decorated.call(this); |
| |
| this.$dropdownContainer.remove(); |
| }; |
| |
| AttachBody.prototype.position = function (decorated, $dropdown, $container) { |
| // Clone all of the container classes |
| $dropdown.attr('class', $container.attr('class')); |
| |
| $dropdown.removeClass('select2'); |
| $dropdown.addClass('select2-container--open'); |
| |
| $dropdown.css({ |
| position: 'absolute', |
| top: -999999 |
| }); |
| |
| this.$container = $container; |
| }; |
| |
| AttachBody.prototype.render = function (decorated) { |
| var $container = $('<span></span>'); |
| |
| var $dropdown = decorated.call(this); |
| $container.append($dropdown); |
| |
| this.$dropdownContainer = $container; |
| |
| return $container; |
| }; |
| |
| AttachBody.prototype._hideDropdown = function (decorated) { |
| this.$dropdownContainer.detach(); |
| }; |
| |
| AttachBody.prototype._attachPositioningHandler = |
| function (decorated, container) { |
| var self = this; |
| |
| var scrollEvent = 'scroll.select2.' + container.id; |
| var resizeEvent = 'resize.select2.' + container.id; |
| var orientationEvent = 'orientationchange.select2.' + container.id; |
| |
| var $watchers = this.$container.parents().filter(Utils.hasScroll); |
| $watchers.each(function () { |
| Utils.StoreData(this, 'select2-scroll-position', { |
| x: $(this).scrollLeft(), |
| y: $(this).scrollTop() |
| }); |
| }); |
| |
| $watchers.on(scrollEvent, function (ev) { |
| var position = Utils.GetData(this, 'select2-scroll-position'); |
| $(this).scrollTop(position.y); |
| }); |
| |
| $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent, |
| function (e) { |
| self._positionDropdown(); |
| self._resizeDropdown(); |
| }); |
| }; |
| |
| AttachBody.prototype._detachPositioningHandler = |
| function (decorated, container) { |
| var scrollEvent = 'scroll.select2.' + container.id; |
| var resizeEvent = 'resize.select2.' + container.id; |
| var orientationEvent = 'orientationchange.select2.' + container.id; |
| |
| var $watchers = this.$container.parents().filter(Utils.hasScroll); |
| $watchers.off(scrollEvent); |
| |
| $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent); |
| }; |
| |
| AttachBody.prototype._positionDropdown = function () { |
| var $window = $(window); |
| |
| var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above'); |
| var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below'); |
| |
| var newDirection = null; |
| |
| var offset = this.$container.offset(); |
| |
| offset.bottom = offset.top + this.$container.outerHeight(false); |
| |
| var container = { |
| height: this.$container.outerHeight(false) |
| }; |
| |
| container.top = offset.top; |
| container.bottom = offset.top + container.height; |
| |
| var dropdown = { |
| height: this.$dropdown.outerHeight(false) |
| }; |
| |
| var viewport = { |
| top: $window.scrollTop(), |
| bottom: $window.scrollTop() + $window.height() |
| }; |
| |
| var enoughRoomAbove = viewport.top < (offset.top - dropdown.height); |
| var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height); |
| |
| var css = { |
| left: offset.left, |
| top: container.bottom |
| }; |
| |
| // Determine what the parent element is to use for calciulating the offset |
| var $offsetParent = this.$dropdownParent; |
| |
| // For statically positoned elements, we need to get the element |
| // that is determining the offset |
| if ($offsetParent.css('position') === 'static') { |
| $offsetParent = $offsetParent.offsetParent(); |
| } |
| |
| var parentOffset = $offsetParent.offset(); |
| |
| css.top -= parentOffset.top; |
| css.left -= parentOffset.left; |
| |
| if (!isCurrentlyAbove && !isCurrentlyBelow) { |
| newDirection = 'below'; |
| } |
| |
| if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) { |
| newDirection = 'above'; |
| } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) { |
| newDirection = 'below'; |
| } |
| |
| if (newDirection == 'above' || |
| (isCurrentlyAbove && newDirection !== 'below')) { |
| css.top = container.top - parentOffset.top - dropdown.height; |
| } |
| |
| if (newDirection != null) { |
| this.$dropdown |
| .removeClass('select2-dropdown--below select2-dropdown--above') |
| .addClass('select2-dropdown--' + newDirection); |
| this.$container |
| .removeClass('select2-container--below select2-container--above') |
| .addClass('select2-container--' + newDirection); |
| } |
| |
| this.$dropdownContainer.css(css); |
| }; |
| |
| AttachBody.prototype._resizeDropdown = function () { |
| var css = { |
| width: this.$container.outerWidth(false) + 'px' |
| }; |
| |
| if (this.options.get('dropdownAutoWidth')) { |
| css.minWidth = css.width; |
| css.position = 'relative'; |
| css.width = 'auto'; |
| } |
| |
| this.$dropdown.css(css); |
| }; |
| |
| AttachBody.prototype._showDropdown = function (decorated) { |
| this.$dropdownContainer.appendTo(this.$dropdownParent); |
| |
| this._positionDropdown(); |
| this._resizeDropdown(); |
| }; |
| |
| return AttachBody; |
| }); |
| |
| S2.define('select2/dropdown/minimumResultsForSearch',[ |
| |
| ], function () { |
| function countResults (data) { |
| var count = 0; |
| |
| for (var d = 0; d < data.length; d++) { |
| var item = data[d]; |
| |
| if (item.children) { |
| count += countResults(item.children); |
| } else { |
| count++; |
| } |
| } |
| |
| return count; |
| } |
| |
| function MinimumResultsForSearch (decorated, $element, options, dataAdapter) { |
| this.minimumResultsForSearch = options.get('minimumResultsForSearch'); |
| |
| if (this.minimumResultsForSearch < 0) { |
| this.minimumResultsForSearch = Infinity; |
| } |
| |
| decorated.call(this, $element, options, dataAdapter); |
| } |
| |
| MinimumResultsForSearch.prototype.showSearch = function (decorated, params) { |
| if (countResults(params.data.results) < this.minimumResultsForSearch) { |
| return false; |
| } |
| |
| return decorated.call(this, params); |
| }; |
| |
| return MinimumResultsForSearch; |
| }); |
| |
| S2.define('select2/dropdown/selectOnClose',[ |
| '../utils' |
| ], function (Utils) { |
| function SelectOnClose () { } |
| |
| SelectOnClose.prototype.bind = function (decorated, container, $container) { |
| var self = this; |
| |
| decorated.call(this, container, $container); |
| |
| container.on('close', function (params) { |
| self._handleSelectOnClose(params); |
| }); |
| }; |
| |
| SelectOnClose.prototype._handleSelectOnClose = function (_, params) { |
| if (params && params.originalSelect2Event != null) { |
| var event = params.originalSelect2Event; |
| |
| // Don't select an item if the close event was triggered from a select or |
| // unselect event |
| if (event._type === 'select' || event._type === 'unselect') { |
| return; |
| } |
| } |
| |
| var $highlightedResults = this.getHighlightedResults(); |
| |
| // Only select highlighted results |
| if ($highlightedResults.length < 1) { |
| return; |
| } |
| |
| var data = Utils.GetData($highlightedResults[0], 'data'); |
| |
| // Don't re-select already selected resulte |
| if ( |
| (data.element != null && data.element.selected) || |
| (data.element == null && data.selected) |
| ) { |
| return; |
| } |
| |
| this.trigger('select', { |
| data: data |
| }); |
| }; |
| |
| return SelectOnClose; |
| }); |
| |
| S2.define('select2/dropdown/closeOnSelect',[ |
| |
| ], function () { |
| function CloseOnSelect () { } |
| |
| CloseOnSelect.prototype.bind = function (decorated, container, $container) { |
| var self = this; |
| |
| decorated.call(this, container, $container); |
| |
| container.on('select', function (evt) { |
| self._selectTriggered(evt); |
| }); |
| |
| container.on('unselect', function (evt) { |
| self._selectTriggered(evt); |
| }); |
| }; |
| |
| CloseOnSelect.prototype._selectTriggered = function (_, evt) { |
| var originalEvent = evt.originalEvent; |
| |
| // Don't close if the control key is being held |
| if (originalEvent && originalEvent.ctrlKey) { |
| return; |
| } |
| |
| this.trigger('close', { |
| originalEvent: originalEvent, |
| originalSelect2Event: evt |
| }); |
| }; |
| |
| return CloseOnSelect; |
| }); |
| |
| S2.define('select2/i18n/en',[],function () { |
| // English |
| return { |
| errorLoading: function () { |
| return 'The results could not be loaded.'; |
| }, |
| inputTooLong: function (args) { |
| var overChars = args.input.length - args.maximum; |
| |
| var message = 'Please delete ' + overChars + ' character'; |
| |
| if (overChars != 1) { |
| message += 's'; |
| } |
| |
| return message; |
| }, |
| inputTooShort: function (args) { |
| var remainingChars = args.minimum - args.input.length; |
| |
| var message = 'Please enter ' + remainingChars + ' or more characters'; |
| |
| return message; |
| }, |
| loadingMore: function () { |
| return 'Loading more results…'; |
| }, |
| maximumSelected: function (args) { |
| var message = 'You can only select ' + args.maximum + ' item'; |
| |
| if (args.maximum != 1) { |
| message += 's'; |
| } |
| |
| return message; |
| }, |
| noResults: function () { |
| return 'No results found'; |
| }, |
| searching: function () { |
| return 'Searching…'; |
| } |
| }; |
| }); |
| |
| S2.define('select2/defaults',[ |
| 'jquery', |
| 'require', |
| |
| './results', |
| |
| './selection/single', |
| './selection/multiple', |
| './selection/placeholder', |
| './selection/allowClear', |
| './selection/search', |
| './selection/eventRelay', |
| |
| './utils', |
| './translation', |
| './diacritics', |
| |
| './data/select', |
| './data/array', |
| './data/ajax', |
| './data/tags', |
| './data/tokenizer', |
| './data/minimumInputLength', |
| './data/maximumInputLength', |
| './data/maximumSelectionLength', |
| |
| './dropdown', |
| './dropdown/search', |
| './dropdown/hidePlaceholder', |
| './dropdown/infiniteScroll', |
| './dropdown/attachBody', |
| './dropdown/minimumResultsForSearch', |
| './dropdown/selectOnClose', |
| './dropdown/closeOnSelect', |
| |
| './i18n/en' |
| ], function ($, require, |
| |
| ResultsList, |
| |
| SingleSelection, MultipleSelection, Placeholder, AllowClear, |
| SelectionSearch, EventRelay, |
| |
| Utils, Translation, DIACRITICS, |
| |
| SelectData, ArrayData, AjaxData, Tags, Tokenizer, |
| MinimumInputLength, MaximumInputLength, MaximumSelectionLength, |
| |
| Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll, |
| AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect, |
| |
| EnglishTranslation) { |
| function Defaults () { |
| this.reset(); |
| } |
| |
| Defaults.prototype.apply = function (options) { |
| options = $.extend(true, {}, this.defaults, options); |
| |
| if (options.dataAdapter == null) { |
| if (options.ajax != null) { |
| options.dataAdapter = AjaxData; |
| } else if (options.data != null) { |
| options.dataAdapter = ArrayData; |
| } else { |
| options.dataAdapter = SelectData; |
| } |
| |
| if (options.minimumInputLength > 0) { |
| options.dataAdapter = Utils.Decorate( |
| options.dataAdapter, |
| MinimumInputLength |
| ); |
| } |
| |
| if (options.maximumInputLength > 0) { |
| options.dataAdapter = Utils.Decorate( |
| options.dataAdapter, |
| MaximumInputLength |
| ); |
| } |
| |
| if (options.maximumSelectionLength > 0) { |
| options.dataAdapter = Utils.Decorate( |
| options.dataAdapter, |
| MaximumSelectionLength |
| ); |
| } |
| |
| if (options.tags) { |
| options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags); |
| } |
| |
| if (options.tokenSeparators != null || options.tokenizer != null) { |
| options.dataAdapter = Utils.Decorate( |
| options.dataAdapter, |
| Tokenizer |
| ); |
| } |
| |
| if (options.query != null) { |
| var Query = require(options.amdBase + 'compat/query'); |
| |
| options.dataAdapter = Utils.Decorate( |
| options.dataAdapter, |
| Query |
| ); |
| } |
| |
| if (options.initSelection != null) { |
| var InitSelection = require(options.amdBase + 'compat/initSelection'); |
| |
| options.dataAdapter = Utils.Decorate( |
| options.dataAdapter, |
| InitSelection |
| ); |
| } |
| } |
| |
| if (options.resultsAdapter == null) { |
| options.resultsAdapter = ResultsList; |
| |
| if (options.ajax != null) { |
| options.resultsAdapter = Utils.Decorate( |
| options.resultsAdapter, |
| InfiniteScroll |
| ); |
| } |
| |
| if (options.placeholder != null) { |
| options.resultsAdapter = Utils.Decorate( |
| options.resultsAdapter, |
| HidePlaceholder |
| ); |
| } |
| |
| if (options.selectOnClose) { |
| options.resultsAdapter = Utils.Decorate( |
| options.resultsAdapter, |
| SelectOnClose |
| ); |
| } |
| } |
| |
| if (options.dropdownAdapter == null) { |
| if (options.multiple) { |
| options.dropdownAdapter = Dropdown; |
| } else { |
| var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch); |
| |
| options.dropdownAdapter = SearchableDropdown; |
| } |
| |
| if (options.minimumResultsForSearch !== 0) { |
| options.dropdownAdapter = Utils.Decorate( |
| options.dropdownAdapter, |
| MinimumResultsForSearch |
| ); |
| } |
| |
| if (options.closeOnSelect) { |
| options.dropdownAdapter = Utils.Decorate( |
| options.dropdownAdapter, |
| CloseOnSelect |
| ); |
| } |
| |
| if ( |
| options.dropdownCssClass != null || |
| options.dropdownCss != null || |
| options.adaptDropdownCssClass != null |
| ) { |
| var DropdownCSS = require(options.amdBase + 'compat/dropdownCss'); |
| |
| options.dropdownAdapter = Utils.Decorate( |
| options.dropdownAdapter, |
| DropdownCSS |
| ); |
| } |
| |
| options.dropdownAdapter = Utils.Decorate( |
| options.dropdownAdapter, |
| AttachBody |
| ); |
| } |
| |
| if (options.selectionAdapter == null) { |
| if (options.multiple) { |
| options.selectionAdapter = MultipleSelection; |
| } else { |
| options.selectionAdapter = SingleSelection; |
| } |
| |
| // Add the placeholder mixin if a placeholder was specified |
| if (options.placeholder != null) { |
| options.selectionAdapter = Utils.Decorate( |
| options.selectionAdapter, |
| Placeholder |
| ); |
| } |
| |
| if (options.allowClear) { |
| options.selectionAdapter = Utils.Decorate( |
| options.selectionAdapter, |
| AllowClear |
| ); |
| } |
| |
| if (options.multiple) { |
| options.selectionAdapter = Utils.Decorate( |
| options.selectionAdapter, |
| SelectionSearch |
| ); |
| } |
| |
| if ( |
| options.containerCssClass != null || |
| options.containerCss != null || |
| options.adaptContainerCssClass != null |
| ) { |
| var ContainerCSS = require(options.amdBase + 'compat/containerCss'); |
| |
| options.selectionAdapter = Utils.Decorate( |
| options.selectionAdapter, |
| ContainerCSS |
| ); |
| } |
| |
| options.selectionAdapter = Utils.Decorate( |
| options.selectionAdapter, |
| EventRelay |
| ); |
| } |
| |
| if (typeof options.language === 'string') { |
| // Check if the language is specified with a region |
| if (options.language.indexOf('-') > 0) { |
| // Extract the region information if it is included |
| var languageParts = options.language.split('-'); |
| var baseLanguage = languageParts[0]; |
| |
| options.language = [options.language, baseLanguage]; |
| } else { |
| options.language = [options.language]; |
| } |
| } |
| |
| if ($.isArray(options.language)) { |
| var languages = new Translation(); |
| options.language.push('en'); |
| |
| var languageNames = options.language; |
| |
| for (var l = 0; l < languageNames.length; l++) { |
| var name = languageNames[l]; |
| var language = {}; |
| |
| try { |
| // Try to load it with the original name |
| language = Translation.loadPath(name); |
| } catch (e) { |
| try { |
| // If we couldn't load it, check if it wasn't the full path |
| name = this.defaults.amdLanguageBase + name; |
| language = Translation.loadPath(name); |
| } catch (ex) { |
| // The translation could not be loaded at all. Sometimes this is |
| // because of a configuration problem, other times this can be |
| // because of how Select2 helps load all possible translation files. |
| if (options.debug && window.console && console.warn) { |
| console.warn( |
| 'Select2: The language file for "' + name + '" could not be ' + |
| 'automatically loaded. A fallback will be used instead.' |
| ); |
| } |
| |
| continue; |
| } |
| } |
| |
| languages.extend(language); |
| } |
| |
| options.translations = languages; |
| } else { |
| var baseTranslation = Translation.loadPath( |
| this.defaults.amdLanguageBase + 'en' |
| ); |
| var customTranslation = new Translation(options.language); |
| |
| customTranslation.extend(baseTranslation); |
| |
| options.translations = customTranslation; |
| } |
| |
| return options; |
| }; |
| |
| Defaults.prototype.reset = function () { |
| function stripDiacritics (text) { |
| // Used 'uni range + named function' from http://jsperf.com/diacritics/18 |
| function match(a) { |
| return DIACRITICS[a] || a; |
| } |
| |
| return text.replace(/[^\u0000-\u007E]/g, match); |
| } |
| |
| function matcher (params, data) { |
| // Always return the object if there is nothing to compare |
| if ($.trim(params.term) === '') { |
| return data; |
| } |
| |
| // Do a recursive check for options with children |
| if (data.children && data.children.length > 0) { |
| // Clone the data object if there are children |
| // This is required as we modify the object to remove any non-matches |
| var match = $.extend(true, {}, data); |
| |
| // Check each child of the option |
| for (var c = data.children.length - 1; c >= 0; c--) { |
| var child = data.children[c]; |
| |
| var matches = matcher(params, child); |
| |
| // If there wasn't a match, remove the object in the array |
| if (matches == null) { |
| match.children.splice(c, 1); |
| } |
| } |
| |
| // If any children matched, return the new object |
| if (match.children.length > 0) { |
| return match; |
| } |
| |
| // If there were no matching children, check just the plain object |
| return matcher(params, match); |
| } |
| |
| var original = stripDiacritics(data.text).toUpperCase(); |
| var term = stripDiacritics(params.term).toUpperCase(); |
| |
| // Check if the text contains the term |
| if (original.indexOf(term) > -1) { |
| return data; |
| } |
| |
| // If it doesn't contain the term, don't return anything |
| return null; |
| } |
| |
| this.defaults = { |
| amdBase: './', |
| amdLanguageBase: './i18n/', |
| closeOnSelect: true, |
| debug: false, |
| dropdownAutoWidth: false, |
| escapeMarkup: Utils.escapeMarkup, |
| language: EnglishTranslation, |
| matcher: matcher, |
| minimumInputLength: 0, |
| maximumInputLength: 0, |
| maximumSelectionLength: 0, |
| minimumResultsForSearch: 0, |
| selectOnClose: false, |
| sorter: function (data) { |
| return data; |
| }, |
| templateResult: function (result) { |
| return result.text; |
| }, |
| templateSelection: function (selection) { |
| return selection.text; |
| }, |
| theme: 'default', |
| width: 'resolve' |
| }; |
| }; |
| |
| Defaults.prototype.set = function (key, value) { |
| var camelKey = $.camelCase(key); |
| |
| var data = {}; |
| data[camelKey] = value; |
| |
| var convertedData = Utils._convertData(data); |
| |
| $.extend(true, this.defaults, convertedData); |
| }; |
| |
| var defaults = new Defaults(); |
| |
| return defaults; |
| }); |
| |
| S2.define('select2/options',[ |
| 'require', |
| 'jquery', |
| './defaults', |
| './utils' |
| ], function (require, $, Defaults, Utils) { |
| function Options (options, $element) { |
| this.options = options; |
| |
| if ($element != null) { |
| this.fromElement($element); |
| } |
| |
| this.options = Defaults.apply(this.options); |
| |
| if ($element && $element.is('input')) { |
| var InputCompat = require(this.get('amdBase') + 'compat/inputData'); |
| |
| this.options.dataAdapter = Utils.Decorate( |
| this.options.dataAdapter, |
| InputCompat |
| ); |
| } |
| } |
| |
| Options.prototype.fromElement = function ($e) { |
| var excludedData = ['select2']; |
| |
| if (this.options.multiple == null) { |
| this.options.multiple = $e.prop('multiple'); |
| } |
| |
| if (this.options.disabled == null) { |
| this.options.disabled = $e.prop('disabled'); |
| } |
| |
| if (this.options.language == null) { |
| if ($e.prop('lang')) { |
| this.options.language = $e.prop('lang').toLowerCase(); |
| } else if ($e.closest('[lang]').prop('lang')) { |
| this.options.language = $e.closest('[lang]').prop('lang'); |
| } |
| } |
| |
| if (this.options.dir == null) { |
| if ($e.prop('dir')) { |
| this.options.dir = $e.prop('dir'); |
| } else if ($e.closest('[dir]').prop('dir')) { |
| this.options.dir = $e.closest('[dir]').prop('dir'); |
| } else { |
| this.options.dir = 'ltr'; |
| } |
| } |
| |
| $e.prop('disabled', this.options.disabled); |
| $e.prop('multiple', this.options.multiple); |
| |
| if (Utils.GetData($e[0], 'select2Tags')) { |
| if (this.options.debug && window.console && console.warn) { |
| console.warn( |
| 'Select2: The `data-select2-tags` attribute has been changed to ' + |
| 'use the `data-data` and `data-tags="true"` attributes and will be ' + |
| 'removed in future versions of Select2.' |
| ); |
| } |
| |
| Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags')); |
| Utils.StoreData($e[0], 'tags', true); |
| } |
| |
| if (Utils.GetData($e[0], 'ajaxUrl')) { |
| if (this.options.debug && window.console && console.warn) { |
| console.warn( |
| 'Select2: The `data-ajax-url` attribute has been changed to ' + |
| '`data-ajax--url` and support for the old attribute will be removed' + |
| ' in future versions of Select2.' |
| ); |
| } |
| |
| $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl')); |
| Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl')); |
| |
| } |
| |
| var dataset = {}; |
| |
| // Prefer the element's `dataset` attribute if it exists |
| // jQuery 1.x does not correctly handle data attributes with multiple dashes |
| if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) { |
| dataset = $.extend(true, {}, $e[0].dataset, Utils.GetData($e[0])); |
| } else { |
| dataset = Utils.GetData($e[0]); |
| } |
| |
| var data = $.extend(true, {}, dataset); |
| |
| data = Utils._convertData(data); |
| |
| for (var key in data) { |
| if ($.inArray(key, excludedData) > -1) { |
| continue; |
| } |
| |
| if ($.isPlainObject(this.options[key])) { |
| $.extend(this.options[key], data[key]); |
| } else { |
| this.options[key] = data[key]; |
| } |
| } |
| |
| return this; |
| }; |
| |
| Options.prototype.get = function (key) { |
| return this.options[key]; |
| }; |
| |
| Options.prototype.set = function (key, val) { |
| this.options[key] = val; |
| }; |
| |
| return Options; |
| }); |
| |
| S2.define('select2/core',[ |
| 'jquery', |
| './options', |
| './utils', |
| './keys' |
| ], function ($, Options, Utils, KEYS) { |
| var Select2 = function ($element, options) { |
| if (Utils.GetData($element[0], 'select2') != null) { |
| Utils.GetData($element[0], 'select2').destroy(); |
| } |
| |
| this.$element = $element; |
| |
| this.id = this._generateId($element); |
| |
| options = options || {}; |
| |
| this.options = new Options(options, $element); |
| |
| Select2.__super__.constructor.call(this); |
| |
| // Set up the tabindex |
| |
| var tabindex = $element.attr('tabindex') || 0; |
| Utils.StoreData($element[0], 'old-tabindex', tabindex); |
| $element.attr('tabindex', '-1'); |
| |
| // Set up containers and adapters |
| |
| var DataAdapter = this.options.get('dataAdapter'); |
| this.dataAdapter = new DataAdapter($element, this.options); |
| |
| var $container = this.render(); |
| |
| this._placeContainer($container); |
| |
| var SelectionAdapter = this.options.get('selectionAdapter'); |
| this.selection = new SelectionAdapter($element, this.options); |
| this.$selection = this.selection.render(); |
| |
| this.selection.position(this.$selection, $container); |
| |
| var DropdownAdapter = this.options.get('dropdownAdapter'); |
| this.dropdown = new DropdownAdapter($element, this.options); |
| this.$dropdown = this.dropdown.render(); |
| |
| this.dropdown.position(this.$dropdown, $container); |
| |
| var ResultsAdapter = this.options.get('resultsAdapter'); |
| this.results = new ResultsAdapter($element, this.options, this.dataAdapter); |
| this.$results = this.results.render(); |
| |
| this.results.position(this.$results, this.$dropdown); |
| |
| // Bind events |
| |
| var self = this; |
| |
| // Bind the container to all of the adapters |
| this._bindAdapters(); |
| |
| // Register any DOM event handlers |
| this._registerDomEvents(); |
| |
| // Register any internal event handlers |
| this._registerDataEvents(); |
| this._registerSelectionEvents(); |
| this._registerDropdownEvents(); |
| this._registerResultsEvents(); |
| this._registerEvents(); |
| |
| // Set the initial state |
| this.dataAdapter.current(function (initialData) { |
| self.trigger('selection:update', { |
| data: initialData |
| }); |
| }); |
| |
| // Hide the original select |
| $element.addClass('select2-hidden-accessible'); |
| $element.attr('aria-hidden', 'true'); |
| |
| // Synchronize any monitored attributes |
| this._syncAttributes(); |
| |
| Utils.StoreData($element[0], 'select2', this); |
| |
| // Ensure backwards compatibility with $element.data('select2'). |
| $element.data('select2', this); |
| }; |
| |
| Utils.Extend(Select2, Utils.Observable); |
| |
| Select2.prototype._generateId = function ($element) { |
| var id = ''; |
| |
| if ($element.attr('id') != null) { |
| id = $element.attr('id'); |
| } else if ($element.attr('name') != null) { |
| id = $element.attr('name') + '-' + Utils.generateChars(2); |
| } else { |
| id = Utils.generateChars(4); |
| } |
| |
| id = id.replace(/(:|\.|\[|\]|,)/g, ''); |
| id = 'select2-' + id; |
| |
| return id; |
| }; |
| |
| Select2.prototype._placeContainer = function ($container) { |
| $container.insertAfter(this.$element); |
| |
| var width = this._resolveWidth(this.$element, this.options.get('width')); |
| |
| if (width != null) { |
| $container.css('width', width); |
| } |
| }; |
| |
| Select2.prototype._resolveWidth = function ($element, method) { |
| var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i; |
| |
| if (method == 'resolve') { |
| var styleWidth = this._resolveWidth($element, 'style'); |
| |
| if (styleWidth != null) { |
| return styleWidth; |
| } |
| |
| return this._resolveWidth($element, 'element'); |
| } |
| |
| if (method == 'element') { |
| var elementWidth = $element.outerWidth(false); |
| |
| if (elementWidth <= 0) { |
| return 'auto'; |
| } |
| |
| return elementWidth + 'px'; |
| } |
| |
| if (method == 'style') { |
| var style = $element.attr('style'); |
| |
| if (typeof(style) !== 'string') { |
| return null; |
| } |
| |
| var attrs = style.split(';'); |
| |
| for (var i = 0, l = attrs.length; i < l; i = i + 1) { |
| var attr = attrs[i].replace(/\s/g, ''); |
| var matches = attr.match(WIDTH); |
| |
| if (matches !== null && matches.length >= 1) { |
| return matches[1]; |
| } |
| } |
| |
| return null; |
| } |
| |
| return method; |
| }; |
| |
| Select2.prototype._bindAdapters = function () { |
| this.dataAdapter.bind(this, this.$container); |
| this.selection.bind(this, this.$container); |
| |
| this.dropdown.bind(this, this.$container); |
| this.results.bind(this, this.$container); |
| }; |
| |
| Select2.prototype._registerDomEvents = function () { |
| var self = this; |
| |
| this.$element.on('change.select2', function () { |
| self.dataAdapter.current(function (data) { |
| self.trigger('selection:update', { |
| data: data |
| }); |
| }); |
| }); |
| |
| this.$element.on('focus.select2', function (evt) { |
| self.trigger('focus', evt); |
| }); |
| |
| this._syncA = Utils.bind(this._syncAttributes, this); |
| this._syncS = Utils.bind(this._syncSubtree, this); |
| |
| if (this.$element[0].attachEvent) { |
| this.$element[0].attachEvent('onpropertychange', this._syncA); |
| } |
| |
| var observer = window.MutationObserver || |
| window.WebKitMutationObserver || |
| window.MozMutationObserver |
| ; |
| |
| if (observer != null) { |
| this._observer = new observer(function (mutations) { |
| $.each(mutations, self._syncA); |
| $.each(mutations, self._syncS); |
| }); |
| this._observer.observe(this.$element[0], { |
| attributes: true, |
| childList: true, |
| subtree: false |
| }); |
| } else if (this.$element[0].addEventListener) { |
| this.$element[0].addEventListener( |
| 'DOMAttrModified', |
| self._syncA, |
| false |
| ); |
| this.$element[0].addEventListener( |
| 'DOMNodeInserted', |
| self._syncS, |
| false |
| ); |
| this.$element[0].addEventListener( |
| 'DOMNodeRemoved', |
| self._syncS, |
| false |
| ); |
| } |
| }; |
| |
| Select2.prototype._registerDataEvents = function () { |
| var self = this; |
| |
| this.dataAdapter.on('*', function (name, params) { |
| self.trigger(name, params); |
| }); |
| }; |
| |
| Select2.prototype._registerSelectionEvents = function () { |
| var self = this; |
| var nonRelayEvents = ['toggle', 'focus']; |
| |
| this.selection.on('toggle', function () { |
| self.toggleDropdown(); |
| }); |
| |
| this.selection.on('focus', function (params) { |
| self.focus(params); |
| }); |
| |
| this.selection.on('*', function (name, params) { |
| if ($.inArray(name, nonRelayEvents) !== -1) { |
| return; |
| } |
| |
| self.trigger(name, params); |
| }); |
| }; |
| |
| Select2.prototype._registerDropdownEvents = function () { |
| var self = this; |
| |
| this.dropdown.on('*', function (name, params) { |
| self.trigger(name, params); |
| }); |
| }; |
| |
| Select2.prototype._registerResultsEvents = function () { |
| var self = this; |
| |
| this.results.on('*', function (name, params) { |
| self.trigger(name, params); |
| }); |
| }; |
| |
| Select2.prototype._registerEvents = function () { |
| var self = this; |
| |
| this.on('open', function () { |
| self.$container.addClass('select2-container--open'); |
| }); |
| |
| this.on('close', function () { |
| self.$container.removeClass('select2-container--open'); |
| }); |
| |
| this.on('enable', function () { |
| self.$container.removeClass('select2-container--disabled'); |
| }); |
| |
| this.on('disable', function () { |
| self.$container.addClass('select2-container--disabled'); |
| }); |
| |
| this.on('blur', function () { |
| self.$container.removeClass('select2-container--focus'); |
| }); |
| |
| this.on('query', function (params) { |
| if (!self.isOpen()) { |
| self.trigger('open', {}); |
| } |
| |
| this.dataAdapter.query(params, function (data) { |
| self.trigger('results:all', { |
| data: data, |
| query: params |
| }); |
| }); |
| }); |
| |
| this.on('query:append', function (params) { |
| this.dataAdapter.query(params, function (data) { |
| self.trigger('results:append', { |
| data: data, |
| query: params |
| }); |
| }); |
| }); |
| |
| this.on('keypress', function (evt) { |
| var key = evt.which; |
| |
| if (self.isOpen()) { |
| if (key === KEYS.ESC || key === KEYS.TAB || |
| (key === KEYS.UP && evt.altKey)) { |
| self.close(); |
| |
| evt.preventDefault(); |
| } else if (key === KEYS.ENTER) { |
| self.trigger('results:select', {}); |
| |
| evt.preventDefault(); |
| } else if ((key === KEYS.SPACE && evt.ctrlKey)) { |
| self.trigger('results:toggle', {}); |
| |
| evt.preventDefault(); |
| } else if (key === KEYS.UP) { |
| self.trigger('results:previous', {}); |
| |
| evt.preventDefault(); |
| } else if (key === KEYS.DOWN) { |
| self.trigger('results:next', {}); |
| |
| evt.preventDefault(); |
| } |
| } else { |
| if (key === KEYS.ENTER || key === KEYS.SPACE || |
| (key === KEYS.DOWN && evt.altKey)) { |
| self.open(); |
| |
| evt.preventDefault(); |
| } |
| } |
| }); |
| }; |
| |
| Select2.prototype._syncAttributes = function () { |
| this.options.set('disabled', this.$element.prop('disabled')); |
| |
| if (this.options.get('disabled')) { |
| if (this.isOpen()) { |
| this.close(); |
| } |
| |
| this.trigger('disable', {}); |
| } else { |
| this.trigger('enable', {}); |
| } |
| }; |
| |
| Select2.prototype._syncSubtree = function (evt, mutations) { |
| var changed = false; |
| var self = this; |
| |
| // Ignore any mutation events raised for elements that aren't options or |
| // optgroups. This handles the case when the select element is destroyed |
| if ( |
| evt && evt.target && ( |
| evt.target.nodeName !== 'OPTION' && evt.target.nodeName !== 'OPTGROUP' |
| ) |
| ) { |
| return; |
| } |
| |
| if (!mutations) { |
| // If mutation events aren't supported, then we can only assume that the |
| // change affected the selections |
| changed = true; |
| } else if (mutations.addedNodes && mutations.addedNodes.length > 0) { |
| for (var n = 0; n < mutations.addedNodes.length; n++) { |
| var node = mutations.addedNodes[n]; |
| |
| if (node.selected) { |
| changed = true; |
| } |
| } |
| } else if (mutations.removedNodes && mutations.removedNodes.length > 0) { |
| changed = true; |
| } |
| |
| // Only re-pull the data if we think there is a change |
| if (changed) { |
| this.dataAdapter.current(function (currentData) { |
| self.trigger('selection:update', { |
| data: currentData |
| }); |
| }); |
| } |
| }; |
| |
| /** |
| * Override the trigger method to automatically trigger pre-events when |
| * there are events that can be prevented. |
| */ |
| Select2.prototype.trigger = function (name, args) { |
| var actualTrigger = Select2.__super__.trigger; |
| var preTriggerMap = { |
| 'open': 'opening', |
| 'close': 'closing', |
| 'select': 'selecting', |
| 'unselect': 'unselecting', |
| 'clear': 'clearing' |
| }; |
| |
| if (args === undefined) { |
| args = {}; |
| } |
| |
| if (name in preTriggerMap) { |
| var preTriggerName = preTriggerMap[name]; |
| var preTriggerArgs = { |
| prevented: false, |
| name: name, |
| args: args |
| }; |
| |
| actualTrigger.call(this, preTriggerName, preTriggerArgs); |
| |
| if (preTriggerArgs.prevented) { |
| args.prevented = true; |
| |
| return; |
| } |
| } |
| |
| actualTrigger.call(this, name, args); |
| }; |
| |
| Select2.prototype.toggleDropdown = function () { |
| if (this.options.get('disabled')) { |
| return; |
| } |
| |
| if (this.isOpen()) { |
| this.close(); |
| } else { |
| this.open(); |
| } |
| }; |
| |
| Select2.prototype.open = function () { |
| if (this.isOpen()) { |
| return; |
| } |
| |
| this.trigger('query', {}); |
| }; |
| |
| Select2.prototype.close = function () { |
| if (!this.isOpen()) { |
| return; |
| } |
| |
| this.trigger('close', {}); |
| }; |
| |
| Select2.prototype.isOpen = function () { |
| return this.$container.hasClass('select2-container--open'); |
| }; |
| |
| Select2.prototype.hasFocus = function () { |
| return this.$container.hasClass('select2-container--focus'); |
| }; |
| |
| Select2.prototype.focus = function (data) { |
| // No need to re-trigger focus events if we are already focused |
| if (this.hasFocus()) { |
| return; |
| } |
| |
| this.$container.addClass('select2-container--focus'); |
| this.trigger('focus', {}); |
| }; |
| |
| Select2.prototype.enable = function (args) { |
| if (this.options.get('debug') && window.console && console.warn) { |
| console.warn( |
| 'Select2: The `select2("enable")` method has been deprecated and will' + |
| ' be removed in later Select2 versions. Use $element.prop("disabled")' + |
| ' instead.' |
| ); |
| } |
| |
| if (args == null || args.length === 0) { |
| args = [true]; |
| } |
| |
| var disabled = !args[0]; |
| |
| this.$element.prop('disabled', disabled); |
| }; |
| |
| Select2.prototype.data = function () { |
| if (this.options.get('debug') && |
| arguments.length > 0 && window.console && console.warn) { |
| console.warn( |
| 'Select2: Data can no longer be set using `select2("data")`. You ' + |
| 'should consider setting the value instead using `$element.val()`.' |
| ); |
| } |
| |
| var data = []; |
| |
| this.dataAdapter.current(function (currentData) { |
| data = currentData; |
| }); |
| |
| return data; |
| }; |
| |
| Select2.prototype.val = function (args) { |
| if (this.options.get('debug') && window.console && console.warn) { |
| console.warn( |
| 'Select2: The `select2("val")` method has been deprecated and will be' + |
| ' removed in later Select2 versions. Use $element.val() instead.' |
| ); |
| } |
| |
| if (args == null || args.length === 0) { |
| return this.$element.val(); |
| } |
| |
| var newVal = args[0]; |
| |
| if ($.isArray(newVal)) { |
| newVal = $.map(newVal, function (obj) { |
| return obj.toString(); |
| }); |
| } |
| |
| this.$element.val(newVal).trigger('change'); |
| }; |
| |
| Select2.prototype.destroy = function () { |
| this.$container.remove(); |
| |
| if (this.$element[0].detachEvent) { |
| this.$element[0].detachEvent('onpropertychange', this._syncA); |
| } |
| |
| if (this._observer != null) { |
| this._observer.disconnect(); |
| this._observer = null; |
| } else if (this.$element[0].removeEventListener) { |
| this.$element[0] |
| .removeEventListener('DOMAttrModified', this._syncA, false); |
| this.$element[0] |
| .removeEventListener('DOMNodeInserted', this._syncS, false); |
| this.$element[0] |
| .removeEventListener('DOMNodeRemoved', this._syncS, false); |
| } |
| |
| this._syncA = null; |
| this._syncS = null; |
| |
| this.$element.off('.select2'); |
| this.$element.attr('tabindex', |
| Utils.GetData(this.$element[0], 'old-tabindex')); |
| |
| this.$element.removeClass('select2-hidden-accessible'); |
| this.$element.attr('aria-hidden', 'false'); |
| Utils.RemoveData(this.$element[0]); |
| this.$element.removeData('select2'); |
| |
| this.dataAdapter.destroy(); |
| this.selection.destroy(); |
| this.dropdown.destroy(); |
| this.results.destroy(); |
| |
| this.dataAdapter = null; |
| this.selection = null; |
| this.dropdown = null; |
| this.results = null; |
| }; |
| |
| Select2.prototype.render = function () { |
| var $container = $( |
| '<span class="select2 select2-container">' + |
| '<span class="selection"></span>' + |
| '<span class="dropdown-wrapper" aria-hidden="true"></span>' + |
| '</span>' |
| ); |
| |
| $container.attr('dir', this.options.get('dir')); |
| |
| this.$container = $container; |
| |
| this.$container.addClass('select2-container--' + this.options.get('theme')); |
| |
| Utils.StoreData($container[0], 'element', this.$element); |
| |
| return $container; |
| }; |
| |
| return Select2; |
| }); |
| |
| S2.define('select2/compat/utils',[ |
| 'jquery' |
| ], function ($) { |
| function syncCssClasses ($dest, $src, adapter) { |
| var classes, replacements = [], adapted; |
| |
| classes = $.trim($dest.attr('class')); |
| |
| if (classes) { |
| classes = '' + classes; // for IE which returns object |
| |
| $(classes.split(/\s+/)).each(function () { |
| // Save all Select2 classes |
| if (this.indexOf('select2-') === 0) { |
| replacements.push(this); |
| } |
| }); |
| } |
| |
| classes = $.trim($src.attr('class')); |
| |
| if (classes) { |
| classes = '' + classes; // for IE which returns object |
| |
| $(classes.split(/\s+/)).each(function () { |
| // Only adapt non-Select2 classes |
| if (this.indexOf('select2-') !== 0) { |
| adapted = adapter(this); |
| |
| if (adapted != null) { |
| replacements.push(adapted); |
| } |
| } |
| }); |
| } |
| |
| $dest.attr('class', replacements.join(' ')); |
| } |
| |
| return { |
| syncCssClasses: syncCssClasses |
| }; |
| }); |
| |
| S2.define('select2/compat/containerCss',[ |
| 'jquery', |
| './utils' |
| ], function ($, CompatUtils) { |
| // No-op CSS adapter that discards all classes by default |
| function _containerAdapter (clazz) { |
| return null; |
| } |
| |
| function ContainerCSS () { } |
| |
| ContainerCSS.prototype.render = function (decorated) { |
| var $container = decorated.call(this); |
| |
| var containerCssClass = this.options.get('containerCssClass') || ''; |
| |
| if ($.isFunction(containerCssClass)) { |
| containerCssClass = containerCssClass(this.$element); |
| } |
| |
| var containerCssAdapter = this.options.get('adaptContainerCssClass'); |
| containerCssAdapter = containerCssAdapter || _containerAdapter; |
| |
| if (containerCssClass.indexOf(':all:') !== -1) { |
| containerCssClass = containerCssClass.replace(':all:', ''); |
| |
| var _cssAdapter = containerCssAdapter; |
| |
| containerCssAdapter = function (clazz) { |
| var adapted = _cssAdapter(clazz); |
| |
| if (adapted != null) { |
| // Append the old one along with the adapted one |
| return adapted + ' ' + clazz; |
| } |
| |
| return clazz; |
| }; |
| } |
| |
| var containerCss = this.options.get('containerCss') || {}; |
| |
| if ($.isFunction(containerCss)) { |
| containerCss = containerCss(this.$element); |
| } |
| |
| CompatUtils.syncCssClasses($container, this.$element, containerCssAdapter); |
| |
| $container.css(containerCss); |
| $container.addClass(containerCssClass); |
| |
| return $container; |
| }; |
| |
| return ContainerCSS; |
| }); |
| |
| S2.define('select2/compat/dropdownCss',[ |
| 'jquery', |
| './utils' |
| ], function ($, CompatUtils) { |
| // No-op CSS adapter that discards all classes by default |
| function _dropdownAdapter (clazz) { |
| return null; |
| } |
| |
| function DropdownCSS () { } |
| |
| DropdownCSS.prototype.render = function (decorated) { |
| var $dropdown = decorated.call(this); |
| |
| var dropdownCssClass = this.options.get('dropdownCssClass') || ''; |
| |
| if ($.isFunction(dropdownCssClass)) { |
| dropdownCssClass = dropdownCssClass(this.$element); |
| } |
| |
| var dropdownCssAdapter = this.options.get('adaptDropdownCssClass'); |
| dropdownCssAdapter = dropdownCssAdapter || _dropdownAdapter; |
| |
| if (dropdownCssClass.indexOf(':all:') !== -1) { |
| dropdownCssClass = dropdownCssClass.replace(':all:', ''); |
| |
| var _cssAdapter = dropdownCssAdapter; |
| |
| dropdownCssAdapter = function (clazz) { |
| var adapted = _cssAdapter(clazz); |
| |
| if (adapted != null) { |
| // Append the old one along with the adapted one |
| return adapted + ' ' + clazz; |
| } |
| |
| return clazz; |
| }; |
| } |
| |
| var dropdownCss = this.options.get('dropdownCss') || {}; |
| |
| if ($.isFunction(dropdownCss)) { |
| dropdownCss = dropdownCss(this.$element); |
| } |
| |
| CompatUtils.syncCssClasses($dropdown, this.$element, dropdownCssAdapter); |
| |
| $dropdown.css(dropdownCss); |
| $dropdown.addClass(dropdownCssClass); |
| |
| return $dropdown; |
| }; |
| |
| return DropdownCSS; |
| }); |
| |
| S2.define('select2/compat/initSelection',[ |
| 'jquery' |
| ], function ($) { |
| function InitSelection (decorated, $element, options) { |
| if (options.get('debug') && window.console && console.warn) { |
| console.warn( |
| 'Select2: The `initSelection` option has been deprecated in favor' + |
| ' of a custom data adapter that overrides the `current` method. ' + |
| 'This method is now called multiple times instead of a single ' + |
| 'time when the instance is initialized. Support will be removed ' + |
| 'for the `initSelection` option in future versions of Select2' |
| ); |
| } |
| |
| this.initSelection = options.get('initSelection'); |
| this._isInitialized = false; |
| |
| decorated.call(this, $element, options); |
| } |
| |
| InitSelection.prototype.current = function (decorated, callback) { |
| var self = this; |
| |
| if (this._isInitialized) { |
| decorated.call(this, callback); |
| |
| return; |
| } |
| |
| this.initSelection.call(null, this.$element, function (data) { |
| self._isInitialized = true; |
| |
| if (!$.isArray(data)) { |
| data = [data]; |
| } |
| |
| callback(data); |
| }); |
| }; |
| |
| return InitSelection; |
| }); |
| |
| S2.define('select2/compat/inputData',[ |
| 'jquery', |
| '../utils' |
| ], function ($, Utils) { |
| function InputData (decorated, $element, options) { |
| this._currentData = []; |
| this._valueSeparator = options.get('valueSeparator') || ','; |
| |
| if ($element.prop('type') === 'hidden') { |
| if (options.get('debug') && console && console.warn) { |
| console.warn( |
| 'Select2: Using a hidden input with Select2 is no longer ' + |
| 'supported and may stop working in the future. It is recommended ' + |
| 'to use a `<select>` element instead.' |
| ); |
| } |
| } |
| |
| decorated.call(this, $element, options); |
| } |
| |
| InputData.prototype.current = function (_, callback) { |
| function getSelected (data, selectedIds) { |
| var selected = []; |
| |
| if (data.selected || $.inArray(data.id, selectedIds) !== -1) { |
| data.selected = true; |
| selected.push(data); |
| } else { |
| data.selected = false; |
| } |
| |
| if (data.children) { |
| selected.push.apply(selected, getSelected(data.children, selectedIds)); |
| } |
| |
| return selected; |
| } |
| |
| var selected = []; |
| |
| for (var d = 0; d < this._currentData.length; d++) { |
| var data = this._currentData[d]; |
| |
| selected.push.apply( |
| selected, |
| getSelected( |
| data, |
| this.$element.val().split( |
| this._valueSeparator |
| ) |
| ) |
| ); |
| } |
| |
| callback(selected); |
| }; |
| |
| InputData.prototype.select = function (_, data) { |
| if (!this.options.get('multiple')) { |
| this.current(function (allData) { |
| $.map(allData, function (data) { |
| data.selected = false; |
| }); |
| }); |
| |
| this.$element.val(data.id); |
| this.$element.trigger('change'); |
| } else { |
| var value = this.$element.val(); |
| value += this._valueSeparator + data.id; |
| |
| this.$element.val(value); |
| this.$element.trigger('change'); |
| } |
| }; |
| |
| InputData.prototype.unselect = function (_, data) { |
| var self = this; |
| |
| data.selected = false; |
| |
| this.current(function (allData) { |
| var values = []; |
| |
| for (var d = 0; d < allData.length; d++) { |
| var item = allData[d]; |
| |
| if (data.id == item.id) { |
| continue; |
| } |
| |
| values.push(item.id); |
| } |
| |
| self.$element.val(values.join(self._valueSeparator)); |
| self.$element.trigger('change'); |
| }); |
| }; |
| |
| InputData.prototype.query = function (_, params, callback) { |
| var results = []; |
| |
| for (var d = 0; d < this._currentData.length; d++) { |
| var data = this._currentData[d]; |
| |
| var matches = this.matches(params, data); |
| |
| if (matches !== null) { |
| results.push(matches); |
| } |
| } |
| |
| callback({ |
| results: results |
| }); |
| }; |
| |
| InputData.prototype.addOptions = function (_, $options) { |
| var options = $.map($options, function ($option) { |
| return Utils.GetData($option[0], 'data'); |
| }); |
| |
| this._currentData.push.apply(this._currentData, options); |
| }; |
| |
| return InputData; |
| }); |
| |
| S2.define('select2/compat/matcher',[ |
| 'jquery' |
| ], function ($) { |
| function oldMatcher (matcher) { |
| function wrappedMatcher (params, data) { |
| var match = $.extend(true, {}, data); |
| |
| if (params.term == null || $.trim(params.term) === '') { |
| return match; |
| } |
| |
| if (data.children) { |
| for (var c = data.children.length - 1; c >= 0; c--) { |
| var child = data.children[c]; |
| |
| // Check if the child object matches |
| // The old matcher returned a boolean true or false |
| var doesMatch = matcher(params.term, child.text, child); |
| |
| // If the child didn't match, pop it off |
| if (!doesMatch) { |
| match.children.splice(c, 1); |
| } |
| } |
| |
| if (match.children.length > 0) { |
| return match; |
| } |
| } |
| |
| if (matcher(params.term, data.text, data)) { |
| return match; |
| } |
| |
| return null; |
| } |
| |
| return wrappedMatcher; |
| } |
| |
| return oldMatcher; |
| }); |
| |
| S2.define('select2/compat/query',[ |
| |
| ], function () { |
| function Query (decorated, $element, options) { |
| if (options.get('debug') && window.console && console.warn) { |
| console.warn( |
| 'Select2: The `query` option has been deprecated in favor of a ' + |
| 'custom data adapter that overrides the `query` method. Support ' + |
| 'will be removed for the `query` option in future versions of ' + |
| 'Select2.' |
| ); |
| } |
| |
| decorated.call(this, $element, options); |
| } |
| |
| Query.prototype.query = function (_, params, callback) { |
| params.callback = callback; |
| |
| var query = this.options.get('query'); |
| |
| query.call(null, params); |
| }; |
| |
| return Query; |
| }); |
| |
| S2.define('select2/dropdown/attachContainer',[ |
| |
| ], function () { |
| function AttachContainer (decorated, $element, options) { |
| decorated.call(this, $element, options); |
| } |
| |
| AttachContainer.prototype.position = |
| function (decorated, $dropdown, $container) { |
| var $dropdownContainer = $container.find('.dropdown-wrapper'); |
| $dropdownContainer.append($dropdown); |
| |
| $dropdown.addClass('select2-dropdown--below'); |
| $container.addClass('select2-container--below'); |
| }; |
| |
| return AttachContainer; |
| }); |
| |
| S2.define('select2/dropdown/stopPropagation',[ |
| |
| ], function () { |
| function StopPropagation () { } |
| |
| StopPropagation.prototype.bind = function (decorated, container, $container) { |
| decorated.call(this, container, $container); |
| |
| var stoppedEvents = [ |
| 'blur', |
| 'change', |
| 'click', |
| 'dblclick', |
| 'focus', |
| 'focusin', |
| 'focusout', |
| 'input', |
| 'keydown', |
| 'keyup', |
| 'keypress', |
| 'mousedown', |
| 'mouseenter', |
| 'mouseleave', |
| 'mousemove', |
| 'mouseover', |
| 'mouseup', |
| 'search', |
| 'touchend', |
| 'touchstart' |
| ]; |
| |
| this.$dropdown.on(stoppedEvents.join(' '), function (evt) { |
| evt.stopPropagation(); |
| }); |
| }; |
| |
| return StopPropagation; |
| }); |
| |
| S2.define('select2/selection/stopPropagation',[ |
| |
| ], function () { |
| function StopPropagation () { } |
| |
| StopPropagation.prototype.bind = function (decorated, container, $container) { |
| decorated.call(this, container, $container); |
| |
| var stoppedEvents = [ |
| 'blur', |
| 'change', |
| 'click', |
| 'dblclick', |
| 'focus', |
| 'focusin', |
| 'focusout', |
| 'input', |
| 'keydown', |
| 'keyup', |
| 'keypress', |
| 'mousedown', |
| 'mouseenter', |
| 'mouseleave', |
| 'mousemove', |
| 'mouseover', |
| 'mouseup', |
| 'search', |
| 'touchend', |
| 'touchstart' |
| ]; |
| |
| this.$selection.on(stoppedEvents.join(' '), function (evt) { |
| evt.stopPropagation(); |
| }); |
| }; |
| |
| return StopPropagation; |
| }); |
| |
| /*! |
| * jQuery Mousewheel 3.1.13 |
| * |
| * Copyright jQuery Foundation and other contributors |
| * Released under the MIT license |
| * http://jquery.org/license |
| */ |
| |
| (function (factory) { |
| if ( typeof S2.define === 'function' && S2.define.amd ) { |
| // AMD. Register as an anonymous module. |
| S2.define('jquery-mousewheel',['jquery'], factory); |
| } else if (typeof exports === 'object') { |
| // Node/CommonJS style for Browserify |
| module.exports = factory; |
| } else { |
| // Browser globals |
| factory(jQuery); |
| } |
| }(function ($) { |
| |
| var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'], |
| toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ? |
| ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'], |
| slice = Array.prototype.slice, |
| nullLowestDeltaTimeout, lowestDelta; |
| |
| if ( $.event.fixHooks ) { |
| for ( var i = toFix.length; i; ) { |
| $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks; |
| } |
| } |
| |
| var special = $.event.special.mousewheel = { |
| version: '3.1.12', |
| |
| setup: function() { |
| if ( this.addEventListener ) { |
| for ( var i = toBind.length; i; ) { |
| this.addEventListener( toBind[--i], handler, false ); |
| } |
| } else { |
| this.onmousewheel = handler; |
| } |
| // Store the line height and page height for this particular element |
| $.data(this, 'mousewheel-line-height', special.getLineHeight(this)); |
| $.data(this, 'mousewheel-page-height', special.getPageHeight(this)); |
| }, |
| |
| teardown: function() { |
| if ( this.removeEventListener ) { |
| for ( var i = toBind.length; i; ) { |
| this.removeEventListener( toBind[--i], handler, false ); |
| } |
| } else { |
| this.onmousewheel = null; |
| } |
| // Clean up the data we added to the element |
| $.removeData(this, 'mousewheel-line-height'); |
| $.removeData(this, 'mousewheel-page-height'); |
| }, |
| |
| getLineHeight: function(elem) { |
| var $elem = $(elem), |
| $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent'](); |
| if (!$parent.length) { |
| $parent = $('body'); |
| } |
| return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16; |
| }, |
| |
| getPageHeight: function(elem) { |
| return $(elem).height(); |
| }, |
| |
| settings: { |
| adjustOldDeltas: true, // see shouldAdjustOldDeltas() below |
| normalizeOffset: true // calls getBoundingClientRect for each event |
| } |
| }; |
| |
| $.fn.extend({ |
| mousewheel: function(fn) { |
| return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel'); |
| }, |
| |
| unmousewheel: function(fn) { |
| return this.unbind('mousewheel', fn); |
| } |
| }); |
| |
| |
| function handler(event) { |
| var orgEvent = event || window.event, |
| args = slice.call(arguments, 1), |
| delta = 0, |
| deltaX = 0, |
| deltaY = 0, |
| absDelta = 0, |
| offsetX = 0, |
| offsetY = 0; |
| event = $.event.fix(orgEvent); |
| event.type = 'mousewheel'; |
| |
| // Old school scrollwheel delta |
| if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; } |
| if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; } |
| if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; } |
| if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; } |
| |
| // Firefox < 17 horizontal scrolling related to DOMMouseScroll event |
| if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) { |
| deltaX = deltaY * -1; |
| deltaY = 0; |
| } |
| |
| // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy |
| delta = deltaY === 0 ? deltaX : deltaY; |
| |
| // New school wheel delta (wheel event) |
| if ( 'deltaY' in orgEvent ) { |
| deltaY = orgEvent.deltaY * -1; |
| delta = deltaY; |
| } |
| if ( 'deltaX' in orgEvent ) { |
| deltaX = orgEvent.deltaX; |
| if ( deltaY === 0 ) { delta = deltaX * -1; } |
| } |
| |
| // No change actually happened, no reason to go any further |
| if ( deltaY === 0 && deltaX === 0 ) { return; } |
| |
| // Need to convert lines and pages to pixels if we aren't already in pixels |
| // There are three delta modes: |
| // * deltaMode 0 is by pixels, nothing to do |
| // * deltaMode 1 is by lines |
| // * deltaMode 2 is by pages |
| if ( orgEvent.deltaMode === 1 ) { |
| var lineHeight = $.data(this, 'mousewheel-line-height'); |
| delta *= lineHeight; |
| deltaY *= lineHeight; |
| deltaX *= lineHeight; |
| } else if ( orgEvent.deltaMode === 2 ) { |
| var pageHeight = $.data(this, 'mousewheel-page-height'); |
| delta *= pageHeight; |
| deltaY *= pageHeight; |
| deltaX *= pageHeight; |
| } |
| |
| // Store lowest absolute delta to normalize the delta values |
| absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) ); |
| |
| if ( !lowestDelta || absDelta < lowestDelta ) { |
| lowestDelta = absDelta; |
| |
| // Adjust older deltas if necessary |
| if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) { |
| lowestDelta /= 40; |
| } |
| } |
| |
| // Adjust older deltas if necessary |
| if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) { |
| // Divide all the things by 40! |
| delta /= 40; |
| deltaX /= 40; |
| deltaY /= 40; |
| } |
| |
| // Get a whole, normalized value for the deltas |
| delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta); |
| deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta); |
| deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta); |
| |
| // Normalise offsetX and offsetY properties |
| if ( special.settings.normalizeOffset && this.getBoundingClientRect ) { |
| var boundingRect = this.getBoundingClientRect(); |
| offsetX = event.clientX - boundingRect.left; |
| offsetY = event.clientY - boundingRect.top; |
| } |
| |
| // Add information to the event object |
| event.deltaX = deltaX; |
| event.deltaY = deltaY; |
| event.deltaFactor = lowestDelta; |
| event.offsetX = offsetX; |
| event.offsetY = offsetY; |
| // Go ahead and set deltaMode to 0 since we converted to pixels |
| // Although this is a little odd since we overwrite the deltaX/Y |
| // properties with normalized deltas. |
| event.deltaMode = 0; |
| |
| // Add event and delta to the front of the arguments |
| args.unshift(event, delta, deltaX, deltaY); |
| |
| // Clearout lowestDelta after sometime to better |
| // handle multiple device types that give different |
| // a different lowestDelta |
| // Ex: trackpad = 3 and mouse wheel = 120 |
| if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); } |
| nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200); |
| |
| return ($.event.dispatch || $.event.handle).apply(this, args); |
| } |
| |
| function nullLowestDelta() { |
| lowestDelta = null; |
| } |
| |
| function shouldAdjustOldDeltas(orgEvent, absDelta) { |
| // If this is an older event and the delta is divisable by 120, |
| // then we are assuming that the browser is treating this as an |
| // older mouse wheel event and that we should divide the deltas |
| // by 40 to try and get a more usable deltaFactor. |
| // Side note, this actually impacts the reported scroll distance |
| // in older browsers and can cause scrolling to be slower than native. |
| // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false. |
| return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0; |
| } |
| |
| })); |
| |
| S2.define('jquery.select2',[ |
| 'jquery', |
| 'jquery-mousewheel', |
| |
| './select2/core', |
| './select2/defaults', |
| './select2/utils' |
| ], function ($, _, Select2, Defaults, Utils) { |
| if ($.fn.select2 == null) { |
| // All methods that should return the element |
| var thisMethods = ['open', 'close', 'destroy']; |
| |
| $.fn.select2 = function (options) { |
| options = options || {}; |
| |
| if (typeof options === 'object') { |
| this.each(function () { |
| var instanceOptions = $.extend(true, {}, options); |
| |
| var instance = new Select2($(this), instanceOptions); |
| }); |
| |
| return this; |
| } else if (typeof options === 'string') { |
| var ret; |
| var args = Array.prototype.slice.call(arguments, 1); |
| |
| this.each(function () { |
| var instance = Utils.GetData(this, 'select2'); |
| |
| if (instance == null && window.console && console.error) { |
| console.error( |
| 'The select2(\'' + options + '\') method was called on an ' + |
| 'element that is not using Select2.' |
| ); |
| } |
| |
| ret = instance[options].apply(instance, args); |
| }); |
| |
| // Check if we should be returning `this` |
| if ($.inArray(options, thisMethods) > -1) { |
| return this; |
| } |
| |
| return ret; |
| } else { |
| throw new Error('Invalid arguments for Select2: ' + options); |
| } |
| }; |
| } |
| |
| if ($.fn.select2.defaults == null) { |
| $.fn.select2.defaults = Defaults; |
| } |
| |
| return Select2; |
| }); |
| |
| // Return the AMD loader configuration so it can be used outside of this file |
| return { |
| define: S2.define, |
| require: S2.require |
| }; |
| }()); |
| |
| // Autoload the jQuery bindings |
| // We know that all of the modules exist above this, so we're safe |
| var select2 = S2.require('jquery.select2'); |
| |
| // Hold the AMD module references on the jQuery function that was just loaded |
| // This allows Select2 to use the internal loader outside of this file, such |
| // as in the language files. |
| jQuery.fn.select2.amd = S2; |
| |
| // Return the Select2 instance for anyone who is importing it. |
| return select2; |
| })); |