select2-4.0.1/000077500000000000000000000000001262616323400130625ustar00rootroot00000000000000select2-4.0.1/.editorconfig000066400000000000000000000001021262616323400155300ustar00rootroot00000000000000[*] indent_style = space end_of_line = lf [*.js] indent_size = 2 select2-4.0.1/.gitignore000066400000000000000000000000601262616323400150460ustar00rootroot00000000000000node_modules dist/js/i18n/build.txt .sass-cache select2-4.0.1/.jshintignore000066400000000000000000000001121262616323400155600ustar00rootroot00000000000000src/js/banner.*.js src/js/wrapper.*.js tests/vendor/*.js tests/helpers.js select2-4.0.1/.jshintrc000066400000000000000000000006621262616323400147130ustar00rootroot00000000000000{ "bitwise": true, "camelcase": true, "curly": true, "es3": true, "eqnull": true, "freeze": true, "globals": { "console": false, "define": false, "document": false, "expect": false, "MockContainer": false, "module": false, "require": false, "test": false, "window": false }, "indent": 2, "maxlen": 80, "noarg": true, "nonew": true, "quotmark": "single", "undef": true } select2-4.0.1/.travis.yml000066400000000000000000000011241262616323400151710ustar00rootroot00000000000000language: node_js sudo: false node_js: - 0.10 env: global: - secure: XMNK8GVxkwKa6oLl7nJwgg/wmY1YDk5rrMd+UXz26EDCsMDbiy1P7GhN2fEiBSLaQ7YfEuvaDcmzQxTrT0YTHp1PDzb2o9J4tIDdEkqPcv1y8xMaYDfmsN0rBPdBwZEg9H5zUgi7OdUbrGswSYxsKCE3x8EOqK89104HyOo1LN4= - secure: BU5BPRx6H4O3WJ509YPixjUxg+hDF3z2BVJX6NiGmKWweqvCEYFfiiHLwDEgp/ynRcF9vGVi1V4Ly1jq7f8NIajbDZ5q443XchZFYFg78K/EwD5mK6LYt16zb7+Jn0KbzwHeGRGzc9AvcEYlW6i634cSCm4n3BnqtF5PpogSzdw= script: - grunt ci notifications: email: false irc: channels: - "chat.freenode.net#select2" on_success: change on_failure: always select2-4.0.1/CONTRIBUTING.md000066400000000000000000000176451262616323400153300ustar00rootroot00000000000000Contributing to Select2 ======================= Looking to contribute something to Select2? **Here's how you can help.** Please take a moment to review this document in order to make the contribution process easy and effective for everyone involved. Following these guidelines helps to communicate that you respect the time of the developers managing and developing this open source project. In return, they should reciprocate that respect in addressing your issue or assessing patches and features. Using the issue tracker ----------------------- When [reporting bugs][reporting-bugs] or [requesting features][requesting-features], the [issue tracker on GitHub][issue-tracker] is the recommended channel to use. The issue tracker **is not** a place for support requests. The [mailing list][community] or [IRC channel][community] are better places to get help. Reporting bugs with Select2 --------------------------- We really appreciate clear bug reports that _consistently_ show an issue _within Select2_. The ideal bug report follows these guidelines: 1. **Use the [GitHub issue search][issue-search]** — Check if the issue has already been reported. 2. **Check if the issue has been fixed** — Try to reproduce the problem using the code in the `master` branch. 3. **Isolate the problem** — Try to create an [isolated test case][isolated-case] that consistently reproduces the problem. Please try to be as detailed as possible in your bug report, especially if an isolated test case cannot be made. Some useful questions to include the answer to are: - What steps can be used to reproduce the issue? - What is the bug and what is the expected outcome? - What browser(s) and Operating System have you tested with? - Does the bug happen consistently across all tested browsers? - What version of jQuery are you using? And what version of Select2? - Are you using Select2 with other plugins? All of these questions will help others fix and identify any potential bugs. Requesting features in Select2 ------------------------------ Select2 is a large library that carries with it a lot of functionality. Because of this, many feature requests will not be implemented in the core library. Before starting work on a major feature for Select2, **contact the [community][community] first** or you may risk spending a considerable amount of time on something which the project developers are not interested in bringing into the project. Contributing changes to Select2 ------------------------------- Select2 is made up of multiple submodules that all come together to make the standard and extended builds that are available to users. The build system uses Node.js to manage and compile the submodules, all of which is done using the Grunt build system. ### Installing development dependencies Select2 can be built and developed on any system which supports Node.js. The preferred Node.js version is 0.10, but 0.12 and later versions can be used without any noticeable issues. You can download Node.js at [their website][nodejs]. All other required Node.js packages can be installed using [npm][npm], which comes bundled alongside Node.js. ```bash cd /path/to/select2/repo npm install ``` You may need to install libsass on your system if it is not already available in order to build the SASS files which generate the CSS for themes and the main component. In order to build and serve the documentation, you need to have [Jekyll][jekyll] installed on your system. ### Building the Select2 component Select2 uses the [Grunt][grunt] build task system and defines a few custom tasks for common routines. One of them is the `compile` task, which compiles the JavaScript and CSS and produces the final files. ```bash cd /path/to/select2/repo grunt compile ``` You can also generate the minified versions (`.min.js` files) by executing the `minify` task after compiling. ```bash cd /path/to/select2/repo grunt minify ``` ### Building the documentation Using the Grunt build system, you run Jekyll and serve the documentation locally. This will also set up the examples to use the latest version of Select2 that has been built. ```bash cd /path/to/select2/repo grunt docs ``` ### Running tests Select2 uses the QUnit test system to test individual components. ```bash cd /path/to/selct2/repo grunt test ``` ### Submitting a pull request We use GitHub's pull request system for submitting patches. Here are some guidelines to follow when creating the pull request for your fix. 1. Make sure to create a ticket for your pull request. This will serve as the bug ticket, and any discussion about the bug will take place there. Your pull request will be focused on the specific changes that fix the bug. 2. Make sure to reference the ticket you are fixing within your pull request. This will allow us to close off the ticket once we merge the pull request, or follow up on the ticket if there are any related blocking issues. 3. Explain why the specific change was made. Not everyone who is reviewing your pull request will be familiar with the problem it is fixing. 4. Run your tests first. If your tests aren't passing, the pull request won't be able to be merged. If you're breaking existing tests, make sure that you aren't causing any breaking changes. 5. Only include source changes. While it's not required, only including changes from the `src` directory will prevent merge conflicts from occuring. Making this happen can be as a simple as not committing changes from the `dist` directory. By following these steps, you will make it easier for your pull request to be reviewed and eventually merged. Triaging issues and pull requests --------------------------------- Anyone can help the project maintainers triage issues and review pull requests. ### Handling new issues Select2 regularly receives new issues which need to be tested and organized. When a new issue that comes in that is similar to another existing issue, it should be checked to make sure it is not a duplicate. Duplicates issues should be marked by replying to the issue with "Duplicate of #[issue number]" where `[issue number]` is the url or issue number for the existing issue. This will allow the project maintainers to quickly close off additional issues and keep the discussion focused within a single issue. If you can test issues that are reported to Select2 that contain test cases and confirm under what conditions bugs happen, that will allow others to identify what causes a bug quicker. ### Reviewing pull requests It is very common for pull requests to be opened for issues that contain a clear solution to the problem. These pull requests should be rigorously reviewed by the community before being accepted. If you are not sure about a piece of submitted code, or know of a better way to do something, do not hesitate to make a comment on the pull request. ### Reviving old tickets If you come across tickets which have not been updated for a while, you are encouraged to revive them. While this can be as simple as saying `:+1:`, it is best if you can include more information on the issue. Common bugs and feature requests are more likely to be fixed, whether it is by the community or the developers, so keeping tickets up to date is encouraged. Licensing --------- It should also be made clear that **all code contributed to Select** must be licensable under the [MIT license][licensing]. Code that cannot be released under this license **cannot be accepted** into the project. [community]: https://select2.github.io/community.html [grunt]: http://gruntjs.com/ [isolated-case]: http://css-tricks.com/6263-reduced-test-cases/ [issue-search]: https://github.com/select2/select2/search?q=&type=Issues [issue-tracker]: https://github.com/select2/select2/issues [jekyll]: https://jekyllrb.com/docs/installation/ [licensing]: https://github.com/select2/select2/blob/master/LICENSE.md [nodejs]: https://nodejs.org/ [npm]: https://www.npmjs.com/ [reporting-bugs]: #reporting-bugs-with-select2 [requesting-features]: #requesting-features-in-select2select2-4.0.1/Gruntfile.js000066400000000000000000000202761262616323400153660ustar00rootroot00000000000000module.exports = function (grunt) { // Full list of files that must be included by RequireJS includes = [ 'jquery.select2', 'almond', 'jquery-mousewheel' // shimmed for non-full builds ]; fullIncludes = [ 'jquery', 'select2/compat/containerCss', 'select2/compat/dropdownCss', 'select2/compat/initSelection', 'select2/compat/inputData', 'select2/compat/matcher', 'select2/compat/query', 'select2/dropdown/attachContainer', 'select2/dropdown/stopPropagation', 'select2/selection/stopPropagation' ].concat(includes); var i18nModules = []; var i18nPaths = {}; var i18nFiles = grunt.file.expand({ cwd: 'src/js' }, 'select2/i18n/*.js'); var testFiles = grunt.file.expand('tests/**/*.html'); var testUrls = testFiles.map(function (filePath) { return 'http://localhost:9999/' + filePath; }); var testBuildNumber = "unknown"; if (process.env.TRAVIS_JOB_ID) { testBuildNumber = "travis-" + process.env.TRAVIS_JOB_ID; } else { var currentTime = new Date(); testBuildNumber = "manual-" + currentTime.getTime(); } for (var i = 0; i < i18nFiles.length; i++) { var file = i18nFiles[i]; var name = file.split('.')[0]; i18nModules.push({ name: name }); i18nPaths[name] = '../../' + name; } var minifiedBanner = '/*! Select2 <%= package.version %> | https://github.com/select2/select2/blob/master/LICENSE.md */'; grunt.initConfig({ package: grunt.file.readJSON('package.json'), clean: { docs: ['docs/_site'] }, concat: { 'dist': { options: { banner: grunt.file.read('src/js/wrapper.start.js'), }, src: [ 'dist/js/select2.js', 'src/js/wrapper.end.js' ], dest: 'dist/js/select2.js' }, 'dist.full': { options: { banner: grunt.file.read('src/js/wrapper.start.js'), }, src: [ 'dist/js/select2.full.js', 'src/js/wrapper.end.js' ], dest: 'dist/js/select2.full.js' } }, connect: { tests: { options: { base: '.', hostname: '127.0.0.1', port: 9999 } } }, uglify: { 'dist': { src: 'dist/js/select2.js', dest: 'dist/js/select2.min.js', options: { banner: minifiedBanner } }, 'dist.full': { src: 'dist/js/select2.full.js', dest: 'dist/js/select2.full.min.js', options: { banner: minifiedBanner } } }, qunit: { all: { options: { urls: testUrls } } }, 'saucelabs-qunit': { all: { options: { build: testBuildNumber, tags: ['tests', 'qunit'], urls: testUrls, testname: 'QUnit test for Select2', browsers: [ { browserName: 'internet explorer', version: '8' }, { browserName: 'internet explorer', version: '9' }, { browserName: 'internet explorer', version: '10' }, { browserName: 'internet explorer', version: '11' }, { browserName: 'firefox', platform: 'linux' }, { browserName: 'chrome' }, { browserName: 'opera', version: '12', platform: 'linux' } ] } } }, 'gh-pages': { options: { base: 'docs', branch: 'master', clone: 'node_modules/grunt-gh-pages/repo', message: 'Updated docs with master', push: true, repo: 'git@github.com:select2/select2.github.io.git' }, src: '**' }, jekyll: { options: { src: 'docs', dest: 'docs/_site' }, build: { d: null }, serve: { options: { serve: true, watch: true } } }, jshint: { options: { jshintrc: true }, code: { src: ['src/js/**/*.js'] }, tests: { src: ['tests/**/*.js'] } }, sass: { dist: { options: { outputStyle: 'compressed' }, files: { 'dist/css/select2.min.css': [ 'src/scss/core.scss', 'src/scss/theme/default/layout.css' ] } }, dev: { options: { outputStyle: 'nested' }, files: { 'dist/css/select2.css': [ 'src/scss/core.scss', 'src/scss/theme/default/layout.css' ] } } }, symlink: { docs: { cwd: 'dist', expand: true, overwrite: false, src: [ '*' ], dest: 'docs/dist', filter: 'isDirectory' } }, requirejs: { 'dist': { options: { baseUrl: 'src/js', optimize: 'none', name: 'select2/core', out: 'dist/js/select2.js', include: includes, namespace: 'S2', paths: { 'almond': require.resolve('almond').slice(0, -3), 'jquery': 'jquery.shim', 'jquery-mousewheel': 'jquery.mousewheel.shim' }, wrap: { startFile: 'src/js/banner.start.js', endFile: 'src/js/banner.end.js' } } }, 'dist.full': { options: { baseUrl: 'src/js', optimize: 'none', name: 'select2/core', out: 'dist/js/select2.full.js', include: fullIncludes, namespace: 'S2', paths: { 'almond': require.resolve('almond').slice(0, -3), 'jquery': 'jquery.shim', 'jquery-mousewheel': require.resolve('jquery-mousewheel').slice(0, -3) }, wrap: { startFile: 'src/js/banner.start.js', endFile: 'src/js/banner.end.js' } } }, 'i18n': { options: { baseUrl: 'src/js/select2/i18n', dir: 'dist/js/i18n', paths: i18nPaths, modules: i18nModules, namespace: 'S2', wrap: { start: minifiedBanner + grunt.file.read('src/js/banner.start.js'), end: grunt.file.read('src/js/banner.end.js') } } } }, watch: { js: { files: [ 'src/js/select2/**/*.js', 'tests/**/*.js' ], tasks: [ 'compile', 'test', 'minify' ] }, css: { files: [ 'src/scss/**/*.scss' ], tasks: [ 'compile', 'minify' ] } } }); grunt.loadNpmTasks('grunt-contrib-clean'); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-connect'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-qunit'); grunt.loadNpmTasks('grunt-contrib-requirejs'); grunt.loadNpmTasks('grunt-contrib-symlink'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-gh-pages'); grunt.loadNpmTasks('grunt-jekyll'); grunt.loadNpmTasks('grunt-saucelabs'); grunt.loadNpmTasks('grunt-sass'); grunt.registerTask('default', ['compile', 'test', 'minify']); grunt.registerTask('compile', [ 'requirejs:dist', 'requirejs:dist.full', 'requirejs:i18n', 'concat:dist', 'concat:dist.full', 'sass:dev' ]); grunt.registerTask('minify', ['uglify', 'sass:dist']); grunt.registerTask('test', ['connect:tests', 'qunit', 'jshint']); var ciTasks = []; ciTasks.push('compile') ciTasks.push('connect:tests'); // Can't run Sauce Labs tests in pull requests if (process.env.TRAVIS_PULL_REQUEST == 'false') { ciTasks.push('saucelabs-qunit'); } ciTasks.push('qunit'); ciTasks.push('jshint'); grunt.registerTask('ci', ciTasks); grunt.registerTask('docs', ['symlink:docs', 'jekyll:serve']); grunt.registerTask('docs-release', ['default', 'clean:docs', 'gh-pages']); }; select2-4.0.1/LICENSE.md000066400000000000000000000021441262616323400144670ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2012-2015 Kevin Brown, Igor Vaynberg, and Select2 contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. select2-4.0.1/README.md000066400000000000000000000100231262616323400143350ustar00rootroot00000000000000Select2 ======= [![Build Status][travis-ci-image]][travis-ci-status] Select2 is a jQuery-based replacement for select boxes. It supports searching, remote data sets, and pagination of results. To get started, checkout examples and documentation at https://select2.github.io/ Use cases --------- * Enhancing native selects with search. * Enhancing native selects with a better multi-select interface. * Loading data from JavaScript: easily load items via AJAX and have them searchable. * Nesting optgroups: native selects only support one level of nesting. Select2 does not have this restriction. * Tagging: ability to add new items on the fly. * Working with large, remote datasets: ability to partially load a dataset based on the search term. * Paging of large datasets: easy support for loading more pages when the results are scrolled to the end. * Templating: support for custom rendering of results and selections. Browser compatibility --------------------- * IE 8+ * Chrome 8+ * Firefox 10+ * Safari 3+ * Opera 10.6+ Usage ----- You can source Select2 directly from a CDN like [JSDliver][jsdelivr] or [CDNJS][cdnjs], [download it from this GitHub repo][releases], or use one of the integrations below. Integrations ------------ * [Wicket-Select2][wicket-select2] (Java / [Apache Wicket][wicket]) * [select2-rails][select2-rails] (Ruby on Rails) * [AngularUI][angularui-select] ([AngularJS][angularjs]) * [Django][django-select2] * [Symfony][symfony-select2] * [Symfony2][symfony2-select2] * [Bootstrap 2][bootstrap2-select2] and [Bootstrap 3][bootstrap3-select2] (CSS skins) * [Meteor][meteor-select2] ([Bootstrap 3 skin][meteor-select2-bootstrap3]) * [Meteor][meteor-select2-alt] * [Yii 2.x][yii2-select2] * [Yii 1.x][yii-select2] * [AtmosphereJS][atmospherejs-select2] Internationalization (i18n) --------------------------- Select2 supports multiple languages by simply including the right language JS file (`dist/js/i18n/it.js`, `dist/js/i18n/nl.js`, etc.) after `dist/js/select2.js`. Missing a language? Just copy `src/js/select2/i18n/en.js`, translate it, and make a pull request back to Select2 here on GitHub. Documentation ------------- The documentation for Select2 is available [through GitHub Pages][documentation] and is located within this repository in the [`docs` folder][documentation-folder]. Community --------- You can find out about the different ways to get in touch with the Select2 community at the [Select2 community page][community]. Copyright and license --------------------- The license is available within the repository in the [LICENSE][license] file. [angularjs]: https://angularjs.org/ [angularui-select]: http://angular-ui.github.io/#ui-select [atmospherejs-select2]: https://atmospherejs.com/package/jquery-select2 [bootstrap2-select2]: https://github.com/t0m/select2-bootstrap-css [bootstrap3-select2]: https://github.com/t0m/select2-bootstrap-css/tree/bootstrap3 [cdnjs]: http://www.cdnjs.com/libraries/select2 [community]: https://select2.github.io/community.html [django-select2]: https://github.com/applegrew/django-select2 [documentation]: https://select2.github.io/ [documentation-folder]: https://github.com/select2/select2/tree/master/docs [freenode]: https://freenode.net/ [jsdelivr]: http://www.jsdelivr.com/#!select2 [license]: LICENSE.md [meteor-select2]: https://github.com/nate-strauser/meteor-select2 [meteor-select2-alt]: https://jquery-select2.meteor.com [meteor-select2-bootstrap3]: https://github.com/zimme/meteor-select2-bootstrap3-css/ [releases]: https://github.com/select2/select2/releases [select2-rails]: https://github.com/argerim/select2-rails [symfony-select2]: https://github.com/19Gerhard85/sfSelect2WidgetsPlugin [symfony2-select2]: https://github.com/avocode/FormExtensions [travis-ci-image]: https://travis-ci.org/select2/select2.svg?branch=master [travis-ci-status]: https://travis-ci.org/select2/select2 [wicket]: http://wicket.apache.org [wicket-select2]: https://github.com/ivaynberg/wicket-select2 [yii-select2]: https://github.com/tonybolzan/yii-select2 [yii2-select2]: http://demos.krajee.com/widgets#select2 select2-4.0.1/bower.json000066400000000000000000000005521262616323400150750ustar00rootroot00000000000000{ "name": "select2", "description": "Select2 is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.", "main": [ "dist/js/select2.js", "src/scss/core.scss" ], "repository": { "type": "git", "url": "git@github.com:select2/select2.git" } } select2-4.0.1/component.json000066400000000000000000000007241262616323400157620ustar00rootroot00000000000000{ "name": "select2", "repo": "select/select2", "description": "Select2 is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.", "version": "4.0.1", "demo": "https://select2.github.io/", "keywords": [ "jquery" ], "main": "dist/js/select2.js", "styles": [ "dist/css/select2.css" ], "scripts": [ "dist/js/select2.js", "dist/js/i18n/*.js" ], "license": "MIT" } select2-4.0.1/composer.json000066400000000000000000000010201262616323400155750ustar00rootroot00000000000000{ "name": "select2/select2", "description": "Select2 is a jQuery based replacement for select boxes.", "type": "component", "homepage": "https://select2.github.io/", "license": "MIT", "require": { "robloach/component-installer": "*" }, "extra": { "component": { "scripts": [ "dist/js/select2.js" ], "styles": [ "dist/css/select2.css" ], "files": [ "dist/js/select2.js", "dist/js/i18n/*.js", "dist/css/select2.css" ] } } } select2-4.0.1/dist/000077500000000000000000000000001262616323400140255ustar00rootroot00000000000000select2-4.0.1/dist/css/000077500000000000000000000000001262616323400146155ustar00rootroot00000000000000select2-4.0.1/dist/css/select2.css000066400000000000000000000421131262616323400166710ustar00rootroot00000000000000.select2-container { box-sizing: border-box; display: inline-block; margin: 0; position: relative; vertical-align: middle; } .select2-container .select2-selection--single { box-sizing: border-box; cursor: pointer; display: block; height: 28px; user-select: none; -webkit-user-select: none; } .select2-container .select2-selection--single .select2-selection__rendered { display: block; padding-left: 8px; padding-right: 20px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .select2-container .select2-selection--single .select2-selection__clear { position: relative; } .select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered { padding-right: 8px; padding-left: 20px; } .select2-container .select2-selection--multiple { box-sizing: border-box; cursor: pointer; display: block; min-height: 32px; user-select: none; -webkit-user-select: none; } .select2-container .select2-selection--multiple .select2-selection__rendered { display: inline-block; overflow: hidden; padding-left: 8px; text-overflow: ellipsis; white-space: nowrap; } .select2-container .select2-search--inline { float: left; } .select2-container .select2-search--inline .select2-search__field { box-sizing: border-box; border: none; font-size: 100%; margin-top: 5px; padding: 0; } .select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button { -webkit-appearance: none; } .select2-dropdown { background-color: white; border: 1px solid #aaa; border-radius: 4px; box-sizing: border-box; display: block; position: absolute; left: -100000px; width: 100%; z-index: 1051; } .select2-results { display: block; } .select2-results__options { list-style: none; margin: 0; padding: 0; } .select2-results__option { padding: 6px; user-select: none; -webkit-user-select: none; } .select2-results__option[aria-selected] { cursor: pointer; } .select2-container--open .select2-dropdown { left: 0; } .select2-container--open .select2-dropdown--above { border-bottom: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; } .select2-container--open .select2-dropdown--below { border-top: none; border-top-left-radius: 0; border-top-right-radius: 0; } .select2-search--dropdown { display: block; padding: 4px; } .select2-search--dropdown .select2-search__field { padding: 4px; width: 100%; box-sizing: border-box; } .select2-search--dropdown .select2-search__field::-webkit-search-cancel-button { -webkit-appearance: none; } .select2-search--dropdown.select2-search--hide { display: none; } .select2-close-mask { border: 0; margin: 0; padding: 0; display: block; position: fixed; left: 0; top: 0; min-height: 100%; min-width: 100%; height: auto; width: auto; opacity: 0; z-index: 99; background-color: #fff; filter: alpha(opacity=0); } .select2-hidden-accessible { border: 0 !important; clip: rect(0 0 0 0) !important; height: 1px !important; margin: -1px !important; overflow: hidden !important; padding: 0 !important; position: absolute !important; width: 1px !important; } .select2-container--default .select2-selection--single { background-color: #fff; border: 1px solid #aaa; border-radius: 4px; } .select2-container--default .select2-selection--single .select2-selection__rendered { color: #444; line-height: 28px; } .select2-container--default .select2-selection--single .select2-selection__clear { cursor: pointer; float: right; font-weight: bold; } .select2-container--default .select2-selection--single .select2-selection__placeholder { color: #999; } .select2-container--default .select2-selection--single .select2-selection__arrow { height: 26px; position: absolute; top: 1px; right: 1px; width: 20px; } .select2-container--default .select2-selection--single .select2-selection__arrow b { border-color: #888 transparent transparent transparent; border-style: solid; border-width: 5px 4px 0 4px; height: 0; left: 50%; margin-left: -4px; margin-top: -2px; position: absolute; top: 50%; width: 0; } .select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear { float: left; } .select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow { left: 1px; right: auto; } .select2-container--default.select2-container--disabled .select2-selection--single { background-color: #eee; cursor: default; } .select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear { display: none; } .select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b { border-color: transparent transparent #888 transparent; border-width: 0 4px 5px 4px; } .select2-container--default .select2-selection--multiple { background-color: white; border: 1px solid #aaa; border-radius: 4px; cursor: text; } .select2-container--default .select2-selection--multiple .select2-selection__rendered { box-sizing: border-box; list-style: none; margin: 0; padding: 0 5px; width: 100%; } .select2-container--default .select2-selection--multiple .select2-selection__placeholder { color: #999; margin-top: 5px; float: left; } .select2-container--default .select2-selection--multiple .select2-selection__clear { cursor: pointer; float: right; font-weight: bold; margin-top: 5px; margin-right: 10px; } .select2-container--default .select2-selection--multiple .select2-selection__choice { background-color: #e4e4e4; border: 1px solid #aaa; border-radius: 4px; cursor: default; float: left; margin-right: 5px; margin-top: 5px; padding: 0 5px; } .select2-container--default .select2-selection--multiple .select2-selection__choice__remove { color: #999; cursor: pointer; display: inline-block; font-weight: bold; margin-right: 2px; } .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover { color: #333; } .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline { float: right; } .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice { margin-left: 5px; margin-right: auto; } .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { margin-left: 2px; margin-right: auto; } .select2-container--default.select2-container--focus .select2-selection--multiple { border: solid black 1px; outline: 0; } .select2-container--default.select2-container--disabled .select2-selection--multiple { background-color: #eee; cursor: default; } .select2-container--default.select2-container--disabled .select2-selection__choice__remove { display: none; } .select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple { border-top-left-radius: 0; border-top-right-radius: 0; } .select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple { border-bottom-left-radius: 0; border-bottom-right-radius: 0; } .select2-container--default .select2-search--dropdown .select2-search__field { border: 1px solid #aaa; } .select2-container--default .select2-search--inline .select2-search__field { background: transparent; border: none; outline: 0; box-shadow: none; -webkit-appearance: textfield; } .select2-container--default .select2-results > .select2-results__options { max-height: 200px; overflow-y: auto; } .select2-container--default .select2-results__option[role=group] { padding: 0; } .select2-container--default .select2-results__option[aria-disabled=true] { color: #999; } .select2-container--default .select2-results__option[aria-selected=true] { background-color: #ddd; } .select2-container--default .select2-results__option .select2-results__option { padding-left: 1em; } .select2-container--default .select2-results__option .select2-results__option .select2-results__group { padding-left: 0; } .select2-container--default .select2-results__option .select2-results__option .select2-results__option { margin-left: -1em; padding-left: 2em; } .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option { margin-left: -2em; padding-left: 3em; } .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { margin-left: -3em; padding-left: 4em; } .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { margin-left: -4em; padding-left: 5em; } .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { margin-left: -5em; padding-left: 6em; } .select2-container--default .select2-results__option--highlighted[aria-selected] { background-color: #5897fb; color: white; } .select2-container--default .select2-results__group { cursor: default; display: block; padding: 6px; } .select2-container--classic .select2-selection--single { background-color: #f7f7f7; border: 1px solid #aaa; border-radius: 4px; outline: 0; background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%); background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%); background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); } .select2-container--classic .select2-selection--single:focus { border: 1px solid #5897fb; } .select2-container--classic .select2-selection--single .select2-selection__rendered { color: #444; line-height: 28px; } .select2-container--classic .select2-selection--single .select2-selection__clear { cursor: pointer; float: right; font-weight: bold; margin-right: 10px; } .select2-container--classic .select2-selection--single .select2-selection__placeholder { color: #999; } .select2-container--classic .select2-selection--single .select2-selection__arrow { background-color: #ddd; border: none; border-left: 1px solid #aaa; border-top-right-radius: 4px; border-bottom-right-radius: 4px; height: 26px; position: absolute; top: 1px; right: 1px; width: 20px; background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%); background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%); background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); } .select2-container--classic .select2-selection--single .select2-selection__arrow b { border-color: #888 transparent transparent transparent; border-style: solid; border-width: 5px 4px 0 4px; height: 0; left: 50%; margin-left: -4px; margin-top: -2px; position: absolute; top: 50%; width: 0; } .select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear { float: left; } .select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow { border: none; border-right: 1px solid #aaa; border-radius: 0; border-top-left-radius: 4px; border-bottom-left-radius: 4px; left: 1px; right: auto; } .select2-container--classic.select2-container--open .select2-selection--single { border: 1px solid #5897fb; } .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow { background: transparent; border: none; } .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b { border-color: transparent transparent #888 transparent; border-width: 0 4px 5px 4px; } .select2-container--classic.select2-container--open.select2-container--above .select2-selection--single { border-top: none; border-top-left-radius: 0; border-top-right-radius: 0; background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%); background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%); background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); } .select2-container--classic.select2-container--open.select2-container--below .select2-selection--single { border-bottom: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%); background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%); background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); } .select2-container--classic .select2-selection--multiple { background-color: white; border: 1px solid #aaa; border-radius: 4px; cursor: text; outline: 0; } .select2-container--classic .select2-selection--multiple:focus { border: 1px solid #5897fb; } .select2-container--classic .select2-selection--multiple .select2-selection__rendered { list-style: none; margin: 0; padding: 0 5px; } .select2-container--classic .select2-selection--multiple .select2-selection__clear { display: none; } .select2-container--classic .select2-selection--multiple .select2-selection__choice { background-color: #e4e4e4; border: 1px solid #aaa; border-radius: 4px; cursor: default; float: left; margin-right: 5px; margin-top: 5px; padding: 0 5px; } .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove { color: #888; cursor: pointer; display: inline-block; font-weight: bold; margin-right: 2px; } .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover { color: #555; } .select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice { float: right; } .select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice { margin-left: 5px; margin-right: auto; } .select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { margin-left: 2px; margin-right: auto; } .select2-container--classic.select2-container--open .select2-selection--multiple { border: 1px solid #5897fb; } .select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple { border-top: none; border-top-left-radius: 0; border-top-right-radius: 0; } .select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple { border-bottom: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; } .select2-container--classic .select2-search--dropdown .select2-search__field { border: 1px solid #aaa; outline: 0; } .select2-container--classic .select2-search--inline .select2-search__field { outline: 0; box-shadow: none; } .select2-container--classic .select2-dropdown { background-color: white; border: 1px solid transparent; } .select2-container--classic .select2-dropdown--above { border-bottom: none; } .select2-container--classic .select2-dropdown--below { border-top: none; } .select2-container--classic .select2-results > .select2-results__options { max-height: 200px; overflow-y: auto; } .select2-container--classic .select2-results__option[role=group] { padding: 0; } .select2-container--classic .select2-results__option[aria-disabled=true] { color: grey; } .select2-container--classic .select2-results__option--highlighted[aria-selected] { background-color: #3875d7; color: white; } .select2-container--classic .select2-results__group { cursor: default; display: block; padding: 6px; } .select2-container--classic.select2-container--open .select2-dropdown { border-color: #5897fb; } select2-4.0.1/dist/js/000077500000000000000000000000001262616323400144415ustar00rootroot00000000000000select2-4.0.1/dist/js/select2.js000066400000000000000000004143521262616323400163510ustar00rootroot00000000000000/*! * Select2 4.0.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 exports === 'object') { // Node/CommonJS factory(require('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.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved. * Available via the MIT or new BSD license. * see: http://github.com/jrburke/almond for details */ //Going sloppy to avoid 'use strict' string cost, but strict practices should //be followed. /*jslint sloppy: true */ /*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, baseParts = baseName && baseName.split("/"), map = config.map, starMap = (map && map['*']) || {}; //Adjust any relative paths. if (name && name.charAt(0) === ".") { //If have a base name, try to normalize against it, //otherwise, assume it is a top-level require that will //be relative to baseUrl in the end. if (baseName) { name = name.split('/'); lastIndex = name.length - 1; // Node .js allowance: if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) { name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, ''); } //Lop off the last part of baseParts, so that . matches the //"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. name = baseParts.slice(0, baseParts.length - 1).concat(name); //start trimDots for (i = 0; i < name.length; i += 1) { part = name[i]; if (part === ".") { name.splice(i, 1); i -= 1; } else if (part === "..") { if (i === 1 && (name[2] === '..' || name[0] === '..')) { //End of the line. Keep at least one non-dot //path segment at the front so it can be mapped //correctly to disk. Otherwise, there is likely //no path mapping for a path starting with '..'. //This can still fail, but catches the most reasonable //uses of .. break; } else if (i > 0) { name.splice(i - 1, 2); i -= 2; } } } //end trimDots name = name.join("/"); } else if (name.indexOf('./') === 0) { // No baseName, so this is ID is resolved relative // to baseUrl, pull off the leading dot. name = name.substring(2); } } //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]; } /** * 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, relName) { var plugin, parts = splitPrefix(name), prefix = parts[0]; name = parts[1]; if (prefix) { prefix = normalize(prefix, relName); plugin = callDep(prefix); } //Normalize according if (prefix) { if (plugin && plugin.normalize) { name = plugin.normalize(name, makeNormalize(relName)); } else { name = normalize(name, relName); } } else { name = normalize(name, relName); 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, args = [], callbackType = typeof callback, usingExports; //Use name if no relName relName = relName || name; //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], relName); 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, 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; this.listeners = this.listeners || {}; 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); }; 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 = $( '' ); 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 = $( '
  • ' ); 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.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 = $.data(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'); } }); 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'); } }); }; 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 = $('', { 'class': 'select2-results__options select2-results__options--nested' }); $childrenContainer.append($children); $option.append(label); $option.append($childrenContainer); } else { this.template(data, option); } $.data(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(); } }); 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(); }); container.on('unselect', function () { if (!container.isOpen()) { return; } self.setClasses(); }); 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 = $highlighted.data('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 (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 - self.$results.scrollTop() + 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 = $this.data('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 = $(this).data('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 = $( '' ); this._tabindex = 0; if (this.$element.data('old-tabindex') != null) { this._tabindex = this.$element.data('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(); 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 = $this.data('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( '' + '' + '' + '' ); 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); 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('selection:update', function (params) { self.update(params.data); }); }; SingleSelection.prototype.clear = function () { this.$selection.find('.select2-selection__rendered').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 $(''); }; 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.prop('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( '' ); 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 = $selection.data('data'); self.trigger('unselect', { originalEvent: evt, data: data }); } ); }; MultipleSelection.prototype.clear = function () { this.$selection.find('.select2-selection__rendered').empty(); }; 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 = $( '
  • ' + '' + '×' + '' + '
  • ' ); 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.prop('title', selection.title || selection.text); $selection.data('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' ], function ($, KEYS) { 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 = $clear.data('data'); for (var d = 0; d < data.length; d++) { var 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) { return; } } this.$element.val(this.placeholder.id).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 = $( '' + '×' + '' ); $remove.data('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 = $( '' ); 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 = $previousChoice.data('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) { 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' ]; var preventableEvents = ['opening', 'closing', 'selecting', 'unselecting']; 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 $.removeData(this, 'data'); }); }; 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) { 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 $.data(option, 'data', normalizedData); return $option; }; SelectAdapter.prototype.item = function ($option) { var data = {}; data = $.data($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]; $.data($option[0], 'data', data); return data; }; SelectAdapter.prototype._normalizeItem = function (item) { if (!$.isPlainObject(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, {}, existingData, item); 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 () { // TODO: Handle AJAX errors }); self._request = $request; } if (this.ajaxOptions.delay && params.term !== '') { 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; } 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 checkText = option.text === params.term; 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 select (data) { self.trigger('select', { data: data }); } params.term = params.term || ''; var tokenData = this.tokenizer(params, this.options, select); 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 = $( '' + '' + '' ); $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 = $( '' + '' + '' ); 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(''); }); 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 = $( '
  • ' ); 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 = $(''); 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 () { $(this).data('select2-scroll-position', { x: $(this).scrollLeft(), y: $(this).scrollTop() }); }); $watchers.on(scrollEvent, function (ev) { var position = $(this).data('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 position = this.$container.position(); 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 }; // Fix positioning with static parents if (this.$dropdownParent[0].style.position !== 'static') { var parentOffset = this.$dropdownParent.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 - 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.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',[ ], function () { function SelectOnClose () { } SelectOnClose.prototype.bind = function (decorated, container, $container) { var self = this; decorated.call(this, container, $container); container.on('close', function () { self._handleSelectOnClose(); }); }; SelectOnClose.prototype._handleSelectOnClose = function () { var $highlightedResults = this.getHighlightedResults(); // Only select highlighted results if ($highlightedResults.length < 1) { return; } var data = $highlightedResults.data('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', {}); }; 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({}, 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(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 ($e.data('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.' ); } $e.data('data', $e.data('select2Tags')); $e.data('tags', true); } if ($e.data('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', $e.data('ajaxUrl')); $e.data('ajax--url', $e.data('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, $e.data()); } else { dataset = $e.data(); } 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 ($element.data('select2') != null) { $element.data('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; $element.data('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(); $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 = '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._sync = Utils.bind(this._syncAttributes, this); if (this.$element[0].attachEvent) { this.$element[0].attachEvent('onpropertychange', this._sync); } var observer = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver ; if (observer != null) { this._observer = new observer(function (mutations) { $.each(mutations, self._sync); }); this._observer.observe(this.$element[0], { attributes: true, subtree: false }); } else if (this.$element[0].addEventListener) { this.$element[0].addEventListener('DOMAttrModified', self._sync, 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', {}); } }; /** * 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' }; 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._sync); } if (this._observer != null) { this._observer.disconnect(); this._observer = null; } else if (this.$element[0].removeEventListener) { this.$element[0] .removeEventListener('DOMAttrModified', this._sync, false); } this._sync = null; this.$element.off('.select2'); this.$element.attr('tabindex', this.$element.data('old-tabindex')); this.$element.removeClass('select2-hidden-accessible'); this.$element.attr('aria-hidden', 'false'); 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 = $( '' + '' + '' + '' ); $container.attr('dir', this.options.get('dir')); this.$container = $container; this.$container.addClass('select2-container--' + this.options.get('theme')); $container.data('element', this.$element); return $container; }; return Select2; }); S2.define('jquery-mousewheel',[ 'jquery' ], function ($) { // Used to shim jQuery.mousewheel for non-full builds. return $; }); S2.define('jquery.select2',[ 'jquery', 'jquery-mousewheel', './select2/core', './select2/defaults' ], function ($, _, Select2, Defaults) { 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; this.each(function () { var instance = $(this).data('select2'); if (instance == null && window.console && console.error) { console.error( 'The select2(\'' + options + '\') method was called on an ' + 'element that is not using Select2.' ); } var args = Array.prototype.slice.call(arguments, 1); 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; })); select2-4.0.1/docs/000077500000000000000000000000001262616323400140125ustar00rootroot00000000000000select2-4.0.1/docs/.gitignore000066400000000000000000000000131262616323400157740ustar00rootroot00000000000000_site dist select2-4.0.1/docs/README.md000066400000000000000000000025621262616323400152760ustar00rootroot00000000000000Select2 Documentation ===================== [This repository][select2-docs-source] holds the latest documentation for [Select2][select2]. What is this? ------------- The documentation is automatically extracted from the `docs` directory at the [Select2 source repository][select2-source]. This is done periodically by the maintainers of Select2. How can I fix an issue in these docs? ------------------------------------- If you are reading this from the source repository, within the `docs` directory, then you're already in the right place. You can fork the source repository, commit your changes, and then make a pull request and it will be reviewed. **If you are reading this from the [documentation repository][select2-docs-source], you are in the wrong place.** Pull requests made directly to the documentation repository will be ignored and eventually closed, so don't do that. How can I build these docs manually? ------------------------------------ In the [main Select2 repository][select2-source], you can build the documentation by executing ```bash grunt docs ``` Which will start up the documentation on port 4000. You will need [Jekyll][jekyll] installed to build the documentation. [jekyll]: http://jekyllrb.com/ [select2]: https://select2.github.io [select2-docs-source]: https://github.com/select2/select2.github.io [select2-source]: https://github.com/select2/select2 select2-4.0.1/docs/_includes/000077500000000000000000000000001262616323400157575ustar00rootroot00000000000000select2-4.0.1/docs/_includes/examples/000077500000000000000000000000001262616323400175755ustar00rootroot00000000000000select2-4.0.1/docs/_includes/examples/basics.html000066400000000000000000000026531262616323400217350ustar00rootroot00000000000000

    The basics

    Single select boxes

    Select2 can take a regular select box like this...

    and turn it into this...

    
    
    
    
      

    Multiple select boxes

    Select2 also supports multi-value select boxes. The select below is declared with the multiple attribute.

    
    
    
    
    
    select2-4.0.1/docs/_includes/examples/data.html000066400000000000000000000075701262616323400214050ustar00rootroot00000000000000

    Data sources

    In addition to handling options from a standard <select>, Select2 can also retrieve the results from other data sources.

    Loading array data

    Select2 provides a way to load the data from a local array. You can provide initial selections with array data by providing the option tag for the selected values, similar to how it would be done for a standard select.

    
    
    
    
      

    Loading remote data

    Select2 comes with AJAX support built in, using jQuery's AJAX methods. In this example, we can search for repositories using GitHub's API.

    When using Select2 with remote data, the HTML required for the select is the same as any other Select2. If you need to provide default selections, you just need to include an option for each selection that contains the value and text that should be displayed.

    
    
      

    You can configure how Select2 searches for remote data using the ajax option. More information on the individual options that Select2 handles can be found in the options documentation for ajax.

    
    
      

    Select2 will pass any options in the ajax object to jQuery's $.ajax function, or the transport function you specify.

    select2-4.0.1/docs/_includes/examples/disabled-mode.html000066400000000000000000000025141262616323400231560ustar00rootroot00000000000000

    Disabled mode

    Select2 will respond to the disabled attribute on <select> elements. You can also initialize Select2 with disabled: true to get the same effect.

    
    
    
    
    
    select2-4.0.1/docs/_includes/examples/disabled-results.html000066400000000000000000000017001262616323400237270ustar00rootroot00000000000000

    Disabled results

    Select2 will correctly handle disabled results, both with data coming from a standard select (when the disabled attribute is set) and from remote sources, where the object has disabled: true set.

    
    
    
    
    
    select2-4.0.1/docs/_includes/examples/hide-search.html000066400000000000000000000012151262616323400226360ustar00rootroot00000000000000

    Hiding the search box

    Select2 allows you to hide the search box depending on the number of options which are displayed. In this example, we use the value Infinity to tell Select2 to never display the search box.

    
    
    
    
    
    select2-4.0.1/docs/_includes/examples/localization-rtl-diacritics.html000066400000000000000000000045101262616323400260660ustar00rootroot00000000000000

    Localization, RTL and diacritics support

    Multiple languages

    Select2 supports displaying the messages in different languages, as well as providing your own custom messages that can be displayed.

    The language does not have to be defined when Select2 is being initialized, but instead can be defined in the [lang] attribute of any parent elements as [lang="es"].

    
    
    
    
      

    RTL support

    Select2 will work on RTL websites if the dir attribute is set on the <select> or any parents of it. You can also initialize Select2 with dir: "rtl" set.

    
    
    
    
      

    Diacritics support

    Select2's default matcher will ignore diacritics, making it easier for users to filter results in international selects. Type "aero" into the select below.

    
    
    
    
    
    select2-4.0.1/docs/_includes/examples/matcher.html000066400000000000000000000021461262616323400221110ustar00rootroot00000000000000

    Customizing how results are matched

    Unlike other dropdowns on this page, this one matches options only if the term appears in the beginning of the string as opposed to anywhere:

    This custom matcher uses a compatibility module that is only bundled in the full version of Select2. You also have the option of using a more complex matcher.

    
    
    
    
    
    select2-4.0.1/docs/_includes/examples/multiple-max.html000066400000000000000000000013421262616323400231010ustar00rootroot00000000000000

    Limiting the number of selections

    Select2 multi-value select boxes can set restrictions regarding the maximum number of options selected. The select below is declared with the multiple attribute with maximumSelectionLength in the select2 options.

    
    
    
    
    
    select2-4.0.1/docs/_includes/examples/placeholders.html000066400000000000000000000020031262616323400231230ustar00rootroot00000000000000

    Placeholders

    A placeholder value can be defined and will be displayed until a selection is made. Select2 uses the placeholder attribute on multiple select boxes, which requires IE 10+. You can support it in older versions with the Placeholders.js polyfill.

    
    
    
    
    
    select2-4.0.1/docs/_includes/examples/programmatic-control.html000066400000000000000000000117611262616323400246340ustar00rootroot00000000000000

    Programmatic control

    DOM events

    Select2 will trigger some events on the original select element, allowing you to integrate it with other components. You can find more information on events on the options page.

    change is fired whenever an option is selected or removed.

    select2:open is fired whenever the dropdown is opened. select2:opening is fired before this and can be prevented.

    select2:close is fired whenever the dropdown is closed. select2:closing is fired before this and can be prevented.

    select2:select is fired whenever a result is selected. select2:selecting is fired before this and can be prevented.

    select2:unselect is fired whenever a result is unselected. select2:unselecting is fired before this and can be prevented.

    
    
    
    
      

    Programmatic access

    Select2 supports methods that allow programmatic control of the component.

    
    
    
    
    
    select2-4.0.1/docs/_includes/examples/tags.html000066400000000000000000000014341262616323400214230ustar00rootroot00000000000000

    Tagging support

    Select2 can be used to quickly set up fields used for tagging.

    Note that when tagging is enabled the user can select from pre-existing options or create a new tag by picking the first choice, which is what the user has typed into the search box so far.

    
    
    
    
    
    select2-4.0.1/docs/_includes/examples/themes-templating-responsive-design.html000066400000000000000000000060101262616323400275510ustar00rootroot00000000000000

    Themes, templating and responsive design

    Theme support

    Select2 supports custom themes using the theme option so you can style Select2 to match the rest of your application.

    These are using the classic theme, which matches the old look of Select2.

    
    
    
    
    

    Templating

    Various display options of the Select2 component can be changed: You can access the <option> element (or <optgroup>) and any attributes on those elements using .element.

    Templating is primarily controlled by the templateResult and templateSelection options.

    
    
    
    
    

    Responsive design - Percent width

    Select2's width can be set to a percentage of its parent to support responsive design. The two Select2 boxes below are styled to 50% and 75% width respectively.

    
    
    
    Select2 will do its best to resolve the percent width specified via a css class, but it is not always possible. The best way to ensure that Select2 is using a percent based width is to inline the style declaration into the tag.
    select2-4.0.1/docs/_includes/examples/tokenizer.html000066400000000000000000000015641262616323400225030ustar00rootroot00000000000000

    Automatic tokenization

    Select2 supports ability to add choices automatically as the user is typing into the search field. Try typing in the search field below and entering a space or a comma.

    The separators that should be used when tokenizing can be specified using the tokenSeparators options.

    
    
    
    
    
    select2-4.0.1/docs/_includes/footer.html000066400000000000000000000021151262616323400201420ustar00rootroot00000000000000 select2-4.0.1/docs/_includes/ga.html000066400000000000000000000006631262616323400172410ustar00rootroot00000000000000 select2-4.0.1/docs/_includes/head.html000066400000000000000000000015131262616323400175460ustar00rootroot00000000000000 {{ page.title }} select2-4.0.1/docs/_includes/js-source-states.html000066400000000000000000000045271262616323400220700ustar00rootroot00000000000000 select2-4.0.1/docs/_includes/nav/000077500000000000000000000000001262616323400165435ustar00rootroot00000000000000select2-4.0.1/docs/_includes/nav/announcements-4.0.html000066400000000000000000000020671262616323400226120ustar00rootroot00000000000000 select2-4.0.1/docs/_includes/nav/examples.html000066400000000000000000000044261262616323400212550ustar00rootroot00000000000000 select2-4.0.1/docs/_includes/nav/options-old.html000066400000000000000000000043711262616323400217050ustar00rootroot00000000000000 select2-4.0.1/docs/_includes/nav/options.html000066400000000000000000000052741262616323400211340ustar00rootroot00000000000000 select2-4.0.1/docs/_includes/navigation.html000066400000000000000000000037721262616323400210150ustar00rootroot00000000000000 select2-4.0.1/docs/_includes/notice-previous.html000066400000000000000000000004561262616323400220050ustar00rootroot00000000000000
    Looking for the Select2 3.5.2 docs? We have moved them to a new location while we push forward with Select2 4.0.
    select2-4.0.1/docs/_includes/options-old/000077500000000000000000000000001262616323400202265ustar00rootroot00000000000000select2-4.0.1/docs/_includes/options-old/adapters.html000066400000000000000000000147201262616323400227230ustar00rootroot00000000000000

    Select2 allows plugins to add additional functionality through the core adapters. You can change almost anything involving the way Select2 works to the way Select2 interacts with the page by modifying the core adapters. Most third-party plugins should provide decorators (used to wrap adapters) and custom adapters that you can use.

    Each adapter contains a set of methods which will must always be defined. Along with the global methods that all adapters must implement, these methods must be implemented.

    All adapters

    All adapters must implement a set of methods that Select2 will use to display them and bind any internal events.

    // The basic HTML that should be rendered by Select2. A jQuery or DOM element
    // should be returned, which will automatically be placed by Select2 within the
    // DOM.
    //
    // @returns A jQuery or DOM element that contains any elements that must be
    //   rendered by Select2.
    Adapter.render = function () {
      return $jq;
    };
    
    // Bind to any Select2 or DOM events.
    //
    // @param container The Select2 object that is bound to the jQuery element.  You
    //   can listen to Select2 events with `on` and trigger Select2 events using the
    //   `trigger` method.
    // @param $container The jQuery DOM node that all default adapters will be
    //   rendered within.
    Adapter.bind = function (container, $container) { };
    
    // Position the DOM element within the Select2 DOM container, or in another
    // place. This allows adapters to be located outside of the Select2 DOM,
    // such as at the end of the document or in a specific place within the Select2
    // DOM node.
    //
    // Note: This method is not called on data adapters.
    //
    // @param $rendered The rendered DOM element that was returned from the call to
    //   `render`. This may have been modified by Select2, but the root element
    //   will always be the same.
    // @param $defaultContainer The default container that Select2 will typically
    //   place the rendered DOM element within. For most adapters, this is the
    //   Select2 DOM element.
    Adapter.position = function ($rendered, $defaultContainer) { };
    
    // Destroy any events or DOM elements that have been created.
    // This is called when `select2("destroy")` is called on an element.
    Adapter.destroy = function () { };
    

    Container (selection)

    The selection is what is shown to the user as a replacement of the standard <select> box. It controls the display of the selection option(s), as well anything else that needs to be embedded within the container, such as a search box.

    Key
    selectionAdapter
    Default
    SingleSelection or MultipleSelection
    Base
    BaseSelection
    // Update the selected data.
    //
    // @param data An array of data objects that have been generated by the data
    //   adapter. If no objects should be selected, an empty array will be passed.
    //
    // Note: An array will always be passed into this method, even if Select2 is
    // attached to a source which only accepts a single selection.
    SelectionAdapter.update = function (data) { };
    

    Data set

    The data set is what Select2 uses to generate the possible results that can be selected, as well as the currently selected results.

    Key
    dataAdapter
    Default
    SelectAdapter
    Base
    BaseAdapter
    // Get the currently selected options. This is called when trying to get the
    // initial selection for Select2, as well as when Select2 needs to determine
    // what options within the results are selected.
    //
    // @param callback A function that should be called when the current selection
    //   has been retrieved. The first parameter to the function should be an array
    //   of data objects.
    DataAdapter.current = function (callback) {
      callback(currentData);
    }
    
    // Get a set of options that are filtered based on the parameters that have
    // been passed on in.
    //
    // @param params An object containing any number of parameters that the query
    //   could be affected by. Only the core parameters will be documented.
    // @param params.term A user-supplied term. This is typically the value of the
    //   search box, if one exists, but can also be an empty string or null value.
    // @param params.page The specific page that should be loaded. This is typically
    //   provided when working with remote data sets, which rely on pagination to
    //   determine what objects should be displayed.
    // @param callback The function that should be called with the queried results.
    DataAdapter.query = function (params, callback) {
      callback(queryiedData);
    }
    

    The dropdown adapter defines the main container that the dropdown should be held in. It does not define any extra methods that can be used for decorators, but it is common for decorators to attach to the render and position methods to alter how the dropdown is altered and positioned.

    Key
    dropdownAdapter
    Default
    DropdownAdapter

    Results

    The results adapter controls the list of results that the user can select from. While the results adapter does not define any additional methods that must be implemented, it makes extensive use of the Select2 event system for controlling the display of results and messages.

    Key
    resultsAdapter
    Default
    ResultsAdapter
    select2-4.0.1/docs/_includes/options-old/backwards-compatibility.html000066400000000000000000000136471262616323400257370ustar00rootroot00000000000000

    Select2 offers limited backwards compatibility with the previously 3.5.x release line, allowing people more efficiently transfer across releases and get the latest features. For many of the larger changes, such as the change in how custom data adapters work, compatibility modules were created that will be used to assist in the upgrade process. It is not recommended to rely on these compatibility modules, as they will not always exist, but they make upgrading easier for major changes.

    The compatibility modules are only included in the full builds of Select2. These files end in .full.js, and the compatibility modules are prefixed with select2/compat.

    Simplified function for matching data objects

    Added in Select2 4.0.0. This method was added to make upgrading easier from earlier versions of Select2.

    During the Select2 4.0.0 release, the matcher function was changed to allow for more complex matching of nested objects.

    Key
    matcher
    Value
    A function taking a search term and the data object text.
    Adapter
    oldMatcher

    The custom matcher example provides a guide for how to use this in your own application. For those upgrading from older versions of Select2, you just need to wrap your old matcher with this function to maintain compatibility.

    Old initial selections with initSelection

    Deprecated in Select2 4.0. This has been replaced by another option and is only available in the full builds of Select2.

    In the past, Select2 required an option called initSelection that was defined whenever a custom data source was being used, allowing for the initial selection for the component to be determined. This has been replaced by the current method on the data adapter.

    Key
    initSelection
    Value
    A function taking a callback
    Adapter
    DataAdapter
    Decorator
    InitSelection

    Querying old data with query

    Deprecated in Select2 4.0. This has been replaced by another option and is only available in the full builds of Select2.

    In the past, Select2 supported an option called query that allowed for a custom data source to be used. This option has been replaced by the query method on the data adapter and takes a very similar set of parameters.

    Key
    query
    Value
    A function taking params (including a callback)
    Adapter
    DataAdapter
    Decorator
    Query

    Compatibility with <input type="text" />

    Deprecated in Select2 4.0. It is now encouraged to use the <select> tag instead.

    In past versions of Select2, a <select> element could only be used with a limited subset of options. An <input type="hidden" /> was required instead, which did not allow for a graceful fallback for users who did not have JavaScript enabled. Select2 now supports the <select> element for all options, so it is no longer required to use <input /> elements with Select2.

    Adapter
    DataAdapter
    Decorator
    InputData
    select2-4.0.1/docs/_includes/options-old/core-options.html000066400000000000000000000554361262616323400235520ustar00rootroot00000000000000

    Core options

    Select2 supports a small subset of options in every build that is generated. Each option typically has a decorator that is required that wraps an adapter, adding support for the option. This is only required when a custom adapter is being used, as Select2 will build the required adapters by default.

    Select2 will automatically apply decorators to any adapters which have not been manually overridden. The only time you need to decorate adapters is when you are using third-party adapters not provided by Select2, or you are using features not provided in the Select2 core. You can apply a decorator to an adapter using the Utils.Decorate method provided with Select2.

    $.fn.select2.amd.require(
        ["select2/utils", "select2/selection/single", "select2/selection/placeholder"],
        function (Utils, SingleSelection, Placeholder) {
      var CustomSelectionAdapter = Utils.Decorate(SingleSelection, Placeholder);
    });
    

    All core options that use decorators or adapters will clearly state it in the "Decorator" or "Adapter" part of the documentation. Decorators are typically only compatible with a specific type of adapter, so make sure to note what adapter is given.

    Declaring configuration in the data-* attributes

    It is recommended that you declare your configuration options for Select2 when initializing Select2. You can also define your configuration options by using the HTML5 data-* attributes, which will override any options set when initializing Select2 and any defaults.

    This means that if you declare your <select> tag as...

    <select data-tags="true" data-placeholder="Select an option"></select>
    

    Will be interpreted the same as initializing Select2 as...

    $("select").select2({
      tags: "true",
      placeholder: "Select an option"
    });
    

    You can also define nested configurations, which are typically needed for options such as AJAX. Each level of nesting should be separated by two dashes (--) instead of one. Due to a jQuery bug, nested options using data-* attributes do not work in jQuery 1.x.

    <select data-ajax--url="http://example.org/api/test" data-ajax--cache="true"></select>
    

    Which will be interpreted the same as initializing Select2 with...

    $("select").select2({
      ajax: {
        url: "http://example.org/api/test",
        cache: "true"
      }
    });
    

    The value of the option is subject to jQuery's parsing rules for HTML5 data attributes.

    AMD compatibility

    You can find more information on how to integrate Select2 with your existing AMD-based project by viewing the 4.0 release notes. Select2 automatically loads some modules when the adapters are being automatically constructed, so those who are using Select2 with a custom AMD build using their own system may need to specify the paths that are generated to the Select2 modules.

    Key
    amdBase
    Default
    select2/
    Key
    amdLanguageBase
    Default
    select2/i18n/

    Displaying selections

    Select2 provides options that allow you to directly affect how the container that holds the current selection is displayed.

    Placeholders

    Select2 can display a placeholder for a single-value select that will replace an option, or be shown when no options are selected for multiple-value selects. You can find an example on the example page.

    Key
    placeholder
    Value
    string or object

    Adapter
    SelectionAdapter
    Decorator
    Placeholder and HidePlaceholder
    Heads up! Because browsers assume that the first option in single-value select boxes is selected, you should add an empty <option></option> tag that the placeholder should use or it may not work.

    If the value is a string, the placeholder will be displayed when a blank option is used as the placeholder. The value will be the message to show to users as the placeholders.

    placeholder: "Select a repository"
    

    If the value is an object, the object should be compatible with Select2's internal objects. The id should be the id to look for when determining if the placeholder should be displayed. The text should be the placeholder to display when that option is selected.

    placeholder: {
      id: "-1",
      text: "Select a repository"
    }
    
    You should pass in an object when you are using a framework that creates its own placeholder option. The id should be the same as the value attribute on the option.

    You can allow a selected option to be cleared back to the placeholder by enabling the allowClear option.

    Key
    allowClear
    Value
    boolean
    Adapter
    SelectionAdapter
    Decorator
    AllowClear

    This will display an "x" that the user can click to clear the current selection. It is designed to be used for cases where a single selection can be made.

    Multiple selections

    Select2 can display either a single selection or multiple selections.

    Key
    multiple
    Value
    boolean (true or false)

    This option will determine what the SelectAdapter (used by default) should use to set the value of the underlying select element. It will also determine if the MultipleSelection adapter should be used.

    Container width

    Select2 will try to match the width of the original element as closely as possible. Sometimes this isn't perfect, which is what you can tell Select2 how to determine the width.

    Value Description
    "element" Uses javascript to calculate the width of the source element.
    "style" Copies the value of the width style attribute set on the source element.
    "resolve" Tries to use style to determine the width, falling back to element.
    Anything else The value of the width option is directly set as the width of the container.
    Key
    width
    Value
    string

    Internationalization (Language support)

    Messages will be displayed to users when necessary, such as when no search results were found or more characters need to be entered in order for a search to be made. These messages have been translated into many languages by contributors to Select2, but you can also provide your own translations.

    Key
    language
    Value
    object or string

    Module
    Translation

    Heads up! When using translations provided by Select2, you must make sure to include the translation file in your page after Select2.

    When a string is passed in as the language, Select2 will try to resolve it into a language file. This allows you to specify your own language files, which must be defined as an AMD module. If the language file cannot be found, Select2 will assume it is a language code controlled by Select2, and it will try to load the translations for that language instead.

    You can include your own translations by providing an object similar to the one below.

    language: {
      // You can find all of the options in the language files provided in the
      // build. They all must be functions that return the string that should be
      // displayed.
      inputTooShort: function () {
        return "You must enter more characters...";
      }
    }
    

    Templating results and selections

    By default, Select2 will display the option text within the list of results and when the option has been selected. Select2 comes with options that allow you to further customize the display of results and selections, allowing you to display them however you want.

    Customizing the display of selections

    When an option is displayed after it has been selected, it is passed through a formatting function that determines what is displayed. By default, the function only returns the text key of the data object.

    Key
    templateSelection
    Value
    A function taking a selection object
    Anything rendered as a selection is templated. This includes placeholders and pre-existing selections that are displayed, so you must ensure that your templating functions can support them.

    The templateSelection function should return a string containing the text to be displayed, or an object (such as a jQuery object) that contains the data that should be displayed.

    Strings are assumed to contain only text and will be passed through the escapeMarkup function, which strips any HTML markup.

    Anything else will be passed directly to jQuery.fn.append and will be handled directly by jQuery. Any markup, such as HTML, returned will not be escaped and it is up to you to escape any malicious input provided by users.

    Customizing the display of results

    When an option is displayed after it has been selected, it is passed through a formatting function that determines what is displayed. By default, the function only returns the text key of the data object.

    Key
    templateResult
    Value
    A function taking a result object
    Anything rendered in the results is templated. This includes results such as the "Searching..." and "Loading more..." text which will periodically be displayed, which allows you to add more advanced formatting to these automatically generated options.

    The templateResult function should return a string containing the text to be displayed, or an object (such as a jQuery object) that contains the data that should be displayed. It can also return null, which will prevent the option from being displayed in the results list.

    Strings are assumed to contain only text and will be passed through the escapeMarkup function, which strips any HTML markup.

    Anything else will be passed directly to jQuery.fn.append and will be handled directly by jQuery. Any markup, such as HTML, returned will not be escaped and it is up to you to escape any malicious input provided by users.

    Returning and displaying results

    Select2 can work on many different data sets ranging from local options, the same way that a <select> typically works, from remote options where a server generates the results that users can select from.

    Array

    Select2 allows creating the results based on an array of data objects that is included when initializing Select2.

    Key
    data
    Value
    array of objects
    Adapter
    ArrayAdapter

    The objects that the users can select from should be passed as an array with each object containing id and text properties.

    AJAX

    Select2 allows searching for results from remote data sources using AJAX requests.

    Key
    ajax
    Value
    object
    Adapter
    AjaxAdapter

    All options passed to this option will be directly passed to the $.ajax function that executes AJAX requests. There are a few custom options that Select2 will intercept, allowing you to customize the request as it is being made.

    ajax: {
      // The number of milliseconds to wait for the user to stop typing before
      // issuing the ajax request.
      delay: 250,
      // You can craft a custom url based on the parameters that are passed into the
      // request. This is useful if you are using a framework which has
      // JavaScript-based functions for generating the urls to make requests to.
      //
      // @param params The object containing the parameters used to generate the
      //   request.
      // @returns The url that the request should be made to.
      url: function (params) {
        return UrlGenerator.Random();
      },
      // You can pass custom data into the request based on the parameters used to
      // make the request. For `GET` requests, the default method, these are the
      // query parameters that are appended to the url. For `POST` requests, this
      // is the form data that will be passed into the request. For other requests,
      // the data returned from here should be customized based on what jQuery and
      // your server are expecting.
      //
      // @param params The object containing the parameters used to generate the
      //   request.
      // @returns Data to be directly passed into the request.
      data: function (params) {
        var queryParameters = {
          q: params.term
        }
    
        return queryParameters;
      },
      // You can modify the results that are returned from the server, allowing you
      // to make last-minute changes to the data, or find the correct part of the
      // response to pass to Select2. Keep in mind that results should be passed as
      // an array of objects.
      //
      // @param data The data as it is returned directly by jQuery.
      // @returns An object containing the results data as well as any required
      //   metadata that is used by plugins. The object should contain an array of
      //   data objects as the `results` key.
      processResults: function (data) {
        return {
          results: data
        };
      },
      // You can use a custom AJAX transport function if you do not want to use the
      // default one provided by jQuery.
      //
      // @param params The object containing the parameters used to generate the
      //   request.
      // @param success A callback function that takes `data`, the results from the
      //   request.
      // @param failure A callback function that indicates that the request could
      //   not be completed.
      // @returns An object that has an `abort` function that can be called to abort
      //   the request if needed.
      transport: function (params, success, failure) {
        var $request = $.ajax(params);
    
        $request.then(success);
        $request.fail(failure);
    
        return $request;
      }
    }
    

    Tags

    Users can create their own options based on the text that they have entered.

    Key
    tags
    Value
    boolean / array of objects
    Adapter
    DataAdapter
    Decorator
    Tags

    If the tags option is passed into Select2, if a user types anything into the search box which doesn't already exist, it will be displayed at the top and the user will be able to select it.

    For backwards compatibility, if an array of objects is passed in with the tags option, the options will be automatically created and the user will be able to select from them. This is the same as how array data works, and has similar limitations.

    Change how options are matched when searching

    When users filter down the results by entering search terms into the search box, Select2 uses an internal "matcher" to match search terms to results. When a remote data set is used, Select2 expects that the returned results have already been filtered.

    Key
    matcher
    Value
    A function taking search params and the data object.

    Select2 will pass the individual data objects that have been passed back from the data adapter into the matcher individually to determine if they should be displayed. Only the first-level objects will be passed in, so if you are working with nested data, you need to match those individually.

    matcher: function (params, data) {
      // If there are no search terms, return all of the data
      if ($.trim(params.term) === '') {
        return data;
      }
    
      // `params.term` should be the term that is used for searching
      // `data.text` is the text that is displayed for the data object
      if (data.text.indexOf(params.term) > -1) {
        var modifiedData = $.extend({}, data, true);
        modifiedData.text += ' (matched)';
    
        // You can return modified objects from here
        // This includes matching the `children` how you want in nested data sets
        return modifiedData;
      }
    
      // Return `null` if the term should not be displayed
      return null;
    }
    

    This allows for more advanced matching when working with nested objects, allowing you to handle them however you want. For those who are not looking to implement highly customized matching, but instead are just looking to change the matching algorithm for the text, a compatibility modules has been created to make it easier.

    select2-4.0.1/docs/_includes/options-old/dropdown.html000066400000000000000000000200761262616323400227550ustar00rootroot00000000000000

    Select2 allows you to change the way that the dropdown works, allowing you to do anything from attach it to a different location in the document or add a search box.

    By default, Select2 will attach the dropdown to the end of the body and will absolutely position it to appear below the selection container.

    Key
    dropdownParent
    Value
    jQuery element or DOM node

    Adapter
    DropdownAdapter
    Decorator
    AttachBody
    Heads up! This will cause DOM events to be raised outside of the standard Select2 DOM container. This can cause issues with third-party components such as modals.

    When the dropdown is attached to the body, you are not limited to just displaying the dropdown below the container. Select2 will display above the container if there is not enough space below the container, but there is enough space above it. You are also not limited to displaying the dropdown within the parent container, which means Select2 will render correctly inside of modals and other small containers.

    Select2 can place the dropdown directly after the selection container, so it will appear in the same location within the DOM as the rest of Select2.

    Adapter
    DropdownAdapter
    Decorator
    AttachContainer
    Check your build. This module is only included in the full builds of Select2.
    Harvest Chosen migrators! If you are migrating to Select2 from Chosen, this option will cause Select2 to position the dropdown in a similar way.

    Users can filter down the results by typing a search term into a box that is displayed at the top of the dropdown.

    Adapter
    DropdownAdapter
    Decorator
    DropdownSearch

    A search box is added to the top of the dropdown automatically for select boxes where only a single option can be selected.

    Sometimes when working with large data sets, it is more efficient to start filtering the results when the search term is a certain length. This is very common when working with remote data sets, as allows for only significant search terms to be used.

    Key
    minimumInputLength
    Value
    integer
    Adapter
    DataAdapter
    Decorator
    MinimumInputLength

    In some cases, search terms need to be limited to a certain range. Select2 allows you to limit the length of the search term such that it does not exceed a certain length.

    Key
    maximumInputLength
    Value
    integer
    Adapter
    DataAdapter
    Decorator
    MaximumInputLength

    When working with smaller data sets, the search box can take up more space that is necessary, as there are not enough results for filtering to be effective. Select2 allows you to only display the search box when the number of search results reaches a certain threshold.

    Key
    minimumResultsForSearch
    Value
    integer
    Adapter
    DropdownAdapter
    Decorator
    MinimumResultsForSearch

    When users close the dropdown, the last highlighted option can be automatically selected. This is commonly used in combination with tagging and placeholders and other situations where the user is required to select an option, or they need to be able to quickly select multiple options.

    Adapter
    ResultsAdapter
    Decorator
    SelectOnClose

    Close the dropdown when a result is selected

    Select2 will automatically close the dropdown when an element is selected, similar to what is done with a normal select box. This behavior can be changed though to keep the dropdown open when results are selected, allowing for multiple options to be selected quickly.

    Key
    closeOnSelect
    Default
    true
    Adapter
    DropdownAdapter
    Decorator
    CloseOnSelect

    If this decorator is not used (or closeOnSelect is set to false), the dropdown will not automatically close when a result is selected. The dropdown will also never close if the ctrl key is held down when the result is selected.

    select2-4.0.1/docs/_includes/options-old/events.html000066400000000000000000000025271262616323400224260ustar00rootroot00000000000000

    Select2 has an internal event system that is used to notify parts of the component that state has changed, as well as an adapter that allows some of these events to be relayed to the outside word.

    Adapter
    SelectionAdapter
    Decorator
    EventRelay

    Public events

    All public events are relayed using the jQuery event system, and they are triggered on the <select> element that Select2 is attached to. You can attach to them using the .on method provided by jQuery.

    Internal events

    Select2 triggers internal events using its own internal event system, which allows adapters to communicate with each other. These events are not accessible through the jQuery event system.

    You can find more information on the public events triggered by individual adapters in the individual adapter documentation.

    select2-4.0.1/docs/_includes/options-old/setting-default-options.html000066400000000000000000000025441262616323400257110ustar00rootroot00000000000000

    Setting default options

    In some cases, you need to set the default options for all instances of Select2 in your web application. This is especially useful when you are migrating from past versions of Select2, or you are using non-standard options like custom AMD builds. Select2 exposes the default options through $.fn.select2.defaults, which allows you to set them globally.

    When setting options globally, any past defaults that have been set will be overriden. Default options are only used when an option is requested that has not been set during initialization.

    You can set default options by calling $.fn.select2.defaults.set("key", "value"). The key that is set should take the same format as keys set using HTML data-* attributes which means that two dashes (--) will be replaced by a level of nesting, and a single dash (-) will convert it to a camelCase string.

    $.fn.select2.defaults.set("theme", "classic");
    

    You can reset the default options by calling $.fn.select2.defaults.reset().

    select2-4.0.1/docs/_includes/options/000077500000000000000000000000001262616323400174525ustar00rootroot00000000000000select2-4.0.1/docs/_includes/options/compatibility.html000066400000000000000000000004401262616323400232070ustar00rootroot00000000000000

    Backwards compatibility

    {% include options/compatibility/matcher.html %} {% include options/compatibility/initial-selection.html %} {% include options/compatibility/query-function.html %} {% include options/compatibility/text-input.html %}
    select2-4.0.1/docs/_includes/options/compatibility/000077500000000000000000000000001262616323400223235ustar00rootroot00000000000000select2-4.0.1/docs/_includes/options/compatibility/initial-selection.html000066400000000000000000000025711262616323400266320ustar00rootroot00000000000000

    Old initial selections with initSelection

    Deprecated in Select2 4.0. This has been replaced by another option and is only available in the full builds of Select2.

    In the past, Select2 required an option called initSelection that was defined whenever a custom data source was being used, allowing for the initial selection for the component to be determined. This has been replaced by the current method on the data adapter.

    Key
    initSelection
    Value
    A function taking a callback
    Adapter
    DataAdapter
    Decorator
    InitSelection
    select2-4.0.1/docs/_includes/options/compatibility/introduction.html000066400000000000000000000015171262616323400257360ustar00rootroot00000000000000

    Select2 offers limited backwards compatibility with the previously 3.5.x release line, allowing people more efficiently transfer across releases and get the latest features. For many of the larger changes, such as the change in how custom data adapters work, compatibility modules were created that will be used to assist in the upgrade process. It is not recommended to rely on these compatibility modules, as they will not always exist, but they make upgrading easier for major changes.

    The compatibility modules are only included in the full builds of Select2. These files end in .full.js, and the compatibility modules are prefixed with select2/compat.

    select2-4.0.1/docs/_includes/options/compatibility/matcher.html000066400000000000000000000025431262616323400246400ustar00rootroot00000000000000

    Simplified function for matching data objects

    Added in Select2 4.0.0. This method was added to make upgrading easier from earlier versions of Select2.

    During the Select2 4.0.0 release, the matcher function was changed to allow for more complex matching of nested objects.

    Key
    matcher
    Value
    A function taking a search term and the data object text.
    Adapter
    oldMatcher

    The custom matcher example provides a guide for how to use this in your own application. For those upgrading from older versions of Select2, you just need to wrap your old matcher with this function to maintain compatibility.

    select2-4.0.1/docs/_includes/options/compatibility/query-function.html000066400000000000000000000025011262616323400261770ustar00rootroot00000000000000

    Querying old data with query

    Deprecated in Select2 4.0. This has been replaced by another option and is only available in the full builds of Select2.

    In the past, Select2 supported an option called query that allowed for a custom data source to be used. This option has been replaced by the query method on the data adapter and takes a very similar set of parameters.

    Key
    query
    Value
    A function taking params (including a callback)
    Adapter
    DataAdapter
    Decorator
    Query
    select2-4.0.1/docs/_includes/options/compatibility/text-input.html000066400000000000000000000020501262616323400253270ustar00rootroot00000000000000

    Compatibility with <input type="text" />

    Deprecated in Select2 4.0. It is now encouraged to use the <select> tag instead.

    In past versions of Select2, a <select> element could only be used with a limited subset of options. An <input type="hidden" /> was required instead, which did not allow for a graceful fallback for users who did not have JavaScript enabled. Select2 now supports the <select> element for all options, so it is no longer required to use <input /> elements with Select2.

    Adapter
    DataAdapter
    Decorator
    InputData
    select2-4.0.1/docs/_includes/options/core.html000066400000000000000000000002771262616323400212760ustar00rootroot00000000000000

    Core options

    {% include options/core/options.html %} {% include options/core/data-attributes.html %} {% include options/core/amd-support.html %}
    select2-4.0.1/docs/_includes/options/core/000077500000000000000000000000001262616323400204025ustar00rootroot00000000000000select2-4.0.1/docs/_includes/options/core/amd-support.html000066400000000000000000000024761262616323400235540ustar00rootroot00000000000000

    Can I use Select2 with my AMD or CommonJS loader?

    Yes, Select2 should work with most AMD or CommonJS loaders without any issues.

    How do I tell Select2 where to look for modules?

    For most AMD and CommonJS setups, the location of the data files used by Select2 will be automatically determined and handled without you needing to do anything.

    If you are using Select2 in a build environment where preexisting module names are changed during a build step, Select2 may not be able to find optional dependencies or language files. You can manually set the prefixes to use for these files using the amdBase and amdLanugageBase options.

    $.fn.select2.defaults.set('amdBase', 'select2/');
    $.fn.select2.defaults.set('amdLanguageBase', 'select2/i18n/');
    

    Select2 is being placed before jQuery in my JavaScript file

    Due to a bug in older versions of the r.js build tool, Select2 was sometimes placed before jQuery in then compiled build file. Because of this, Select2 will trigger an error because it won't be able to find or load jQuery.

    You can fix this issue by upgrading to a newer version of the r.js build tool.

    select2-4.0.1/docs/_includes/options/core/data-attributes.html000066400000000000000000000036751262616323400244000ustar00rootroot00000000000000

    Can I declare my configuration within the HTML?

    It is recommended that you declare your configuration options for Select2 when initializing Select2. You can also define your configuration options by using the HTML5 data-* attributes, which will override any options set when initializing Select2 and any defaults.

    How should camelCase options be written?

    This means that if you declare your <select> tag as...

    <select data-tags="true" data-placeholder="Select an option" data-allow-clear="true"></select>
    

    Will be interpreted the same as initializing Select2 as...

    $("select").select2({
      tags: "true",
      placeholder: "Select an option",
      allowClear: true
    });
    

    Are options with nested configurations supported?

    You can also define nested configurations, which are typically needed for options such as AJAX. Each level of nesting should be separated by two dashes (--) instead of one. Due to a jQuery bug, nested options using data-* attributes do not work in jQuery 1.x.

    <select data-ajax--url="http://example.org/api/test" data-ajax--cache="true"></select>
    

    Which will be interpreted the same as initializing Select2 with...

    $("select").select2({
      ajax: {
        url: "http://example.org/api/test",
        cache: "true"
      }
    });
    

    The value of the option is subject to jQuery's parsing rules for HTML5 data attributes.

    select2-4.0.1/docs/_includes/options/core/options.html000066400000000000000000000031451262616323400227660ustar00rootroot00000000000000

    How should Select2 be initialized?

    Can default options be set for all dropdowns?

    In some cases, you need to set the default options for all instances of Select2 in your web application. This is especially useful when you are migrating from past versions of Select2, or you are using non-standard options like custom AMD builds. Select2 exposes the default options through $.fn.select2.defaults, which allows you to set them globally.

    When setting options globally, any past defaults that have been set will be overriden. Default options are only used when an option is requested that has not been set during initialization.

    You can set default options by calling $.fn.select2.defaults.set("key", "value").

    $.fn.select2.defaults.set("theme", "classic");
    

    How can I set a default value for a nested option?

    The key that is set should take the same format as keys set using HTML data-* attributes which means that two dashes (--) will be replaced by a level of nesting, and a single dash (-) will convert it to a camelCase string.

    How can I reset all of the global default options?

    You can reset the default options by calling

    $.fn.select2.defaults.reset();
    
    select2-4.0.1/docs/_includes/options/data.html000066400000000000000000000002561262616323400212540ustar00rootroot00000000000000

    Data adapters

    {% include options/data/select.html %} {% include options/data/array.html %} {% include options/data/ajax.html %}
    select2-4.0.1/docs/_includes/options/data/000077500000000000000000000000001262616323400203635ustar00rootroot00000000000000select2-4.0.1/docs/_includes/options/data/ajax.html000066400000000000000000000053371262616323400222040ustar00rootroot00000000000000

    Can Select2 be connected to a remote data source?

    Select2 supports connecting to a remote data source using the ajax option.

    How can I set the initially selected options when using AJAX?

    You can refer to the following Stack Overflow answer if you want to set the initial value for AJAX requests: Select2 4.0.0 initial value with AJAX

    What should the results returned to Select2 look like?

    {% include options/not-written.html %}

    Is there a way to modify the response before passing it back to Select2?

    You can use the ajax.processResults option to modify the data returned from the server before passing it to Select2.

    $('select').select2({
      ajax: {
        url: '/example/api',
        processResults: function (data) {
          return {
            results: data.items
          };
        }
      }
    });
    

    A request is being triggered on every key stroke, can I delay this?

    By default, Select2 will trigger a new AJAX request whenever the user changes their search term. You can set a time limit for debouncing requests using the ajax.delay option.

    $('select').select2({
      ajax: {
        url: '/example/api',
        delay: 250
      }
    });
    

    This will tell Select2 to wait 250 milliseconds before sending the request out to your API.

    I want to add more query parameters to the request, where can this be done?

    By default, Select2 will send the query term as well as the pagination data as query parameters in requests. You can override the data that is sent to your API, or change any of the query paramters, by overriding the ajax.data option.

    $('select').select2({
      ajax: {
        data: function (params) {
          var query = {
            search: params.term,
            page: params.page
          }
    
          // Query paramters will be ?search=[term]&page=[page]
          return query;
        }
      }
    });
    

    Can an AJAX plugin other than jQuery.ajax be used?

    Select2 uses the transport method defined in ajax.transport to send requests to your API. By default, this transport method is jQuery.ajax but this can be changed.

    $('select').select2({
      ajax: {
        transport: function (params, success, failure) {
          var request = new AjaxRequest(params.url, params);
          request.on('success', success);
          request.on('failure', failure);
        }
      }
    });
    
    select2-4.0.1/docs/_includes/options/data/array.html000066400000000000000000000026011262616323400223660ustar00rootroot00000000000000

    Can I load data into Select2 using an array?

    Yes, but only when you are initially creating it.

    What properties are required on the objects passed in to the array?

    The id and text properties are required on each object, and these are the properties that Select2 uses for the internal data objects. Any additional paramters passed in with data objects will be included on the data objects that Select2 exposes.

    How should nested results be formatted?

    How many levels of nesting are allowed?

    Because Select2 falls back to an <optgroup> when creating nested options, only a single level of nesting can be supported.

    Why are <option> tags being created?

    The data option is a shortcut that Select2 provides which allows you to load options into your select from a data array.

    My objects don't use id for their unique identifiers, what can I do?

    You can re-map your identifier before passing it to Select2.

    My objects use a property other than text for the text that needs to be displayed

    These can also be re-mapped.

    select2-4.0.1/docs/_includes/options/data/select.html000066400000000000000000000024121262616323400225270ustar00rootroot00000000000000

    Can Select2 be used with a <select> tag?

    Does Select2 support nesting options?

    Yes, just like in a standard select.

    How many levels of nesting can there be?

    Only a single level of nesting is allowed per the HTML specification.

    Can <optgroup> tags be made selectable?

    No. This is a limitation of the HTML specification and is not a limitation that Select2 can overcome.

    How are <option> and <optgroup> tags serialized into data objects?

    Select2 will convert the <option> tag into a data object based on the following rules.

    {
      "id": "value attribute" || "option text",
      "text": "label attribute" || "option text",
      "element": HTMLOptionElement
    }
    

    And <optgroup> tags will be converted into data objects using the following rules

    {
      "text": "label attribute",
      "children": [ option data object, ... ],
      "elment": HTMLOptGroupElement
    }
    
    select2-4.0.1/docs/_includes/options/dropdown.html000066400000000000000000000003311262616323400221710ustar00rootroot00000000000000

    Displaying results

    {% include options/dropdown/filtering.html %} {% include options/dropdown/selections.html %} {% include options/dropdown/placement.html %}
    select2-4.0.1/docs/_includes/options/dropdown/000077500000000000000000000000001262616323400213065ustar00rootroot00000000000000select2-4.0.1/docs/_includes/options/dropdown/filtering.html000066400000000000000000000007321262616323400241610ustar00rootroot00000000000000

    Can I change when search results are loaded?

    Can Select2 wait until the user has typed a search term before triggering the request?

    {% include options/not-written.html %}

    Select2 is allowing long search terms, can this be prevented?

    {% include options/not-written.html %}

    I only want the search box if there are enough results

    {% include options/not-written.html %}
    select2-4.0.1/docs/_includes/options/dropdown/placement.html000066400000000000000000000011711262616323400241440ustar00rootroot00000000000000

    Can I change how the dropdown is placed?

    {% include options/not-written.html %} {% include options/not-written.html %}

    I'm using a Bootstrap modal and I can't use the search box

    {% include options/not-written.html %}

    I'm using jQuery UI and I can't use the search box

    {% include options/not-written.html %}
    select2-4.0.1/docs/_includes/options/dropdown/selections.html000066400000000000000000000005211262616323400243420ustar00rootroot00000000000000

    Can I change how selecting results works?

    Can I select the highlighted result when the dropdown is closed?

    {% include options/not-written.html %}

    Can I prevent the dropdown from closing when a result is selected?

    {% include options/not-written.html %}
    select2-4.0.1/docs/_includes/options/events.html000066400000000000000000000002071262616323400216430ustar00rootroot00000000000000

    Events

    {% include options/events/jquery.html %} {% include options/events/internal.html %}
    select2-4.0.1/docs/_includes/options/events/000077500000000000000000000000001262616323400207565ustar00rootroot00000000000000select2-4.0.1/docs/_includes/options/events/internal.html000066400000000000000000000004471262616323400234650ustar00rootroot00000000000000

    Internal Select2 events

    Select2 has an internal event system that works independently of the DOM event system. This internal event system is only accesssible from plugins and adapters that are connected to Select2.

    select2-4.0.1/docs/_includes/options/events/jquery.html000066400000000000000000000010101262616323400231530ustar00rootroot00000000000000

    Public jQuery events

    What events will Select2 trigger?

    {% include options/not-written.html %}

    How can I attach listeners for these events?

    {% include options/not-written.html %}

    What events does Select2 listen for?

    {% include options/not-written.html %}

    What events can be prevented? How can I prevent a selection from being made?

    {% include options/not-written.html %}
    select2-4.0.1/docs/_includes/options/introduction.html000066400000000000000000000011241262616323400230570ustar00rootroot00000000000000
    This page of the documentation is currently undergoing a rewrite and may be incomplete. If you do not find the answer you are looking for on this page, you may have better luck looking at the old options page.

    This documentation is set up in the form of a FAQ and covers the most common questions. If you do not find the answer to your question here, you may want to reach out to the community to see if someone else can answer it.

    select2-4.0.1/docs/_includes/options/not-written.html000066400000000000000000000004561262616323400226370ustar00rootroot00000000000000
    This answer to this question has not yet been written. You can improve this documentation by creating a pull request with an answer to this question.
    select2-4.0.1/docs/_includes/options/selections.html000066400000000000000000000004421262616323400225100ustar00rootroot00000000000000

    Displaying selections

    {% include options/selections/multiple.html %} {% include options/selections/placeholder.html %} {% include options/selections/clearing-selections.html %} {% include options/selections/templating.html %}
    select2-4.0.1/docs/_includes/options/selections/000077500000000000000000000000001262616323400216225ustar00rootroot00000000000000select2-4.0.1/docs/_includes/options/selections/clearing-selections.html000066400000000000000000000005221262616323400264410ustar00rootroot00000000000000

    Can I allow users to clear their selections?

    The "x" icon is not clearing the selection

    {% include options/not-written.html %}

    Can users remove all of their selections in a multiple select at once?

    {% include options/not-written.html %}
    select2-4.0.1/docs/_includes/options/selections/multiple.html000066400000000000000000000010351262616323400243420ustar00rootroot00000000000000

    Can I allow users to make multiple selections?

    Yes, Select2 supports making multiple selections through the use of the multiple option that can be passed in when initializing Select2.

    Can the multiple attribute be used on my <select> element?

    Yes, Select2 will automatically map the value of the multiple attribute to the multiple option during initialization.

    select2-4.0.1/docs/_includes/options/selections/placeholder.html000066400000000000000000000037211262616323400247750ustar00rootroot00000000000000

    How can I have Select2 display a placeholder?

    Select2 supports displaying a placeholder by default using the placeholder option. This can be either a data object matching the placeholder option, or a string to display as the placeholder if you are using a blank placeholder option.

    My first option is being displayed instead of my placeholder

    This usually means that you do not have a blank <option></option> as the first option in your <select>.

    Note that this does not apply to multiple selects, as the browser does not select the first option by default when multiple selections can be made.

    I am using AJAX, can I still show a placeholder?

    Yes, Select2 supports placeholders for all configurations. You will still need to add in the placeholder option if you are using a single select.

    Can I use an option without a blank value as my placeholder?

    The placeholder option allows you to pass in a data object instead of just a string if you need more flexibility. The id of the data object should match the value of the placeholder option.

    Can I change how the placeholder looks?

    The placeholder option should go through the standard templating methods, including templateSelection, so you can change how it is displayed.

    My placeholders aren't being displayed in Internet Explorer

    Select2 uses the native placeholder attribute on input boxes for the multiple select, and that attribute is not supported in older versions of Internet Explorer. You need to include Placeholders.js on your page, or use the full build, in order to add placeholder attribute support to input boxes.

    select2-4.0.1/docs/_includes/options/selections/templating.html000066400000000000000000000007461262616323400246630ustar00rootroot00000000000000

    How can I customize the way selections are displayed?

    Nothing is being displayed when I select an option

    {% include options/not-written.html %}

    I am using HTML in my selection template but it isn't displaying it

    {% include options/not-written.html %}

    How can I access the container where the selection is displayed?

    {% include options/not-written.html %}
    select2-4.0.1/docs/_includes/social-buttons.html000066400000000000000000000007651262616323400216230ustar00rootroot00000000000000
    select2-4.0.1/docs/_layouts/000077500000000000000000000000001262616323400156515ustar00rootroot00000000000000select2-4.0.1/docs/_layouts/default.html000066400000000000000000000025011262616323400201610ustar00rootroot00000000000000 {% include head.html %} {% include navigation.html %} {{ content }} {% include footer.html %} {% include ga.html %} select2-4.0.1/docs/_layouts/home.html000066400000000000000000000005201262616323400174640ustar00rootroot00000000000000 {% include head.html %} {% include navigation.html %} {{ content }} {% include footer.html %} {% include ga.html %} select2-4.0.1/docs/_sass/000077500000000000000000000000001262616323400151225ustar00rootroot00000000000000select2-4.0.1/docs/_sass/_alert.scss000066400000000000000000000014061262616323400172660ustar00rootroot00000000000000// Alerts // // Modify Bootstrap's default alert styles to mimick // the `.bs-callout` styles from Bootstrap's docs. // // @see https://github.com/twbs/bootstrap/blob/master/docs/assets/css/src/docs.css#L711 // @see https://github.com/twbs/bootstrap/blob/master/less/alerts.less .alert { background: #fff; border: 1px solid #eee; border-left-width: 5px; border-radius: 3px; color: #333; margin: 20px 0; padding: 20px; h4 { font-size: 18px; margin-top: 0; margin-bottom: 5px; } &-danger { border-left-color: #ce4844; h4 { color: #ce4844; } } &-info { border-left-color: #1b809e; h4 { color: #1b809e; } } &-warning { border-left-color: #aa6708; h4 { color: #aa6708; } } } select2-4.0.1/docs/_sass/_anchorjs.scss000066400000000000000000000006121262616323400177640ustar00rootroot00000000000000// AnchorJS Styles .anchorjs-link { color: inherit; transition: all .16s linear; text-decoration: none; &:link, &:visited { text-decoration: none; color: inherit; } @media (max-width: 480px) { display: none; } } *:hover > .anchorjs-link { opacity: .5; margin-left: -0.9em !important; } *:hover > .anchorjs-link:hover, .anchorjs-link:focus { opacity: 1; } select2-4.0.1/docs/_sass/_buttons.scss000066400000000000000000000005021262616323400176510ustar00rootroot00000000000000// Buttons .btn-outline-inverse { color: #428BCA; background-color: transparent; border-color: #428BCA; padding: 15px 30px; font-size: 20px; transition: all .1s ease-in-out; &:hover { color: #fff; border-color: #428BCA; background-color: #428BCA; } } .btn-toolbar { margin-bottom: 20px; } select2-4.0.1/docs/_sass/_code.scss000066400000000000000000000004731262616323400170740ustar00rootroot00000000000000// Code (inline and block) // Inline code within headings retain the heading's background-color h2 code, h3 code, h4 code { background-color: inherit; } // Modify Bootstrap's styles for blocks of code pre { padding: 9px 14px; margin-bottom: 14px; background-color: #f7f7f9; border: 1px solid #e1e1e8; } select2-4.0.1/docs/_sass/_examples.scss000066400000000000000000000035621262616323400200020ustar00rootroot00000000000000// Examples // // Styles for the Select2 examples, largely copied // from Bootstrap's docs styles. // // @see https://github.com/twbs/bootstrap/blob/master/docs/assets/css/src/docs.css#L533 .s2-example { position: relative; padding: 45px 15px 15px; margin: 0 -15px 15px; background-color: #fafafa; box-shadow: inset 0 3px 6px rgba(0, 0, 0, 0.05); border-color: #e5e5e5 #eee #eee; border-style: solid; border-width: 1px 0; &:after { content: "Example"; position: absolute; top: 15px; left: 15px; font-size: 12px; font-weight: bold; color: #bbb; text-transform: uppercase; letter-spacing: 1px; } @media (min-width: 768px) { margin-left: 0; margin-right: 0; background-color: #fff; border-width: 1px; border-color: #eee; border-radius: 4px 4px 0 0; box-shadow: none; } } // styles for the event log in the "DOM events" section of the docs .s2-event-log { background: #002451; color: white; font-family: Menlo, 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', Monaco, Consolas, monospace; margin: 0 -15px 15px; padding: 45px 15px 15px; position: relative; &:after { content: "Event Log"; position: absolute; top: 15px; left: 15px; font-size: 12px; font-weight: bold; color: #BBB; text-transform: uppercase; letter-spacing: 1px; } @media (min-width: 768px) { margin-left: 0; margin-right: 0; margin-top: -15px; border-width: 1px; border-color: #eee; box-shadow: none; } } .s2-example + pre, .s2-event-log + pre { margin: -15px -15px 15px; border-radius: 0; border-width: 0 0 1px; @media (min-width: 768px) { margin-top: -16px; margin-left: 0; margin-right: 0; border-width: 1px; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; } } .s2-example + .s2-event-log { margin-top: -15px; } select2-4.0.1/docs/_sass/_featurette.scss000066400000000000000000000003011262616323400203200ustar00rootroot00000000000000// Homepage featurettes .s2-docs-featurette { color: #777; padding: 15px 0; text-align: center; h4 { margin: 30px 0 15px; } .fa { font-size: 28px; color: #777; } } select2-4.0.1/docs/_sass/_footer.scss000066400000000000000000000010521262616323400174520ustar00rootroot00000000000000// Footer .s2-docs-footer { border-top: 1px solid #eee; color: #767676; padding-top: 40px; padding-bottom: 40px; margin-top: 100px; text-align: center; &-links { padding-left: 0; margin-top: 20px; } &-links li { display: inline; padding: 0 2px; &:after { content: "·"; padding-left: 8px; } &:first-child { padding-left: 0; } &:last-child:after { content: ""; padding-left: 0; } } @media (min-width: 768px) { p { margin-bottom: 0; } } } select2-4.0.1/docs/_sass/_hamburger.scss000066400000000000000000000014721262616323400201360ustar00rootroot00000000000000// Animated hamburger icon // // Add an animation to Bootstrap's `.navbar-toggle` hamburger icon, // courtesy of Julien Melissas. // // @see http://codepen.io/JulienMelissas/pen/LEBGLj // @see http://julienmelissas.com/animated-x-icon-for-the-bootstrap-navbar-toggle/ .navbar-toggle { border: none; background: transparent !important; &:hover { background: transparent !important; } .icon-bar { width: 22px; transition: all 0.2s; } .top-bar { transform: rotate(45deg); transform-origin: 10% 10%; } .middle-bar { opacity: 0; } .bottom-bar { transform: rotate(-45deg); transform-origin: 10% 90%; } &.collapsed { .top-bar { transform: rotate(0); } .middle-bar { opacity: 1; } .bottom-bar { transform: rotate(0); } } } select2-4.0.1/docs/_sass/_home.scss000066400000000000000000000006661262616323400171160ustar00rootroot00000000000000// Homepage-specific styles .s2-docs-home { .jumbotron { margin-bottom: 0; color: #000; h1 { color: #000; margin-top: 20px; } } .lead { text-align: center; max-width: 800px; margin: 0 auto 40px; } .notice-previous { background: #f6f6f6; color: #666; border-bottom: 1px solid #eee; padding: 15px 20px; } .half-rule { width: 100px; margin: 40px auto; } } select2-4.0.1/docs/_sass/_jumbotron.scss000066400000000000000000000005711262616323400202000ustar00rootroot00000000000000// Jumbotron // // Modify Bootstrap's default `.jumbotron` styles. .jumbotron { background-color: #F6F6F6; border-bottom: 1px solid #eee; color: #777; padding-left: 0; padding-right: 0; h1 { color: #777; font-size: 36px; margin-top: 10px; } .version { color: #999; font-size: 14px; font-weight: normal; margin-bottom: 30px; } } select2-4.0.1/docs/_sass/_layout.scss000066400000000000000000000002331262616323400174710ustar00rootroot00000000000000// Layout .s2-docs-container { line-height: 1.6; } section { margin-bottom: 40px; } .page-header { padding-bottom: 19px; margin-bottom: 29px; } select2-4.0.1/docs/_sass/_nav.scss000066400000000000000000000022231262616323400167410ustar00rootroot00000000000000// Main navigation // // Styles for the top `.navbar` and its dropdowns. .s2-docs-nav { margin-bottom: 0; border-color: #eee; background-color: #f6f6f6; .navbar-brand { font-weight: 500; img { margin-right: 4px; } } .navbar-nav > .active > a, .navbar-nav > .active > a:hover, .navbar-nav > .active > a:focus { background-color: #f0f0f0; color: #000; } @media (min-width: 768px) { .navbar-nav > li > .dropdown-menu:before { position: absolute; top: -21px; left: 24px; display: block; width: 0; height: 0; border-color: rgba(0, 0, 0, 0) rgba(0, 0, 0, 0) rgba(0, 0, 0, 0.1); border-style: solid; border-width: 10px; content: ""; } .navbar-nav > li > .dropdown-menu:after { position: absolute; top: -20px; left: 24px; display: block; width: 0; height: 0; border-color: rgba(0, 0, 0, 0) rgba(0, 0, 0, 0) #FFF; border-style: solid; border-width: 10px; content: ''; } .navbar-nav .dropdown-menu { border-radius: 4px; border-color: #ddd; margin-top: -1px; } } } select2-4.0.1/docs/_sass/_prettify.scss000066400000000000000000000015041262616323400200240ustar00rootroot00000000000000// Google Code Prettify styles .com { color: #999; } .lit { color: #195f91; } .pun, .opn, .clo { color: #93a1a1; } .fun { color: #dc322f; } .str, .atv { color: #C7254E; } .kwd, .prettyprint .tag { color: #2F6F9F; } .typ, .atn, .dec, .var { /*color: teal;*/ color: #428BCA; } .pln { color: #333; } .prettyprint { padding: 9px 14px; margin-bottom: 20px; margin-top: 20px; border: 1px solid #eee; &.linenums { -webkit-box-shadow: inset 40px 0 0 #fbfbfb, inset 41px 0 0 #f6f6f6; -moz-box-shadow: inset 40px 0 0 #fbfbfb, inset 41px 0 0 #f6f6f6; box-shadow: inset 40px 0 0 #fbfbfb, inset 41px 0 0 #f6f6f6; } } // Specify class=linenums on a pre to get line numbering ol.linenums { margin: 0 0 0 -12px; li { padding-left: 12px; color: #bebebe; line-height: 18px; } } select2-4.0.1/docs/_sass/_result-repository.scss000066400000000000000000000016561262616323400217210ustar00rootroot00000000000000// Styles accompanying the "Loading remote data" example `templateResult .select2-result-repository { padding-top: 4px; padding-bottom: 3px; &__avatar { float: left; width: 60px; margin-right: 10px; img { width: 100%; height: auto; border-radius: 2px; } } &__meta { margin-left: 70px; } &__title { color: black; font-weight: bold; word-wrap: break-word; line-height: 1.1; margin-bottom: 4px; } &__forks, &__stargazers { margin-right: 1em; } &__forks, &__stargazers, &__watchers { display: inline-block; color: #aaa; font-size: 11px; } &__description { font-size: 13px; color: #777; margin-top: 4px; } .select2-results__option--highlighted & { &__title { color: white; } &__forks, &__stargazers, &__description, &__watchers { color: mix(#428BCA, white, 30%); } } } select2-4.0.1/docs/_sass/_sidenav.scss000066400000000000000000000055351262616323400176170ustar00rootroot00000000000000// Side navigation // // Scrollspy and affixed enhanced navigation to // highlight sections and secondary sections of docs content`. .s2-docs-sidebar { // By default it is not affixed in mobile views, so undo that &.affix { position: static; } @media (min-width: 768px) { padding-left: 20px; } } // First level of nav .s2-docs-sidenav { margin-top: 20px; margin-bottom: 20px; } // All levels of nav .s2-docs-sidebar .nav { > li > a { margin-left: -1px; display: block; padding: 4px 20px; font-size: 13px; font-weight: 500; color: #767676; border-left: 1px solid transparent; transition: color .2s, border-color .2s; } > li > a code { background-color: inherit; color: inherit; } > li > a:hover, > li > a:focus { color: #428BCA; text-decoration: none; background-color: transparent; border-left-color: #428BCA; } > .active > a, > .active:hover > a, > .active:focus > a { padding-left: 19px; font-weight: bold; color: #428BCA; background-color: transparent; border-left: 2px solid #428BCA; } // Nav: second level (shown on .active) .nav { display: none; // Hide by default, but at >768px, show it padding-bottom: 10px; } .nav > li > a { padding-top: 1px; padding-bottom: 1px; padding-left: 30px; font-size: 12px; font-weight: normal; } .nav > li > a:hover, .nav > li > a:focus { padding-left: 30px; } .nav > .active > a, .nav > .active:hover > a, .nav > .active:focus > a { padding-left: 29px; font-weight: 400; } } // Show and affix the side nav when space allows it @media (min-width: 992px) { .s2-docs-sidebar .s2-docs-sidenav { padding-top: 40px; transition: border-color .2s; border-left: 1px solid transparent; } .s2-docs-sidebar.affix .s2-docs-sidenav { border-left-color: #eee; } .s2-docs-sidebar .nav > .active > ul { display: block; } // Widen the fixed sidebar .s2-docs-sidebar.affix, .s2-docs-sidebar.affix-bottom { width: 213px; } // Undo the static from mobile first approach .s2-docs-sidebar.affix { position: fixed; top: 0px; } // Undo the static from mobile first approach .s2-docs-sidebar.affix-bottom { position: absolute; } .s2-docs-sidebar.affix-bottom .s2-docs-sidenav, .s2-docs-sidebar.affix .s2-docs-sidenav { margin-top: 0; margin-bottom: 0; } } @media (min-width: 1200px) { // Widen the fixed sidebar again .s2-docs-sidebar.affix-bottom, .s2-docs-sidebar.affix { width: 263px; } } /* Back to top (hidden on mobile) */ .back-to-top { display: none; padding: 4px 10px; margin-top: 10px; margin-left: 10px; font-size: 12px; font-weight: 400; color: #999; &:hover { color: #428BCA; text-decoration: none; } @media (min-width: 768px) { display: block; } } select2-4.0.1/docs/_sass/_social.scss000066400000000000000000000010611262616323400174260ustar00rootroot00000000000000// Social buttons // // Twitter and GitHub social action buttons. .s2-docs-social { margin-bottom: 20px; text-align: center; } .s2-docs-social-buttons { display: inline-block; padding-left: 0; margin-bottom: 0; list-style: none; li { display: inline-block; padding: 5px 8px; line-height: 1; } .twitter-follow-button { width: 225px !important; } .twitter-share-button { width: 98px !important; } } // Style the GitHub buttons via CSS instead of inline attributes .github-btn { overflow: hidden; border: 0; } select2-4.0.1/docs/_sass/_typography.scss000066400000000000000000000001001262616323400203530ustar00rootroot00000000000000// Typography h1[id] { padding-top: 20px; margin-top: 0; } select2-4.0.1/docs/announcements-4.0.html000066400000000000000000000670431262616323400200660ustar00rootroot00000000000000--- layout: default title: Select2 4.0.0 Released slug: announcements-4.0 ---

    Announcing Select2 4.0.0

    Select2 4.0.0

    The 4.0 release of Select2 is the result of three years of working on the code base and watching where it needs to go. At the core, it is a full rewrite that addresses many of the extensibility and usability problems that could not be addressed in previous versions.

    This release contains many breaking changes, but easy-upgrade paths have been created as well as helper modules that will allow for backwards compatibility to be maintained with past versions of Select2. Upgrading will require you to read the release notes carefully, but the migration path should be relatively straightforward. You can view a list of the most common changes that you will need to make in the release notes.

    Below is an in-depth review of what is new in Select2, as well as some of the major changes that have been made.

    New features

    The notable features of this new release include:

    • A more flexible plugin framework that allows you to override Select2 to behave exactly how you want it to.
    • Consistency with standard <select> elements for all data adapters, removing the need for hidden <input> elements.
    • A new build system that uses AMD to keep everything organized.
    • Less specific selectors allowing for Select2 to be styled to fit the rest of your application.

    Plugin system

    Select2 now provides interfaces that allow for it to be easily extended, allowing for anyone to create a plugin that changes the way Select2 works. This is the result of Select2 being broken into four distinct sections, each of which can be extended and used together to create your unique Select2.

    The adapters implement a consistent interface that is documented in the options section for adapters, allowing you to customize Select2 to do exactly what you are looking for. Select2 is designed such that you can mix and match plugins, with most of the core options being built as decorators that wrap the standard adapters.

    AMD-based build system

    Select2 now uses an AMD-based build system, allowing for builds that only require the parts of Select2 that you need. While a custom build system has not yet been created, Select2 is open source and will gladly accept a pull request for one.

    Select2 includes the minimal almond AMD loader, but a custom select2.amd.js build is available if you already use an AMD loader. The code base (available in the src directory) also uses AMD, allowing you to include Select2 in your own build system and generate your own builds alongside your existing infrastructure.

    The AMD methods used by Select2 are available as jQuery.fn.select2.amd.define()/require(), allowing you to use the included almond loader. These methods are primarily used by the translations, but they are the recommended way to access custom modules that Select2 provides.

    Migrating from Select2 3.5

    There are a few breaking changes that migrators should be aware of when they are coming from older versions of Select2.

    If you use the full build of Select2 (select2.full.js), you will be automatically notified of the major breaking changes, and compatibility modules will be used in some cases to ensure that your code still behaves how you were expecting.

    No more hidden input tags

    In past versions of Select2, an <input type="hidden" /> tag was recommended if you wanted to do anything advanced with Select2, such as work with remote data sources or allow users to add their own tags. This had the unfortunate side-effect of servers not receiving the data from Select2 as an array, like a standard <select> element does, but instead sending a string containing the comma-separated strings. The code base ended up being littered with special cases for the hidden input, and libraries using Select2 had to work around the differences it caused.

    In Select2 4.0, the <select> element supports all core options, and support for the old <input type="hidden" /> has been deprecated. This means that if you previously declared an AJAX field with some pre-selected options that looked like…

    <input type="hidden" name="select-boxes" value="1,2,4,6" />
    

    It will need to be recreated as a <select> element with some <option> tags that have value attributes that match the old value.

    <select name="select-boxes" multiple="multiple">
      <option value="1" selected="selected">Select2</option>
      <option value="2" selected="selected">Chosen</option>
      <option value="4" selected="selected">selectize.js</option>
      <option value="6" selected="selected">typeahead.js</option>
    </select>
    

    The options that you create should have selected="selected" set so Select2 and the browser knows that they should be selected. The value attribute of the option should also be set to the value that will be returned from the server for the result, so Select2 can highlight it as selected in the dropdown. The text within the option should also reflect the value that should be displayed by default for the option.

    Advanced matching of searches

    In past versions of Select2, when matching search terms to individual options, which limited the control that you had when displaying results, especially in cases where there was nested data. The matcher function was only given the individual option, even if it was a nested options, without any context.

    With the new matcher function, only the root-level options are matched and matchers are expected to limit the results of any children options that they contain. This allows developers to customize how options within groups can be displayed, and modify how the results are returned.

    A function has been created that allows old-style matcher functions to be converted to the new style. You can retrieve the function from the select2/compat/matcher module, which should just wrap the old matcher function.

    So if your old code used a matcher that only displayed options if they started with the term that was entered, it would look something like…

    function matchStart (term, text) {
      if (text.toUpperCase().indexOf(term.toUpperCase()) == 0) {
        return true;
      }
    
      return false;
    }
    
    $("select").select2({
      matcher: matchStart
    })
    

    Then in Select2 4.0, you would need to wrap the matchStart method (or the name of the matcher you created) with a oldMatcher method that we have created.

    function matchStart (term, text) {
      if (text.toUpperCase().indexOf(term.toUpperCase()) == 0) {
        return true;
      }
    
      return false;
    }
    
    $.fn.select2.amd.require(['select2/compat/matcher'], function (oldMatcher) {
      $("select").select2({
        matcher: oldMatcher(matchStart)
      })
    });
    

    This will work for any matchers that only took in the search term and the text of the option as parameters. If your matcher relied on the third parameter containing the jQuery element representing the original <option> tag, then you may need to slightly change your matcher to expect the full JavaScript data object being passed in instead. You can still retrieve the jQuery element from the data object using the data.element property.

    More flexible placeholders

    In the most recent versions of Select2, placeholders could only be applied to the first (typically the default) option in a <select> if it was blank. The placeholderOption option was added to Select2 to allow users using the select tag to select a different option, typically an automatically generated option with a different value.

    The placeholder option can now take an object as well as just a string. This replaces the need for the old placeholderOption, as now the id of the object can be set to the value attribute of the <option> tag.

    For a select that looks like the following, where the first option (with a value of -1) is the placeholder option…

    <select>
      <option value="-1" selected="selected">Select an option</option>
      <option value="1">Something else</option>
    </select>
    

    You would have previously had to get the placeholder option through the placeholderOption, but now you can do it through the placeholder option by setting an id.

    $("select").select2({
      placeholder: {
        id: "-1",
        placeholder: "Select an option"
      }
    })
    

    And Select2 will automatically display the placeholder when the value of the select is -1, which it will be by default. This does not break the old functionality of Select2 where the placeholder option was blank by default.

    Display reflects the actual order of the values

    In past versions of Select2, choices were displayed in the order that they were selected. In cases where Select2 was used on a <select> element, the order that the server received the selections did not always match the order that the choices were displayed, resulting in confusion in situations where the order is important.

    Select2 will now order selected choices in the same order that will be sent to the server.

    Changed method and option names

    When designing the future option set for Select2 4.0, special care was taken to ensure that the most commonly used options were brought over. For the most part, the commonly used options of Select2 can still be referenced under their previous names, but there were some changes which have been noted.

    Removed the requirement of initSelection

    In the past, whenever you wanted to use a custom data adapter, such as AJAX or tagging, you needed to help Select2 out in determining the initial values that were selected. This was typically done through the initSelection option, which took the underlying data of the input and converted it into data objects that Select2 could use.

    This is now handled by the data adapter in the current method, which allows Select2 to convert the currently selected values into data objects that can be displayed. The default implementation converts the text and value of option elements into data objects, and is probably suitable for most cases. An example of the old initSelection option is included below, which converts the value of the selected options into a data object with both the id and text matching the selected value.

    initSelection : function (element, callback) {
      var data = [];
      $(element.val()).each(function () {
        data.push({id: this, text: this});
      });
      callback(data);
    }
    

    When using the new current method of the custom data adapter, this method is called any time Select2 needs a list of the currently selected options. This is different from the old initSelection in that it was only called once, so it could suffer from being relatively slow to process the data (such as from a remote data source).

    $.fn.select2.amd.require([
      'select2/data/array',
      'select2/utils'
    ], function (ArrayData, Utils) {
      function CustomData ($element, options) {
        CustomData.__super__.constructor.call(this, $element, options);
      }
    
      Utils.Extend(CustomData, ArrayData);
    
      CustomData.prototype.current = function (callback) {
        var data = [];
        var currentVal = this.$element.val();
    
        if (!this.$element.prop('multiple')) {
          currentVal = [currentVal];
        }
    
        for (var v = 0; v < currentVal.length; v++) {
          data.push({
            id: currentVal[v],
            text: currentVal[v]
          });
        }
    
        callback(data);
      };
    
      $("#select").select2({
        dataAdapter: CustomData
      });
    }
    

    The new current method of the data adapter works in a similar way to the old initSelection method, with three notable differences. The first, and most important, is that it is called whenever the current selections are needed to ensure that Select2 is always displaying the most accurate and up to date data. No matter what type of element Select2 is attached to, whether it supports a single or multiple selections, the data passed to the callback must be an array, even if it contains one selection. The last is that there is only one parameter, the callback to be executed with the latest data, and the current element that Select2 is attached to is available on the class itself as this.$element.

    If you only need to load in the initial options once, and otherwise will be letting Select2 handle the state of the selections, you don't need to use a custom data adapter. You can just create the <option> tags on your own, and Select2 will pick up the changes.

    var $element = $('select').select2(); // the select element you are working with
    
    var $request = $.ajax({
      url: '/my/remote/source' // wherever your data is actually coming from
    });
    
    $request.then(function (data) {
      // This assumes that the data comes back as an array of data objects
      // The idea is that you are using the same callback as the old `initSelection`
    
      for (var d = 0; d < data.length; d++) {
        var item = data[d];
    
        // Create the DOM option that is pre-selected by default
        var option = new Option(item.text, item.id, true, true);
    
        // Append it to the select
        $element.append(option);
      }
    
      // Update the selected options that are displayed
      $element.trigger('change');
    });
    

    Custom data adapters instead of query

    In the past, any time you wanted to hook Select2 up to a different data source you would be required to implement custom query and initSelection methods. This allowed Select2 to determine the initial selection and the list of results to display, and it would handle everything else internally, which was fine more most people.

    The custom query and initSelection methods have been replaced by custom data adapters that handle how Select2 stores and retrieves the data that will be displayed to the user. An example of the old query option is provided below, which is the same as the old example, and it generates results that contain the search term repeated a certain number of times.

    query: function (query) {
      var data = {results: []}, i, j, s;
      for (i = 1; i < 5; i++) {
        s = "";
        for (j = 0; j < i; j++) {s = s + query.term;}
        data.results.push({id: query.term + i, text: s});
      }
      query.callback(data);
    }
    

    This has been replaced by custom data adapters which define a similarly named query method. The comparable data adapter is provided below as an example.

    $.fn.select2.amd.require([
      'select2/data/array',
      'select2/utils'
    ], function (ArrayData, Utils) {
      function CustomData ($element, options) {
        CustomData.__super__.constructor.call(this, $element, options);
      }
    
      Utils.Extend(CustomData, ArrayData);
    
      CustomData.prototype.query = function (params, callback) {
        var data = {
          results: []
        };
    
        for (var i = 1; i < 5; i++) {
          var s = "";
    
          for (var j = 0; j < i; j++) {
            s = s + params.term;
          }
    
          data.results.push({
            id: params.term + i,
            text: s
          });
        }
    
        callback(data);
      };
    
      $("#select").select2({
        dataAdapter: CustomData
      });
    }
    

    The new query method of the data adapter is very similar to the old query option that was passed into Select2 when initializing it. The old query argument is mostly the same as the new params that are passed in to query on, and the callback that should be used to return the results is now passed in as the second parameter.

    Renamed templating options

    Select2 previously provided multiple options for formatting the results list and selected options, commonly referred to as "formatters", using the formatSelection and formatResult options. As the "formatters" were also used for things such as localization, which has also changed, they have been renamed to templateSelection and templateResult and their signatures have changed as well.

    You should refer to the updated documentation on templates when migrating from previous versions of Select2.

    The id and text properties are strictly enforced

    When working with array and AJAX data in the past, Select2 allowed a custom id function or attribute to be set in various places, ranging from the initialization of Select2 to when the remote data was being returned. This allowed Select2 to better integrate with existing data sources that did not necessarily use the id attribute to indicate the unique identifier for an object.

    Select2 no longer supports a custom id or text to be used, but provides integration points for converting incorrect data to the expected format.

    When working with array data

    Select2 previously supported defining array data as an object that matched the signature of an AJAX response. A text property could be specified that would map the given property to the text property on the individual objects. You can now do this when initializing Select2 by using the following jQuery code to map the old text and id properties to the new ones.

    var data = $.map([
      {
        pk: 1,
        word: 'one'
      },
      {
        pk: 2,
        word: 'two'
      }
    ], function (obj) {
      obj.id = obj.id || obj.pk;
      obj.text = obj.text || obj.word;
    
      return obj;
    });
    

    This will result in an array of data objects that have the id properties that match the existing pk properties and text properties that match the existing word properties.

    When working with remote data

    The same code that was given above can be used in the processResults method of an AJAX call to map properties there as well.

    Renamed translation options

    In previous versions of Select2, the default messages provided to users could be localized to fit the language of the website that it was being used on. Select2 only comes with the English language by default, but provides community-contributed translations for many common languages. Many of the formatters have been moved to the language option and the signatures of the formatters have been changed to handle future additions.

    Declaring options using data-* attributes

    In the past, Select2 has only supported declaring a subset of options using data-* attributes. Select2 now supports declaring all options using the attributes, using the format specified in the documentation.

    You could previously declare the URL that was used for AJAX requests using the data-ajax-url attribute. While Select2 still allows for this, the new attribute that should be used is the data-ajax--url attribute. Support for the old attribute will be removed in Select2 4.1.

    Although it was not documented, a list of possible tags could also be provided using the data-select2-tags attribute and passing in a JSON-formatted array of objects for tags. As the method for specifying tags has changed in 4.0, you should now provide the array of objects using the data-data attribute, which maps to the array data option. You should also enable tags by setting data-tags="true" on the object, to maintain the ability for users to create their own options as well.

    If you previously declared the list of tags as…

    <select data-select2-tags='[{"id": "1", "text": "One"}, {"id": "2", "text": "Two"}]'></select>
    

    …then you should now declare it as…

    <select data-data='[{"id": "1", "text": "One"}, {"id": "2", "text": "Two"}]' data-tags="true"></select>
    

    Deprecated and removed methods

    As Select2 now uses a <select> element for all data sources, a few methods that were available by calling .select2() are no longer required.

    .select2("val")

    The "val" method has been deprecated and will be removed in Select2 4.1. The deprecated method no longer includes the triggerChange parameter.

    You should directly call .val on the underlying <select> element instead. If you needed the second parameter (triggerChange), you should also call .trigger("change") on the element.

    $("select").val("1").trigger("change"); // instead of $("select").select2("val", "1");
    

    .select2("enable")

    Select2 will respect the disabled property of the underlying select element. In order to enable or disable Select2, you should call .prop('disabled', true/false) on the <select> element. Support for the old methods will be completely removed in Select2 4.1.

    $("select").prop("disabled", true); // instead of $("select").enable(false);
    
    select2-4.0.1/docs/community.html000066400000000000000000000100701262616323400167220ustar00rootroot00000000000000--- layout: default title: Community - Select2 slug: community ---

    Community

    Select2 has an active community that enjoys helping each other out.

    Having trouble getting Select2 working on your website? Is it not working together with another plugin, even though you think it should? Select2 has a few communities that you can go to for help getting it all working together.

    1. Try sending a message to the Select2 discussion group or searching the archives.
    2. Ask in the #select2 channel on chat.freenode.net or use the web irc client.
    3. Raise a question on Stack Overflow, make sure to include the "jquery-select2" tag.

    Found a problem with Select2? Feel free to open a ticket on the Select2 repository on GitHub, but you should keep a few things in mind:

    1. Use the GitHub issue search to check if your issue has already been reported.
    2. Try to isolate your problem as much as possible, so we can easily test if the issue has been fixed.
    3. Once you are sure the issue is with Select2, and not a third party library, submit a ticket to the repository.

    You can find more information on reporting bugs in the contributing guide, including tips on what information to include.

    New feature requests are usually requested by the Select2 community on GitHub, and are often fulfilled by fellow contributors.

    1. Use the GitHub issue search to check if your feature has already been requested.
    2. Check if it hasn't already been implemented as a third party plugin.
    3. Please make sure you are only requesting a single feature, and not a collection of smaller features.

    You can find more information on requesting new features in the contributing guide.

    You can find more information on getting involved with Select2 in the contributing guide.

    select2-4.0.1/docs/css/000077500000000000000000000000001262616323400146025ustar00rootroot00000000000000select2-4.0.1/docs/css/s2-docs.scss000066400000000000000000000005221262616323400167500ustar00rootroot00000000000000--- --- @import "result-repository"; @import "sidenav"; @import "hamburger"; @import "code"; @import "featurette"; @import "layout"; @import "nav"; @import "footer"; @import "alert"; @import "home"; @import "examples"; @import "social"; @import "buttons"; @import "anchorjs"; @import "jumbotron"; @import "prettify"; @import "typography" select2-4.0.1/docs/dist/000077500000000000000000000000001262616323400147555ustar00rootroot00000000000000select2-4.0.1/docs/dist/.gitkeep000066400000000000000000000000001262616323400163740ustar00rootroot00000000000000select2-4.0.1/docs/examples.html000066400000000000000000000151131262616323400165170ustar00rootroot00000000000000--- layout: default title: Examples - Select2 slug: examples ---

    Examples

    {% include examples/basics.html %} {% include examples/placeholders.html %} {% include examples/data.html %} {% include examples/disabled-mode.html %} {% include examples/disabled-results.html %} {% include examples/multiple-max.html %} {% include examples/hide-search.html %} {% include examples/programmatic-control.html %} {% include examples/tags.html %} {% include examples/tokenizer.html %} {% include examples/matcher.html %} {% include examples/localization-rtl-diacritics.html %} {% include examples/themes-templating-responsive-design.html %}
    {% include js-source-states.html %} select2-4.0.1/docs/images/000077500000000000000000000000001262616323400152575ustar00rootroot00000000000000select2-4.0.1/docs/images/logo.png000066400000000000000000000047051262616323400167330ustar00rootroot00000000000000‰PNG  IHDRHHUí³GtEXtSoftwareAdobe ImageReadyqÉe< gIDATxÚì›{pÕÇ»{oÌ“‡‚M…Š«@! é mA_ØÂ8à#¾Š£w´ã?ÚN¶uÚª­õEÅZüÃÎh¤j[èÔÓécZê Žâ &’!æ"!‘¤’{÷ô÷Û=çìÙÍÍͽ¹{IØá»»ÙÝ»÷w>÷û;¯]òdasQ{¸æÂéŧՇb\´_ @%êO ¯è\åT…³ Õ“Ž]³mª¹æõ$Àxõú¤wp3êÓqÀ¢ÏnžŒ`ÊQi€ñŠîU>YàlJÓ5‰Ü´i"ƒ™…z)`¼¢ï˜5Ñà\ƒêÎ!ú®k&˜¨]Yã}÷Œ|…³u$‡p„(†ùfê…<ãÅ4-×pÖ£:òŽŶ>W®Ù™Ç`¼Ú™57á­FµN 8BóêL‚)E=5ÁxEe(õΪ êšDnZå˜bÔc(sÁ2yÙŠÓqMó$ãUsJn‹ Q bSŽPŒ—¹p,8+QMSŒWTö•ñÀœúÅsM"7‹3œZÔ§ÁŒ1©Õ‘Ñ ¨/çÅÀnÖ2£*_†™Ää‡ÂEër:¦ NgÌXŽûÕ¨*TY®ÝEÝOl4u|…›_¡nËæÏ=ë«0tô8èÃ`ßR`&®ÛÁȾs¢Öb G\€P—âæTF½Î¥Ð_¸b½V:!@F§(¬}:>€ë.Ðy°ö±8§¿Ä(¥ð¾?Sj£Í âæ1ÔM™€3P± ú#Cä^`f'÷ˆ}‚eX.bÌ!æ®i÷žÐÆš%ÄÍs~¹)˜‘upªg@:Å €1ËA:ÿVÍrðóª«Náö ¿ÎÞPö½S!&p̓xÝ£]0&p ëLÜ<‰Úšœž9_ƒOz @‹aá‡c ŒÉ}Ž®³ÿ¶¯Ó%¨N<~t ï>xö=çÛp»Õ’(î¤ÉŸ<ƒªHÌQÍå—Â`ßU`#ò´ á"8N‘0lpw”®€3ÀnclW‘›ö¢{àx†çÌ€‡ƒßM&þ”R–?zµ%™ë»ªVCkÿ4`1»ðÀaè¦SÏX¿*‹*°ÁŠb˜ªÃlpDÖ…Û¶¸p¼®Â®ñá ­-‚ÁædË<®:?'P³ã?©à½9ß„¾¦UÑj"ES*dºê¢áØH8&H :wt()Ç”&]q ýK5MßýÒ…ðpíåÿi/«¸j:rè’M/¯ljkÝÛÙÝ5“b^«­˜% »‡l§ŒåIp:˜Nó뺤[RIÓ¡‚Bx®îjØ=o‰±ìÖêiŲhÍuÔ{ûzw½ßÔt}thH^Rn®Ç\(*QfÿòN«.p²Ö5•’OӪσV\ ½Åqýu;BjÎ8 º-¸¸½½mOWg·ýÊ à…•՜˭ƒL(}îŽ SÒN¦RLº-Ù4@cízxuÞ¢±BD}õ8‚ŠeÐWî~þ`SÓ-±“ÃŽk˜ ”ņqh °›q{¾É\.Ð…ƒÈ^²Áÿ†8 FKÓO*¿­ØÇŠËR)ÆÛ¨[Ò‡¾Z¼õÍeG:ºþ|¬£«\:ÅÚšöì ¨éí9†…Y†…ڀNJ¸sd=Ã@‚3ÀINŽ×)ÿõ‚ЦhÞµ{w´hÙÎNQ]c:px*9ûÌÿÉ¿˜%¨kÎ9Ì´ ªóAª:ÔpÆ` !ê 8JÓãg͆åkàh±/G÷£nFHûS4ÿ¦,:Öùˉ¶H¥Ý])FéÅF€ps2­ÍWpµ¯ Ê> Á‰ÉºH€3¸Ûdjê¼»x¼2¿Æ÷9;ËI?EP§’T±e_Cä@û08ìj¡ì&ˆÉL¡¹,¸;½Àýæ†Jnºw«E¿G©°í¡†ÉáØ­ÜÉò xqit—B—ÖljCÍ[£šyëÛ :zþ:Ü9Û â¶T.çhŒC3]Žq»M|Î>¾Õá} ¬¦ää˜ÁÝj4h½`ºæ¼lM·Rp¿¶&ëj>wÚöïGá@ç=ðù°. Á”ÊxDÊ$J'QA›ŠÛâ§i Þc jŽÒä“£ŒÙ3á÷‹—BgI)ä`iá-Ý?5¸ã½ÐÞ³ÿ‚í„$êÆâ¤é9ï…œ8Mâ~-îÑJ'ž»çÏχG?Oh°ýƒ½57€©ÖàiºGŽPÇ8ä1æ:DbE…À‚Á|€CuR}‚ƨ»ÁžÍ/ÊeDf~<0¤0AýˆZ5§ …ÉÓ¿A}¦îBÏÄêÕ–L—§jÑ8uO¥…\óKÔ’„ͼâ¦j\?‹ºl Àiá½é¥>Ô…ëqý(u‘&!jž@}OôyÆ7X …+ùãž«'z r#õsü›î…>ɘ@ •á>„3àÿ„Y(<ÛšpJó)k]C½ã¿e~N:¾ ×; Ão€ø¸<ºá¤Ü:Ò>žÁ+ð›óÌa>Bs¼7Hÿ5›P˜þ7ÍN Ù‹üZ~‹úÂ9‘ÎMüy).å“Nwæ˜.Ô·Ì?næï‹Z¡0½±No§›#8/r×ôùuCÿßd …éÿ>üتÕ¡Lf—j;‚yÃïk 9^É[L¿bü;Ôݧ'7×2z(Lo«ÿÀê˜|¾û1^×¼–É"hYI€Px oU–øtÇW­¡¡æÓL‡®A¶–P8ÀDo¯¤áÓ˜­°³ÈUÃÝtqŠŸ|ƒWÄ‘l†›}@6$zAìÔƒ0ö4ïq^ ¿”‹Psȵ€÷¿>Ê{øP¡;W!æ Iã=ðŸ£ÄkŸñß®\‡—{@¨jÞoæÍ÷‘|ëÿ œA»ñ(M@IEND®B`‚select2-4.0.1/docs/index.html000066400000000000000000000151141262616323400160110ustar00rootroot00000000000000--- layout: home title: Select2 - The jQuery replacement for select boxes slug: home ---

    Select2

    The jQuery replacement for select boxes

    Download Select2

    Currently v4.0.1

    {% include notice-previous.html %}
    Select2 gives you a customizable select box with support for searching, tagging, remote data sets, infinite scrolling, and many other highly used options.

    In your language

    Select2 comes with support for RTL environments, searching with diacritics and over 40 languages built-in.

    Remote data support

    Using AJAX you can efficiently search large lists of items.

    Fits in with your theme

    Fully skinnable, CSS built with Sass and an optional theme for Bootstrap 3.

    Fully extensible

    The plugin system allows you to easily customize Select2 to work exactly how you want it to.

    Dynamic item creation

    Allow users to type in a new option and add it on the fly.

    Full browser support

    Support for both modern and legacy browsers is built-in, even including Internet Explorer 8.


    Getting started with Select2

    In order to use Select2, you must include the JavaScript and CSS file on your website. You can get these files built for you from many different locations.

    Using Select2 from a CDN

    Select2 is hosted on both the cdnjs and jsDelivr CDNs, allowing you to quickly include Select2 on your website.

    1. Include the following lines of code in the <head> section of your HTML.

      <link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/css/select2.min.css" rel="stylesheet" />
      <script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/js/select2.min.js"></script>
      
      Immediately following a new release, it takes some time for CDNs to catch up and get the new versions live on the CDN.
    2. Initialize Select2 on the <select> element that you want to make awesome.

      <script type="text/javascript">
        $('select').select2();
      </script>
      
    3. Check out the examples page to start using the additional features of Select2.

    Downloading the code locally

    In some situations, you can't use Select2 from a CDN and you must include the files through your own static file servers.

    1. Download the code from GitHub and copy the dist directory to your project.

    2. Include the following lines of code in the <head> section of your HTML.

      <link href="path/to/select2.min.css" rel="stylesheet" />
      <script src="path/to/select2.min.js"></script>
      
    3. Check out the examples page to start using the additional features of Select2.

    The different Select2 builds

    Select2 provides multiple builds that are tailored to different environments where it is going to be used. If you think you need to use Select2 in a nonstandard environment, like when you are using AMD, you should read over the list below.

    Build name When you should use it
    Standard (select2.js / select2.min.js) This is the build that most people should be using for Select2. It includes the most commonly used features.
    Full (select2.full.js / select2.full.min.js) You should only use this build if you need the additional features from Select2, like the compatibility modules or recommended includes like jquery.mousewheel
    select2-4.0.1/docs/options-old.html000066400000000000000000000014041262616323400171460ustar00rootroot00000000000000--- layout: default title: Options - Select2 slug: options ---

    Options

    {% include options-old/core-options.html %} {% include options-old/dropdown.html %} {% include options-old/events.html %} {% include options-old/adapters.html %} {% include options-old/setting-default-options.html %} {% include options-old/backwards-compatibility.html %}
    select2-4.0.1/docs/options.html000066400000000000000000000015541262616323400164000ustar00rootroot00000000000000--- layout: default title: Options - Select2 slug: options ---

    Options

    Select2 supports a wide variety of options that allow you to customize it to your needs.

    {% include options/introduction.html %} {% include options/core.html %} {% include options/data.html %} {% include options/selections.html %} {% include options/dropdown.html %} {% include options/events.html %} {% include options/compatibility.html %}
    select2-4.0.1/package.json000066400000000000000000000030671262616323400153560ustar00rootroot00000000000000{ "name": "select2", "description": "Select2 is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.", "homepage": "https://select2.github.io", "author": { "name": "Kevin Brown", "url": "https://github.com/kevin-brown" }, "contributors": [ { "name": "Igor Vaynberg", "url": "https://github.com/ivaynberg" } ], "repository": { "type": "git", "url": "git://github.com/select2/select2.git" }, "bugs": { "url": "https://github.com/select2/select2/issues" }, "keywords": [ "select", "autocomplete", "typeahead", "dropdown", "multiselect", "tag", "tagging" ], "license": "MIT", "main": "dist/js/select2.js", "files": [ "src", "dist" ], "version": "4.0.1", "jspm": { "main": "js/select2", "directories": { "lib": "dist" } }, "devDependencies": { "grunt": "^0.4.5", "grunt-cli": "^0.1.13", "grunt-contrib-clean": "^0.6.0", "grunt-contrib-concat": "^0.4.0", "grunt-contrib-connect": "^0.9.0", "grunt-contrib-jshint": "^0.10.0", "grunt-contrib-nodeunit": "~0.3.3", "grunt-contrib-qunit": "~0.4.0", "grunt-contrib-requirejs": "^0.4.4", "grunt-contrib-symlink": "^0.3.0", "grunt-contrib-uglify": "~0.4.0", "grunt-contrib-watch": "~0.6.0", "grunt-gh-pages": "^0.9.1", "grunt-jekyll": "^0.4.2", "grunt-sass": "^1.0.0", "grunt-saucelabs": "^8.6.0" }, "dependencies": { "almond": "~0.3.1", "jquery-mousewheel": "~3.1.13" } } select2-4.0.1/select2.jquery.json000066400000000000000000000015651262616323400166430ustar00rootroot00000000000000{ "name": "select2", "title": "Select2", "description": "Select2 is a jQuery based replacement for select boxes. It supports searching, remote data sets, and infinite scrolling of results.", "keywords": [ "select", "autocomplete", "typeahead", "dropdown", "multiselect", "tag", "tagging" ], "version": "4.0.1", "author": { "name": "Kevin Brown", "url": "https://github.com/kevin-brown" }, "licenses": [ { "type": "MIT", "url": "http://opensource.org/licenses/MIT" } ], "bugs": "https://github.com/select2/select2/issues", "homepage": "https://select2.github.io", "docs": "https://select2.github.io", "download": "https://github.com/select2/select2/releases", "dependencies": { "jquery": ">=1.7.2" } } select2-4.0.1/src/000077500000000000000000000000001262616323400136515ustar00rootroot00000000000000select2-4.0.1/src/js/000077500000000000000000000000001262616323400142655ustar00rootroot00000000000000select2-4.0.1/src/js/banner.end.js000066400000000000000000000002251262616323400166340ustar00rootroot00000000000000 // Return the AMD loader configuration so it can be used outside of this file return { define: S2.define, require: S2.require }; }()); select2-4.0.1/src/js/banner.start.js000066400000000000000000000004031262616323400172210ustar00rootroot00000000000000(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; } select2-4.0.1/src/js/jquery.mousewheel.shim.js000066400000000000000000000001571262616323400212600ustar00rootroot00000000000000define([ 'jquery' ], function ($) { // Used to shim jQuery.mousewheel for non-full builds. return $; }); select2-4.0.1/src/js/jquery.select2.js000066400000000000000000000026711262616323400175100ustar00rootroot00000000000000define([ 'jquery', 'jquery-mousewheel', './select2/core', './select2/defaults' ], function ($, _, Select2, Defaults) { 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; this.each(function () { var instance = $(this).data('select2'); if (instance == null && window.console && console.error) { console.error( 'The select2(\'' + options + '\') method was called on an ' + 'element that is not using Select2.' ); } var args = Array.prototype.slice.call(arguments, 1); 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; }); select2-4.0.1/src/js/jquery.shim.js000066400000000000000000000005451262616323400171050ustar00rootroot00000000000000/* global jQuery:false, $:false */ define(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 _$; }); select2-4.0.1/src/js/select2/000077500000000000000000000000001262616323400156265ustar00rootroot00000000000000select2-4.0.1/src/js/select2/compat/000077500000000000000000000000001262616323400171115ustar00rootroot00000000000000select2-4.0.1/src/js/select2/compat/containerCss.js000066400000000000000000000026571262616323400221140ustar00rootroot00000000000000define([ '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; }); select2-4.0.1/src/js/select2/compat/dropdownCss.js000066400000000000000000000026171262616323400217620ustar00rootroot00000000000000define([ '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; }); select2-4.0.1/src/js/select2/compat/initSelection.js000066400000000000000000000021411262616323400222560ustar00rootroot00000000000000define([ '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; }); select2-4.0.1/src/js/select2/compat/inputData.js000066400000000000000000000056151262616323400214070ustar00rootroot00000000000000define([ 'jquery' ], function ($) { 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 `' + '' ); 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(''); }); 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; }); select2-4.0.1/src/js/select2/dropdown/selectOnClose.js000066400000000000000000000015271262616323400225670ustar00rootroot00000000000000define([ ], function () { function SelectOnClose () { } SelectOnClose.prototype.bind = function (decorated, container, $container) { var self = this; decorated.call(this, container, $container); container.on('close', function () { self._handleSelectOnClose(); }); }; SelectOnClose.prototype._handleSelectOnClose = function () { var $highlightedResults = this.getHighlightedResults(); // Only select highlighted results if ($highlightedResults.length < 1) { return; } var data = $highlightedResults.data('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; }); select2-4.0.1/src/js/select2/dropdown/stopPropagation.js000066400000000000000000000012351262616323400232120ustar00rootroot00000000000000define([ ], 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; }); select2-4.0.1/src/js/select2/i18n/000077500000000000000000000000001262616323400164055ustar00rootroot00000000000000select2-4.0.1/src/js/select2/i18n/ar.js000066400000000000000000000017261262616323400173530ustar00rootroot00000000000000define(function () { // Arabic return { errorLoading: function () { return 'لا يمكن تحميل النتائج'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'الرجاء حذ٠' + overChars + ' عناصر'; return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'الرجاء Ø¥Ø¶Ø§ÙØ© ' + remainingChars + ' عناصر'; return message; }, loadingMore: function () { return 'جاري تحميل نتائج إضاÙية...'; }, maximumSelected: function (args) { var message = 'تستطيع إختيار ' + args.maximum + ' بنود Ùقط'; return message; }, noResults: function () { return 'لم يتم العثور على أي نتائج'; }, searching: function () { return 'جاري البحث…'; } }; });select2-4.0.1/src/js/select2/i18n/az.js000066400000000000000000000012771262616323400173640ustar00rootroot00000000000000define(function () { // Azerbaijani return { inputTooLong: function (args) { var overChars = args.input.length - args.maximum; return overChars + ' simvol silin'; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; return remainingChars + ' simvol daxil edin'; }, loadingMore: function () { return 'Daha çox nÉ™ticÉ™ yüklÉ™nir…'; }, maximumSelected: function (args) { return 'SadÉ™cÉ™ ' + args.maximum + ' element seçə bilÉ™rsiniz'; }, noResults: function () { return 'NÉ™ticÉ™ tapılmadı'; }, searching: function () { return 'Axtarılır…'; } }; }); select2-4.0.1/src/js/select2/i18n/bg.js000066400000000000000000000022041262616323400173310ustar00rootroot00000000000000define(function () { // Bulgarian return { inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'ÐœÐ¾Ð»Ñ Ð²ÑŠÐ²ÐµÐ´ÐµÑ‚Ðµ Ñ ' + overChars + ' по-малко Ñимвол'; if (overChars > 1) { message += 'a'; } return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'ÐœÐ¾Ð»Ñ Ð²ÑŠÐ²ÐµÐ´ÐµÑ‚Ðµ още ' + remainingChars + ' Ñимвол'; if (remainingChars > 1) { message += 'a'; } return message; }, loadingMore: function () { return 'Зареждат Ñе още…'; }, maximumSelected: function (args) { var message = 'Можете да направите до ' + args.maximum + ' '; if (args.maximum > 1) { message += 'избора'; } else { message += 'избор'; } return message; }, noResults: function () { return 'ÐÑма намерени ÑъвпадениÑ'; }, searching: function () { return 'ТърÑене…'; } }; }); select2-4.0.1/src/js/select2/i18n/ca.js000066400000000000000000000022361262616323400173310ustar00rootroot00000000000000define(function () { // Catalan return { errorLoading: function () { return 'La càrrega ha fallat'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'Si us plau, elimina ' + overChars + ' car'; if (overChars == 1) { message += 'àcter'; } else { message += 'àcters'; } return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Si us plau, introdueix ' + remainingChars + ' car'; if (remainingChars == 1) { message += 'àcter'; } else { message += 'àcters'; } return message; }, loadingMore: function () { return 'Carregant més resultats…'; }, maximumSelected: function (args) { var message = 'Només es pot seleccionar ' + args.maximum + ' element'; if (args.maximum != 1) { message += 's'; } return message; }, noResults: function () { return 'No s\'han trobat resultats'; }, searching: function () { return 'Cercant…'; } }; }); select2-4.0.1/src/js/select2/i18n/cs.js000066400000000000000000000031511262616323400173500ustar00rootroot00000000000000define(function () { // Czech function small (count, masc) { switch(count) { case 2: return masc ? 'dva' : 'dvÄ›'; case 3: return 'tÅ™i'; case 4: return 'ÄtyÅ™i'; } return ''; } return { errorLoading: function () { return 'Výsledky nemohly být naÄteny.'; }, inputTooLong: function (args) { var n = args.input.length - args.maximum; if (n == 1) { return 'Prosím zadejte o jeden znak ménÄ›'; } else if (n <= 4) { return 'Prosím zadejte o ' + small(n, true) + ' znaky ménÄ›'; } else { return 'Prosím zadejte o ' + n + ' znaků ménÄ›'; } }, inputTooShort: function (args) { var n = args.minimum - args.input.length; if (n == 1) { return 'Prosím zadejte jeÅ¡tÄ› jeden znak'; } else if (n <= 4) { return 'Prosím zadejte jeÅ¡tÄ› další ' + small(n, true) + ' znaky'; } else { return 'Prosím zadejte jeÅ¡tÄ› dalších ' + n + ' znaků'; } }, loadingMore: function () { return 'NaÄítají se další výsledky…'; }, maximumSelected: function (args) { var n = args.maximum; if (n == 1) { return 'Můžete zvolit jen jednu položku'; } else if (n <= 4) { return 'Můžete zvolit maximálnÄ› ' + small(n, false) + ' položky'; } else { return 'Můžete zvolit maximálnÄ› ' + n + ' položek'; } }, noResults: function () { return 'Nenalezeny žádné položky'; }, searching: function () { return 'Vyhledávání…'; } }; }); select2-4.0.1/src/js/select2/i18n/da.js000066400000000000000000000016731262616323400173360ustar00rootroot00000000000000define(function () { // Danish return { errorLoading: function () { return 'Resultaterne kunne ikke indlæses.'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'Angiv venligst ' + overChars + ' tegn mindre'; return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Angiv venligst ' + remainingChars + ' tegn mere'; return message; }, loadingMore: function () { return 'Indlæser flere resultater…'; }, maximumSelected: function (args) { var message = 'Du kan kun vælge ' + args.maximum + ' emne'; if (args.maximum != 1) { message += 'r'; } return message; }, noResults: function () { return 'Ingen resultater fundet'; }, searching: function () { return 'Søger…'; } }; }); select2-4.0.1/src/js/select2/i18n/de.js000066400000000000000000000015731262616323400173410ustar00rootroot00000000000000define(function () { // German return { inputTooLong: function (args) { var overChars = args.input.length - args.maximum; return 'Bitte ' + overChars + ' Zeichen weniger eingeben'; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; return 'Bitte ' + remainingChars + ' Zeichen mehr eingeben'; }, loadingMore: function () { return 'Lade mehr Ergebnisse…'; }, maximumSelected: function (args) { var message = 'Sie können nur ' + args.maximum + ' Eintr'; if (args.maximum === 1) { message += 'ag'; } else { message += 'äge'; } message += ' auswählen'; return message; }, noResults: function () { return 'Keine Übereinstimmungen gefunden'; }, searching: function () { return 'Suche…'; } }; }); select2-4.0.1/src/js/select2/i18n/en.js000066400000000000000000000017631262616323400173540ustar00rootroot00000000000000define(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…'; } }; }); select2-4.0.1/src/js/select2/i18n/es.js000066400000000000000000000022471262616323400173570ustar00rootroot00000000000000define(function () { // Spanish return { errorLoading: function () { return 'La carga falló'; }, inputTooLong: function (args) { var remainingChars = args.input.length - args.maximum; var message = 'Por favor, elimine ' + remainingChars + ' car'; if (remainingChars == 1) { message += 'ácter'; } else { message += 'acteres'; } return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Por favor, introduzca ' + remainingChars + ' car'; if (remainingChars == 1) { message += 'ácter'; } else { message += 'acteres'; } return message; }, loadingMore: function () { return 'Cargando más resultados…'; }, maximumSelected: function (args) { var message = 'Sólo puede seleccionar ' + args.maximum + ' elemento'; if (args.maximum != 1) { message += 's'; } return message; }, noResults: function () { return 'No se encontraron resultados'; }, searching: function () { return 'Buscando…'; } }; }); select2-4.0.1/src/js/select2/i18n/et.js000066400000000000000000000020601262616323400173510ustar00rootroot00000000000000define(function () { // Estonian return { inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'Sisesta ' + overChars + ' täht'; if (overChars != 1) { message += 'e'; } message += ' vähem'; return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Sisesta ' + remainingChars + ' täht'; if (remainingChars != 1) { message += 'e'; } message += ' rohkem'; return message; }, loadingMore: function () { return 'Laen tulemusi…'; }, maximumSelected: function (args) { var message = 'Saad vaid ' + args.maximum + ' tulemus'; if (args.maximum == 1) { message += 'e'; } else { message += 't'; } message += ' valida'; return message; }, noResults: function () { return 'Tulemused puuduvad'; }, searching: function () { return 'Otsin…'; } }; }); select2-4.0.1/src/js/select2/i18n/eu.js000066400000000000000000000021741262616323400173600ustar00rootroot00000000000000define(function () { // Basque return { inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'Idatzi '; if (overChars == 1) { message += 'karaktere bat'; } else { message += overChars + ' karaktere'; } message += ' gutxiago'; return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Idatzi '; if (remainingChars == 1) { message += 'karaktere bat'; } else { message += remainingChars + ' karaktere'; } message += ' gehiago'; return message; }, loadingMore: function () { return 'Emaitza gehiago kargatzen…'; }, maximumSelected: function (args) { if (args.maximum === 1) { return 'Elementu bakarra hauta dezakezu'; } else { return args.maximum + ' elementu hauta ditzakezu soilik'; } }, noResults: function () { return 'Ez da bat datorrenik aurkitu'; }, searching: function () { return 'Bilatzen…'; } }; }); select2-4.0.1/src/js/select2/i18n/fa.js000066400000000000000000000022001262616323400173230ustar00rootroot00000000000000/* jshint -W100 */ /* jslint maxlen: 86 */ define(function () { // Farsi (Persian) return { errorLoading: function () { return 'امکان بارگذاری نتایج وجود ندارد.'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'Ù„Ø·ÙØ§Ù‹ ' + overChars + ' کاراکتر را حذ٠نمایید'; return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Ù„Ø·ÙØ§Ù‹ تعداد ' + remainingChars + ' کاراکتر یا بیشتر وارد نمایید'; return message; }, loadingMore: function () { return 'در حال بارگذاری نتایج بیشتر...'; }, maximumSelected: function (args) { var message = 'شما تنها می‌توانید ' + args.maximum + ' آیتم را انتخاب نمایید'; return message; }, noResults: function () { return 'هیچ نتیجه‌ای ÛŒØ§ÙØª نشد'; }, searching: function () { return 'در حال جستجو...'; } }; }); select2-4.0.1/src/js/select2/i18n/fi.js000066400000000000000000000012731262616323400173440ustar00rootroot00000000000000define(function () { // Finnish return { inputTooLong: function (args) { var overChars = args.input.length - args.maximum; return 'Ole hyvä ja anna ' + overChars + ' merkkiä vähemmän'; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; return 'Ole hyvä ja anna ' + remainingChars + ' merkkiä lisää'; }, loadingMore: function () { return 'Ladataan lisää tuloksia…'; }, maximumSelected: function (args) { return 'Voit valita ainoastaan ' + args.maximum + ' kpl'; }, noResults: function () { return 'Ei tuloksia'; }, searching: function () { } }; }); select2-4.0.1/src/js/select2/i18n/fr.js000066400000000000000000000020231262616323400173470ustar00rootroot00000000000000define(function () { // French return { inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'Supprimez ' + overChars + ' caractère'; if (overChars !== 1) { message += 's'; } return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Saisissez ' + remainingChars + ' caractère'; if (remainingChars !== 1) { message += 's'; } return message; }, loadingMore: function () { return 'Chargement de résultats supplémentaires…'; }, maximumSelected: function (args) { var message = 'Vous pouvez seulement sélectionner ' + args.maximum + ' élément'; if (args.maximum !== 1) { message += 's'; } return message; }, noResults: function () { return 'Aucun résultat trouvé'; }, searching: function () { return 'Recherche en cours…'; } }; }); select2-4.0.1/src/js/select2/i18n/gl.js000066400000000000000000000021311262616323400173420ustar00rootroot00000000000000define(function () { // Galician return { inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'Elimine '; if (overChars === 1) { message += 'un carácter'; } else { message += overChars + ' caracteres'; } return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Engada '; if (remainingChars === 1) { message += 'un carácter'; } else { message += remainingChars + ' caracteres'; } return message; }, loadingMore: function () { return 'Cargando máis resultados…'; }, maximumSelected: function (args) { var message = 'Só pode '; if (args.maximum === 1) { message += 'un elemento'; } else { message += args.maximum + ' elementos'; } return message; }, noResults: function () { return 'Non se atoparon resultados'; }, searching: function () { return 'Buscando…'; } }; }); select2-4.0.1/src/js/select2/i18n/he.js000066400000000000000000000024241262616323400173410ustar00rootroot00000000000000define(function () { // Hebrew return { errorLoading: function () { return 'שגי××” בטעינת התוצ×ות'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = '× × ×œ×ž×—×•×§ '; if (overChars === 1) { message += 'תו ×חד'; } else { message += overChars + ' תווי×'; } return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = '× × ×œ×”×›× ×™×¡ '; if (remainingChars === 1) { message += 'תו ×חד'; } else { message += remainingChars + ' תווי×'; } message += ' ×ו יותר'; return message; }, loadingMore: function () { return 'טוען תוצ×ות נוספות…'; }, maximumSelected: function (args) { var message = 'ב×פשרותך לבחור עד '; if (args.maximum === 1) { message += 'פריט ×חד'; } else { message += args.maximum + ' פריטי×'; } return message; }, noResults: function () { return '×œ× × ×ž×¦×ו תוצ×ות'; }, searching: function () { return 'מחפש…'; } }; }); select2-4.0.1/src/js/select2/i18n/hi.js000066400000000000000000000023721262616323400173470ustar00rootroot00000000000000define(function () { // Hindi return { errorLoading: function () { return 'परिणामों को लोड नहीं किया जा सका।'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = overChars + ' अकà¥à¤·à¤° को हटा दें'; if (overChars > 1) { message = overChars + ' अकà¥à¤·à¤°à¥‹à¤‚ को हटा दें '; } return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'कृपया ' + remainingChars + ' या अधिक अकà¥à¤·à¤° दरà¥à¤œ करें'; return message; }, loadingMore: function () { return 'अधिक परिणाम लोड हो रहे है...'; }, maximumSelected: function (args) { var message = 'आप केवल ' + args.maximum + ' आइटम का चयन कर सकते हैं'; return message; }, noResults: function () { return 'कोई परिणाम नहीं मिला'; }, searching: function () { return 'खोज रहा है...'; } }; }); select2-4.0.1/src/js/select2/i18n/hr.js000066400000000000000000000020061262616323400173520ustar00rootroot00000000000000define(function () { // Croatian function character (n) { var message = ' ' + n + ' znak'; if (n % 10 < 5 && n % 10 > 0 && (n % 100 < 5 || n % 100 > 19)) { if (n % 10 > 1) { message += 'a'; } } else { message += 'ova'; } return message; } return { errorLoading: function () { return 'Preuzimanje nije uspjelo.'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; return 'Unesite ' + character(overChars); }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; return 'Unesite joÅ¡ ' + character(remainingChars); }, loadingMore: function () { return 'UÄitavanje rezultata…'; }, maximumSelected: function (args) { return 'Maksimalan broj odabranih stavki je ' + args.maximum; }, noResults: function () { return 'Nema rezultata'; }, searching: function () { return 'Pretraga…'; } }; }); select2-4.0.1/src/js/select2/i18n/hu.js000066400000000000000000000013351262616323400173610ustar00rootroot00000000000000define(function () { // Hungarian return { inputTooLong: function (args) { var overChars = args.input.length - args.maximum; return 'Túl hosszú. ' + overChars + ' karakterrel több, mint kellene.'; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; return 'Túl rövid. Még ' + remainingChars + ' karakter hiányzik.'; }, loadingMore: function () { return 'Töltés…'; }, maximumSelected: function (args) { return 'Csak ' + args.maximum + ' elemet lehet kiválasztani.'; }, noResults: function () { return 'Nincs találat.'; }, searching: function () { return 'Keresés…'; } }; }); select2-4.0.1/src/js/select2/i18n/id.js000066400000000000000000000014151262616323400173400ustar00rootroot00000000000000define(function () { // Indonesian return { errorLoading: function () { return 'Data tidak boleh diambil.'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; return 'Hapuskan ' + overChars + ' huruf'; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; return 'Masukkan ' + remainingChars + ' huruf lagi'; }, loadingMore: function () { return 'Mengambil data…'; }, maximumSelected: function (args) { return 'Anda hanya dapat memilih ' + args.maximum + ' pilihan'; }, noResults: function () { return 'Tidak ada data yang sesuai'; }, searching: function () { return 'Mencari…'; } }; }); select2-4.0.1/src/js/select2/i18n/is.js000066400000000000000000000016701262616323400173620ustar00rootroot00000000000000define(function () { // Icelandic return { inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'Vinsamlegast styttið texta um ' + overChars + ' staf'; if (overChars <= 1) { return message; } return message + 'i'; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Vinsamlegast skrifið ' + remainingChars + ' staf'; if (remainingChars > 1) { message += 'i'; } message += ' í viðbót'; return message; }, loadingMore: function () { return 'Sæki fleiri niðurstöður…'; }, maximumSelected: function (args) { return 'Þú getur aðeins valið ' + args.maximum + ' atriði'; }, noResults: function () { return 'Ekkert fannst'; }, searching: function () { return 'Leita…'; } }; }); select2-4.0.1/src/js/select2/i18n/it.js000066400000000000000000000021501262616323400173550ustar00rootroot00000000000000define(function () { // Italian return { errorLoading: function () { return 'I risultati non possono essere caricati.'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'Per favore cancella ' + overChars + ' caratter'; if (overChars !== 1) { message += 'i'; } else { message += 'e'; } return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Per favore inserisci ' +remainingChars+ ' o più caratteri'; return message; }, loadingMore: function () { return 'Caricando più risultati…'; }, maximumSelected: function (args) { var message = 'Puoi selezionare solo ' + args.maximum + ' element'; if (args.maximum !== 1) { message += 'i'; } else { message += 'o'; } return message; }, noResults: function () { return 'Nessun risultato trovato'; }, searching: function () { return 'Sto cercando…'; } }; }); select2-4.0.1/src/js/select2/i18n/ja.js000066400000000000000000000016561262616323400173450ustar00rootroot00000000000000define(function () { // Japanese return { errorLoading: function () { return 'çµæžœãŒèª­ã¿è¾¼ã¾ã‚Œã¾ã›ã‚“ã§ã—ãŸ'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = overChars + ' 文字を削除ã—ã¦ãã ã•ã„'; return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'å°‘ãªãã¨ã‚‚ ' + remainingChars + ' 文字を入力ã—ã¦ãã ã•ã„'; return message; }, loadingMore: function () { return '読ã¿è¾¼ã¿ä¸­â€¦'; }, maximumSelected: function (args) { var message = args.maximum + ' ä»¶ã—ã‹é¸æŠžã§ãã¾ã›ã‚“'; return message; }, noResults: function () { return '対象ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“'; }, searching: function () { return '検索ã—ã¦ã„ã¾ã™â€¦'; } }; }); select2-4.0.1/src/js/select2/i18n/ko.js000066400000000000000000000016661262616323400173650ustar00rootroot00000000000000define(function () { // Korean return { errorLoading: function () { return '결과를 불러올 수 없습니다.'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = '너무 ê¹ë‹ˆë‹¤. ' + overChars + ' ê¸€ìž ì§€ì›Œì£¼ì„¸ìš”.'; return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = '너무 짧습니다. ' + remainingChars + ' ê¸€ìž ë” ìž…ë ¥í•´ì£¼ì„¸ìš”.'; return message; }, loadingMore: function () { return '불러오는 중…'; }, maximumSelected: function (args) { var message = '최대 ' + args.maximum + '개까지만 ì„ íƒ ê°€ëŠ¥í•©ë‹ˆë‹¤.'; return message; }, noResults: function () { return '결과가 없습니다.'; }, searching: function () { return '검색 중…'; } }; }); select2-4.0.1/src/js/select2/i18n/lt.js000066400000000000000000000023301262616323400173600ustar00rootroot00000000000000define(function () { // Italian function ending (count, first, second, third) { if ((count % 100 > 9 && count % 100 < 21) || count % 10 === 0) { if (count % 10 > 1) { return second; } else { return third; } } else { return first; } } return { inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'PaÅ¡alinkite ' + overChars + ' simbol'; message += ending(overChars, 'ių', 'ius', 'į'); return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Ä®raÅ¡ykite dar ' + remainingChars + ' simbol'; message += ending(remainingChars, 'ių', 'ius', 'į'); return message; }, loadingMore: function () { return 'Kraunama daugiau rezultatų…'; }, maximumSelected: function (args) { var message = 'JÅ«s galite pasirinkti tik ' + args.maximum + ' element'; message += ending(args.maximum, 'ų', 'us', 'Ä…'); return message; }, noResults: function () { return 'Atitikmenų nerasta'; }, searching: function () { return 'IeÅ¡koma…'; } }; }); select2-4.0.1/src/js/select2/i18n/lv.js000066400000000000000000000022361262616323400173670ustar00rootroot00000000000000define(function () { // Latvian function ending (count, eleven, singular, other) { if (count === 11) { return eleven; } if (count % 10 === 1) { return singular; } return other; } return { inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'LÅ«dzu ievadiet par ' + overChars; message += ' simbol' + ending(overChars, 'iem', 'u', 'iem'); return message + ' mazÄk'; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'LÅ«dzu ievadiet vÄ“l ' + remainingChars; message += ' simbol' + ending(remainingChars, 'us', 'u', 'us'); return message; }, loadingMore: function () { return 'Datu ielÄde…'; }, maximumSelected: function (args) { var message = 'JÅ«s varat izvÄ“lÄ“ties ne vairÄk kÄ ' + args.maximum; message += ' element' + ending(args.maximum, 'us', 'u', 'us'); return message; }, noResults: function () { return 'SakritÄ«bu nav'; }, searching: function () { return 'Meklēšana…'; } }; }); select2-4.0.1/src/js/select2/i18n/mk.js000066400000000000000000000022601262616323400173520ustar00rootroot00000000000000define(function () { // Macedonian return { inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'Ве молиме внеÑете ' + args.maximum + ' помалку карактер'; if (args.maximum !== 1) { message += 'и'; } return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Ве молиме внеÑете уште ' + args.maximum + ' карактер'; if (args.maximum !== 1) { message += 'и'; } return message; }, loadingMore: function () { return 'Вчитување резултати…'; }, maximumSelected: function (args) { var message = 'Можете да изберете Ñамо ' + args.maximum + ' Ñтавк'; if (args.maximum === 1) { message += 'а'; } else { message += 'и'; } return message; }, noResults: function () { return 'Ðема пронајдено Ñовпаѓања'; }, searching: function () { return 'Пребарување…'; } }; }); select2-4.0.1/src/js/select2/i18n/ms.js000066400000000000000000000014561262616323400173700ustar00rootroot00000000000000define(function () { // Malay return { errorLoading: function () { return 'Keputusan tidak berjaya dimuatkan.'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; return 'Sila hapuskan ' + overChars + ' aksara'; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; return 'Sila masukkan ' + remainingChars + ' atau lebih aksara'; }, loadingMore: function () { return 'Sedang memuatkan keputusan…'; }, maximumSelected: function (args) { return 'Anda hanya boleh memilih ' + args.maximum + ' pilihan'; }, noResults: function () { return 'Tiada padanan yang ditemui'; }, searching: function () { return 'Mencari…'; } }; });select2-4.0.1/src/js/select2/i18n/nb.js000066400000000000000000000015011262616323400173370ustar00rootroot00000000000000define(function () { // Norwegian (BokmÃ¥l) return { inputTooLong: function (args) { var overChars = args.input.length - args.maximum; return 'Vennligst fjern ' + overChars + ' tegn'; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Vennligst skriv inn '; if (remainingChars > 1) { message += ' flere tegn'; } else { message += ' tegn til'; } return message; }, loadingMore: function () { return 'Laster flere resultater…'; }, maximumSelected: function (args) { return 'Du kan velge maks ' + args.maximum + ' elementer'; }, noResults: function () { return 'Ingen treff'; }, searching: function () { return 'Søker…'; } }; }); select2-4.0.1/src/js/select2/i18n/nl.js000066400000000000000000000020771262616323400173620ustar00rootroot00000000000000define(function () { // Dutch return { errorLoading: function () { return 'De resultaten konden niet worden geladen.'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'Gelieve ' + overChars + ' karakters te verwijderen'; return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Gelieve ' + remainingChars + ' of meer karakters in te voeren'; return message; }, loadingMore: function () { return 'Meer resultaten laden…'; }, maximumSelected: function (args) { var verb = args.maximum == 1 ? 'kan' : 'kunnen'; var message = 'Er ' + verb + ' maar ' + args.maximum + ' item'; if (args.maximum != 1) { message += 's'; } message += ' worden geselecteerd'; return message; }, noResults: function () { return 'Geen resultaten gevonden…'; }, searching: function () { return 'Zoeken…'; } }; }); select2-4.0.1/src/js/select2/i18n/pl.js000066400000000000000000000024071262616323400173610ustar00rootroot00000000000000define(function () { // Polish var charsWords = ['znak', 'znaki', 'znaków']; var itemsWords = ['element', 'elementy', 'elementów']; var pluralWord = function pluralWord(numberOfChars, words) { if (numberOfChars === 1) { return words[0]; } else if (numberOfChars > 1 && numberOfChars <= 4) { return words[1]; } else if (numberOfChars >= 5) { return words[2]; } }; return { errorLoading: function () { return 'Nie można zaÅ‚adować wyników.'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; return 'UsuÅ„ ' + overChars + ' ' + pluralWord(overChars, charsWords); }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; return 'Podaj przynajmniej ' + remainingChars + ' ' + pluralWord(remainingChars, charsWords); }, loadingMore: function () { return 'Trwa Å‚adowanie…'; }, maximumSelected: function (args) { return 'Możesz zaznaczyć tylko ' + args.maximum + ' ' + pluralWord(args.maximum, itemsWords); }, noResults: function () { return 'Brak wyników'; }, searching: function () { return 'Trwa wyszukiwanie…'; } }; }); select2-4.0.1/src/js/select2/i18n/pt-BR.js000066400000000000000000000020721262616323400176700ustar00rootroot00000000000000define(function () { // Brazilian Portuguese return { errorLoading: function () { return 'Os resultados não puderam ser carregados.'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'Apague ' + overChars + ' caracter'; if (overChars != 1) { message += 'es'; } return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Digite ' + remainingChars + ' ou mais caracteres'; return message; }, loadingMore: function () { return 'Carregando mais resultados…'; }, maximumSelected: function (args) { var message = 'Você só pode selecionar ' + args.maximum + ' ite'; if (args.maximum == 1) { message += 'm'; } else { message += 'ns'; } return message; }, noResults: function () { return 'Nenhum resultado encontrado'; }, searching: function () { return 'Buscando…'; } }; }); select2-4.0.1/src/js/select2/i18n/pt.js000066400000000000000000000017771262616323400174020ustar00rootroot00000000000000define(function () { // European Portuguese return { errorLoading: function () { return 'Os resultados não puderam ser carregados.'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'Por favor apague ' + overChars + ' '; message += overChars != 1 ? 'caracteres' : 'carácter'; return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Introduza ' + remainingChars + ' ou mais caracteres'; return message; }, loadingMore: function () { return 'A carregar mais resultados…'; }, maximumSelected: function (args) { var message = 'Apenas pode seleccionar ' + args.maximum + ' '; message += args.maximum != 1 ? 'itens' : 'item'; return message; }, noResults: function () { return 'Sem resultados'; }, searching: function () { return 'A procurar…'; } }; }); select2-4.0.1/src/js/select2/i18n/ro.js000066400000000000000000000020711262616323400173630ustar00rootroot00000000000000define(function () { // Romanian return { inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'Vă rugăm să introduceÈ›i mai puÈ›in de ' + overChars; message += ' caracter'; if (message !== 1) { message += 'e'; } return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Vă rugăm să introduceÈ›i incă ' + remainingChars; message += ' caracter'; if (message !== 1) { message += 'e'; } return message; }, loadingMore: function () { return 'Se încarcă…'; }, maximumSelected: function (args) { var message = 'AveÈ›i voie să selectaÈ›i cel mult ' + args.maximum; message += ' element'; if (message !== 1) { message += 'e'; } return message; }, noResults: function () { return 'Nu a fost găsit nimic'; }, searching: function () { return 'Căutare…'; } }; }); select2-4.0.1/src/js/select2/i18n/ru.js000066400000000000000000000027671262616323400174050ustar00rootroot00000000000000define(function () { // Russian function ending (count, one, couple, more) { if (count % 10 < 5 && count % 10 > 0 && count % 100 < 5 || count % 100 > 20) { if (count % 10 > 1) { return couple; } } else { return more; } return one; } return { errorLoading: function () { return 'Ðевозможно загрузить результаты'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'ПожалуйÑта, введите на ' + overChars + ' Ñимвол'; message += ending(overChars, '', 'a', 'ов'); message += ' меньше'; return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'ПожалуйÑта, введите еще Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ ' + remainingChars + ' Ñимвол'; message += ending(remainingChars, '', 'a', 'ов'); return message; }, loadingMore: function () { return 'Загрузка данных…'; }, maximumSelected: function (args) { var message = 'Ð’Ñ‹ можете выбрать не более ' + args.maximum + ' Ñлемент'; message += ending(args.maximum, '', 'a', 'ов'); return message; }, noResults: function () { return 'Совпадений не найдено'; }, searching: function () { return 'ПоиÑк…'; } }; }); select2-4.0.1/src/js/select2/i18n/sk.js000066400000000000000000000033251262616323400173630ustar00rootroot00000000000000define(function () { // Slovak // use text for the numbers 2 through 4 var smallNumbers = { 2: function (masc) { return (masc ? 'dva' : 'dve'); }, 3: function () { return 'tri'; }, 4: function () { return 'Å¡tyri'; } }; return { inputTooLong: function (args) { var overChars = args.input.length - args.maximum; if (overChars == 1) { return 'Prosím, zadajte o jeden znak menej'; } else if (overChars >= 2 && overChars <= 4) { return 'Prosím, zadajte o ' + smallNumbers[overChars](true) + ' znaky menej'; } else { return 'Prosím, zadajte o ' + overChars + ' znakov menej'; } }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; if (remainingChars == 1) { return 'Prosím, zadajte eÅ¡te jeden znak'; } else if (remainingChars <= 4) { return 'Prosím, zadajte eÅ¡te ÄalÅ¡ie ' + smallNumbers[remainingChars](true) + ' znaky'; } else { return 'Prosím, zadajte eÅ¡te Äalších ' + remainingChars + ' znakov'; } }, loadingMore: function () { return 'Loading more results…'; }, maximumSelected: function (args) { if (args.maximum == 1) { return 'Môžete zvoliÅ¥ len jednu položku'; } else if (args.maximum >= 2 && args.maximum <= 4) { return 'Môžete zvoliÅ¥ najviac ' + smallNumbers[args.maximum](false) + ' položky'; } else { return 'Môžete zvoliÅ¥ najviac ' + args.maximum + ' položiek'; } }, noResults: function () { return 'NenaÅ¡li sa žiadne položky'; }, searching: function () { return 'Vyhľadávanie…'; } }; }); select2-4.0.1/src/js/select2/i18n/sr-Cyrl.js000066400000000000000000000026321262616323400203010ustar00rootroot00000000000000define(function () { // Serbian Cyrilic function ending (count, one, some, many) { if (count % 10 == 1 && count % 100 != 11) { return one; } if (count % 10 >= 2 && count % 10 <= 4 && (count % 100 < 12 || count % 100 > 14)) { return some; } return many; } return { errorLoading: function () { return 'Преузимање није уÑпело.'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'Обришите ' + overChars + ' Ñимбол'; message += ending(overChars, '', 'а', 'а'); return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Укуцајте бар још ' + remainingChars + ' Ñимбол'; message += ending(remainingChars, '', 'а', 'а'); return message; }, loadingMore: function () { return 'Преузимање још резултата…'; }, maximumSelected: function (args) { var message = 'Можете изабрати Ñамо ' + args.maximum + ' Ñтавк'; message += ending(args.maximum, 'у', 'е', 'и'); return message; }, noResults: function () { return 'Ðишта није пронађено'; }, searching: function () { return 'Претрага…'; } }; }); select2-4.0.1/src/js/select2/i18n/sr.js000066400000000000000000000024261262616323400173730ustar00rootroot00000000000000define(function () { // Serbian function ending (count, one, some, many) { if (count % 10 == 1 && count % 100 != 11) { return one; } if (count % 10 >= 2 && count % 10 <= 4 && (count % 100 < 12 || count % 100 > 14)) { return some; } return many; } return { errorLoading: function () { return 'Preuzimanje nije uspelo.'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'ObriÅ¡ite ' + overChars + ' simbol'; message += ending(overChars, '', 'a', 'a'); return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Ukucajte bar joÅ¡ ' + remainingChars + ' simbol'; message += ending(remainingChars, '', 'a', 'a'); return message; }, loadingMore: function () { return 'Preuzimanje joÅ¡ rezultata…'; }, maximumSelected: function (args) { var message = 'Možete izabrati samo ' + args.maximum + ' stavk'; message += ending(args.maximum, 'u', 'e', 'i'); return message; }, noResults: function () { return 'NiÅ¡ta nije pronaÄ‘eno'; }, searching: function () { return 'Pretraga…'; } }; }); select2-4.0.1/src/js/select2/i18n/sv.js000066400000000000000000000016071262616323400173770ustar00rootroot00000000000000define(function () { // Swedish return { errorLoading: function () { return 'Resultat kunde inte laddas.'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'Vänligen sudda ut ' + overChars + ' tecken'; return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Vänligen skriv in ' + remainingChars + ' eller fler tecken'; return message; }, loadingMore: function () { return 'Laddar fler resultat…'; }, maximumSelected: function (args) { var message = 'Du kan max välja ' + args.maximum + ' element'; return message; }, noResults: function () { return 'Inga träffar'; }, searching: function () { return 'Söker…'; } }; }); select2-4.0.1/src/js/select2/i18n/th.js000066400000000000000000000017771262616323400173720ustar00rootroot00000000000000define(function () { // Thai return { inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'โปรดลบออภ' + overChars + ' ตัวอัà¸à¸©à¸£'; return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'โปรดพิมพ์เพิ่มอีภ' + remainingChars + ' ตัวอัà¸à¸©à¸£'; return message; }, loadingMore: function () { return 'à¸à¸³à¸¥à¸±à¸‡à¸„้นข้อมูลเพิ่ม…'; }, maximumSelected: function (args) { var message = 'คุณสามารถเลือà¸à¹„ด้ไม่เà¸à¸´à¸™ ' + args.maximum + ' รายà¸à¸²à¸£'; return message; }, noResults: function () { return 'ไม่พบข้อมูล'; }, searching: function () { return 'à¸à¸³à¸¥à¸±à¸‡à¸„้นข้อมูล…'; } }; }); select2-4.0.1/src/js/select2/i18n/tr.js000066400000000000000000000014311262616323400173670ustar00rootroot00000000000000define(function () { // Turkish return { inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = overChars + ' karakter daha girmelisiniz'; return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'En az ' + remainingChars + ' karakter daha girmelisiniz'; return message; }, loadingMore: function () { return 'Daha fazla…'; }, maximumSelected: function (args) { var message = 'Sadece ' + args.maximum + ' seçim yapabilirsiniz'; return message; }, noResults: function () { return 'Sonuç bulunamadı'; }, searching: function () { return 'Aranıyor…'; } }; }); select2-4.0.1/src/js/select2/i18n/uk.js000066400000000000000000000025331262616323400173650ustar00rootroot00000000000000define(function () { // Ukranian function ending (count, one, couple, more) { if (count % 100 > 10 && count % 100 < 15) { return more; } if (count % 10 === 1) { return one; } if (count % 10 > 1 && count % 10 < 5) { return couple; } return more; } return { errorLoading: function () { return 'Ðеможливо завантажити результати'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; return 'Будь лаÑка, видаліть ' + overChars + ' ' + ending(args.maximum, 'літеру', 'літери', 'літер'); }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; return 'Будь лаÑка, введіть ' + remainingChars + ' або більше літер'; }, loadingMore: function () { return 'Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ–Ð½ÑˆÐ¸Ñ… результатів…'; }, maximumSelected: function (args) { return 'Ви можете вибрати лише ' + args.maximum + ' ' + ending(args.maximum, 'пункт', 'пункти', 'пунктів'); }, noResults: function () { return 'Ðічого не знайдено'; }, searching: function () { return 'Пошук…'; } }; }); select2-4.0.1/src/js/select2/i18n/vi.js000066400000000000000000000016351262616323400173660ustar00rootroot00000000000000define(function () { // Vietnamese return { inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'Vui lòng nhập ít hÆ¡n ' + overChars + ' ký tá»±'; if (overChars != 1) { message += 's'; } return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Vui lòng nhập nhiá»u hÆ¡n ' + remainingChars + ' ký tá»±"'; return message; }, loadingMore: function () { return 'Äang lấy thêm kết quả…'; }, maximumSelected: function (args) { var message = 'Chỉ có thể chá»n được ' + args.maximum + ' lá»±a chá»n'; return message; }, noResults: function () { return 'Không tìm thấy kết quả'; }, searching: function () { return 'Äang tìm…'; } }; }); select2-4.0.1/src/js/select2/i18n/zh-CN.js000066400000000000000000000015541262616323400176670ustar00rootroot00000000000000define(function () { // Chinese (Simplified) return { errorLoading: function () { return '无法载入结果。'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = '请删除' + overChars + '个字符'; return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = '请å†è¾“入至少' + remainingChars + '个字符'; return message; }, loadingMore: function () { return '载入更多结果…'; }, maximumSelected: function (args) { var message = '最多åªèƒ½é€‰æ‹©' + args.maximum + '个项目'; return message; }, noResults: function () { return '未找到结果'; }, searching: function () { return 'æœç´¢ä¸­â€¦'; } }; }); select2-4.0.1/src/js/select2/i18n/zh-TW.js000066400000000000000000000014321262616323400177140ustar00rootroot00000000000000define(function () { // Chinese (Traditional) return { inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = '請刪掉' + overChars + '個字元'; return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'è«‹å†è¼¸å…¥' + remainingChars + '個字元'; return message; }, loadingMore: function () { return '載入中…'; }, maximumSelected: function (args) { var message = 'ä½ åªèƒ½é¸æ“‡æœ€å¤š' + args.maximum + 'é …'; return message; }, noResults: function () { return '沒有找到相符的項目'; }, searching: function () { return 'æœå°‹ä¸­â€¦'; } }; }); select2-4.0.1/src/js/select2/keys.js000066400000000000000000000004731262616323400171430ustar00rootroot00000000000000define([ ], 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; }); select2-4.0.1/src/js/select2/options.js000066400000000000000000000062661262616323400176710ustar00rootroot00000000000000define([ '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 ($e.data('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.' ); } $e.data('data', $e.data('select2Tags')); $e.data('tags', true); } if ($e.data('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', $e.data('ajaxUrl')); $e.data('ajax--url', $e.data('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, $e.data()); } else { dataset = $e.data(); } 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; }); select2-4.0.1/src/js/select2/results.js000066400000000000000000000306721262616323400176750ustar00rootroot00000000000000define([ '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 = $( '
      ' ); 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 = $( '
    • ' ); 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.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 = $.data(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'); } }); 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'); } }); }; 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 = $('
        ', { 'class': 'select2-results__options select2-results__options--nested' }); $childrenContainer.append($children); $option.append(label); $option.append($childrenContainer); } else { this.template(data, option); } $.data(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(); } }); 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(); }); container.on('unselect', function () { if (!container.isOpen()) { return; } self.setClasses(); }); 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 = $highlighted.data('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 (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 - self.$results.scrollTop() + 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 = $this.data('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 = $(this).data('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; }); select2-4.0.1/src/js/select2/selection/000077500000000000000000000000001262616323400176135ustar00rootroot00000000000000select2-4.0.1/src/js/select2/selection/allowClear.js000066400000000000000000000044351262616323400222440ustar00rootroot00000000000000define([ 'jquery', '../keys' ], function ($, KEYS) { 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 = $clear.data('data'); for (var d = 0; d < data.length; d++) { var 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) { return; } } this.$element.val(this.placeholder.id).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 = $( '' + '×' + '' ); $remove.data('data', data); this.$selection.find('.select2-selection__rendered').prepend($remove); }; return AllowClear; }); select2-4.0.1/src/js/select2/selection/base.js000066400000000000000000000101541262616323400210640ustar00rootroot00000000000000define([ '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 = $( '' ); this._tabindex = 0; if (this.$element.data('old-tabindex') != null) { this._tabindex = this.$element.data('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(); 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 = $this.data('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; }); select2-4.0.1/src/js/select2/selection/clickMask.js000066400000000000000000000012141262616323400220500ustar00rootroot00000000000000define([ 'jquery' ], function ($) { function ClickMask () { } ClickMask.prototype.bind = function (decorate, $container, container) { var self = this; decorate.call(this, $container, container); this.$mask = $( '
        ' ); this.$mask.on('mousedown touchstart click', function () { self.trigger('close', {}); }); }; ClickMask.prototype._attachCloseHandler = function (decorate, container) { $(document.body).append(this.$mask); }; ClickMask.prototype._detachCloseHandler = function (deocrate, container) { this.$mask.detach(); }; return ClickMask; }); select2-4.0.1/src/js/select2/selection/eventRelay.js000066400000000000000000000021001262616323400222600ustar00rootroot00000000000000define([ 'jquery' ], function ($) { function EventRelay () { } EventRelay.prototype.bind = function (decorated, container, $container) { var self = this; var relayEvents = [ 'open', 'opening', 'close', 'closing', 'select', 'selecting', 'unselect', 'unselecting' ]; var preventableEvents = ['opening', 'closing', 'selecting', 'unselecting']; 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; }); select2-4.0.1/src/js/select2/selection/multiple.js000066400000000000000000000051511262616323400220060ustar00rootroot00000000000000define([ '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( '
          ' ); 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 = $selection.data('data'); self.trigger('unselect', { originalEvent: evt, data: data }); } ); }; MultipleSelection.prototype.clear = function () { this.$selection.find('.select2-selection__rendered').empty(); }; 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 = $( '
        • ' + '' + '×' + '' + '
        • ' ); 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.prop('title', selection.title || selection.text); $selection.data('data', selection); $selections.push($selection); } var $rendered = this.$selection.find('.select2-selection__rendered'); Utils.appendMany($rendered, $selections); }; return MultipleSelection; }); select2-4.0.1/src/js/select2/selection/placeholder.js000066400000000000000000000024121262616323400224320ustar00rootroot00000000000000define([ '../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; }); select2-4.0.1/src/js/select2/selection/search.js000066400000000000000000000140711262616323400214210ustar00rootroot00000000000000define([ 'jquery', '../utils', '../keys' ], function ($, Utils, KEYS) { function Search (decorated, $element, options) { decorated.call(this, $element, options); } Search.prototype.render = function (decorated) { var $search = $( '' ); 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 = $previousChoice.data('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) { 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; }); select2-4.0.1/src/js/select2/selection/single.js000066400000000000000000000045321262616323400214360ustar00rootroot00000000000000define([ '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( '' + '' + '' + '' ); 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); 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('selection:update', function (params) { self.update(params.data); }); }; SingleSelection.prototype.clear = function () { this.$selection.find('.select2-selection__rendered').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 $(''); }; 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.prop('title', selection.title || selection.text); }; return SingleSelection; }); select2-4.0.1/src/js/select2/selection/stopPropagation.js000066400000000000000000000013061262616323400233420ustar00rootroot00000000000000define([ ], 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; }); select2-4.0.1/src/js/select2/translation.js000066400000000000000000000013151262616323400205220ustar00rootroot00000000000000define([ '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; }); select2-4.0.1/src/js/select2/utils.js000066400000000000000000000142561262616323400173340ustar00rootroot00000000000000define([ '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; this.listeners = this.listeners || {}; 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); }; return Utils; }); select2-4.0.1/src/js/wrapper.end.js000066400000000000000000000007131262616323400170510ustar00rootroot00000000000000 // 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; })); select2-4.0.1/src/js/wrapper.start.js000066400000000000000000000013021262616323400174330ustar00rootroot00000000000000/*! * Select2 <%= package.version %> * 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 exports === 'object') { // Node/CommonJS factory(require('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 = select2-4.0.1/src/scss/000077500000000000000000000000001262616323400146245ustar00rootroot00000000000000select2-4.0.1/src/scss/_dropdown.scss000066400000000000000000000021221262616323400175110ustar00rootroot00000000000000.select2-dropdown { background-color: white; border: 1px solid #aaa; border-radius: 4px; box-sizing: border-box; display: block; position: absolute; left: -100000px; width: 100%; z-index: 1051; } .select2-results { display: block; } .select2-results__options { list-style: none; margin: 0; padding: 0; } .select2-results__option { padding: 6px; user-select: none; -webkit-user-select: none; &[aria-selected] { cursor: pointer; } } .select2-container--open .select2-dropdown { left: 0; } .select2-container--open .select2-dropdown--above { border-bottom: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; } .select2-container--open .select2-dropdown--below { border-top: none; border-top-left-radius: 0; border-top-right-radius: 0; } .select2-search--dropdown { display: block; padding: 4px; .select2-search__field { padding: 4px; width: 100%; box-sizing: border-box; &::-webkit-search-cancel-button { -webkit-appearance: none; } } &.select2-search--hide { display: none; } } select2-4.0.1/src/scss/_multiple.scss000066400000000000000000000011161262616323400175120ustar00rootroot00000000000000.select2-selection--multiple { box-sizing: border-box; cursor: pointer; display: block; min-height: 32px; user-select: none; -webkit-user-select: none; .select2-selection__rendered { display: inline-block; overflow: hidden; padding-left: 8px; text-overflow: ellipsis; white-space: nowrap; } } .select2-search--inline { float: left; .select2-search__field { box-sizing: border-box; border: none; font-size: 100%; margin-top: 5px; padding: 0; &::-webkit-search-cancel-button { -webkit-appearance: none; } } } select2-4.0.1/src/scss/_single.scss000066400000000000000000000010471262616323400171430ustar00rootroot00000000000000.select2-selection--single { box-sizing: border-box; cursor: pointer; display: block; height: 28px; user-select: none; -webkit-user-select: none; .select2-selection__rendered { display: block; padding-left: 8px; padding-right: 20px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .select2-selection__clear { position: relative; } } &[dir="rtl"] { .select2-selection--single { .select2-selection__rendered { padding-right: 8px; padding-left: 20px; } } } select2-4.0.1/src/scss/core.scss000066400000000000000000000015041262616323400164510ustar00rootroot00000000000000.select2-container { box-sizing: border-box; display: inline-block; margin: 0; position: relative; vertical-align: middle; @import "single"; @import "multiple"; } @import "dropdown"; .select2-close-mask { border: 0; margin: 0; padding: 0; display: block; position: fixed; left: 0; top: 0; min-height: 100%; min-width: 100%; height: auto; width: auto; opacity: 0; z-index: 99; // styles required for IE to work background-color: #fff; filter: alpha(opacity=0); } .select2-hidden-accessible { border: 0 !important; clip: rect(0 0 0 0) !important; height: 1px !important; margin: -1px !important; overflow: hidden !important; padding: 0 !important; position: absolute !important; width: 1px !important; } @import "theme/default/layout"; @import "theme/classic/layout"; select2-4.0.1/src/scss/mixins/000077500000000000000000000000001262616323400161335ustar00rootroot00000000000000select2-4.0.1/src/scss/mixins/_gradients.scss000066400000000000000000000020161262616323400211460ustar00rootroot00000000000000// https://github.com/twbs/bootstrap-sass/blob/3.3-stable/assets/stylesheets/bootstrap/mixins/_gradients.scss#L17-L27 // Vertical gradient, from top to bottom // // Creates two color stops, start and end, by specifying a color and position for each color stop. // Color stops are not available in IE9 and below. @mixin gradient-vertical($start-color: #555, $end-color: #333, $start-percent: 0%, $end-percent: 100%) { background-image: -webkit-linear-gradient(top, $start-color $start-percent, $end-color $end-percent); // Safari 5.1-6, Chrome 10+ background-image: -o-linear-gradient(top, $start-color $start-percent, $end-color $end-percent); // Opera 12 background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+ background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}', GradientType=0); // IE9 and down } select2-4.0.1/src/scss/theme/000077500000000000000000000000001262616323400157265ustar00rootroot00000000000000select2-4.0.1/src/scss/theme/classic/000077500000000000000000000000001262616323400173475ustar00rootroot00000000000000select2-4.0.1/src/scss/theme/classic/_defaults.scss000066400000000000000000000016111262616323400222110ustar00rootroot00000000000000$remove-color: #888 !default; $remove-hover-color: #555 !default; $remove-width: 20px !default; $selection-color: #444 !default; $border-color: #aaa !default; $border-radius: 4px !default; $focus-border-color: #5897fb !default; $container-height: 28px !default; $selection-bg-top-color: white !default; $selection-bg-bottom-color: #eeeeee !default; $container-placeholder-color: #999 !default; $container-focus-border-color: blue !default; $selection-opened-bg-top-color: $selection-bg-bottom-color !default; $selection-opened-bg-bottom-color: $selection-bg-top-color !default; $dropdown-z-index: 1 !default; $dropdown-bg-color: $selection-bg-top-color !default; $results-max-height: 200px !default; $results-nested-padding: 20px !default; $results-choice-bg-hover-color: #3875d7 !default; $results-choice-fg-hover-color: white !default; $results-choice-fg-unselectable-color: grey !default; select2-4.0.1/src/scss/theme/classic/_multiple.scss000066400000000000000000000030721262616323400222400ustar00rootroot00000000000000.select2-selection--multiple { background-color: white; border: 1px solid $border-color; border-radius: $border-radius; cursor: text; outline: 0; &:focus { border: 1px solid $focus-border-color; } .select2-selection__rendered { list-style: none; margin: 0; padding: 0 5px; } .select2-selection__clear { display: none; } .select2-selection__choice { background-color: #e4e4e4; border: 1px solid $border-color; border-radius: $border-radius; cursor: default; float: left; margin-right: 5px; margin-top: 5px; padding: 0 5px; } .select2-selection__choice__remove { color: $remove-color; cursor: pointer; display: inline-block; font-weight: bold; margin-right: 2px; &:hover { color: $remove-hover-color; } } } &[dir="rtl"] { .select2-selection--multiple { .select2-selection__choice { float: right; } .select2-selection__choice { margin-left: 5px; margin-right: auto; } .select2-selection__choice__remove { margin-left: 2px; margin-right: auto; } } } &.select2-container--open { .select2-selection--multiple { border: 1px solid $focus-border-color; } &.select2-container--above { .select2-selection--multiple { border-top: none; border-top-left-radius: 0; border-top-right-radius: 0; } } &.select2-container--below { .select2-selection--multiple { border-bottom: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; } } } select2-4.0.1/src/scss/theme/classic/_single.scss000066400000000000000000000047251262616323400216740ustar00rootroot00000000000000.select2-selection--single { background-color: mix($selection-bg-top-color, $selection-bg-bottom-color); border: 1px solid $border-color; border-radius: $border-radius; outline: 0; @include gradient-vertical($selection-bg-top-color, $selection-bg-bottom-color, 50%, 100%); &:focus { border: 1px solid $focus-border-color; } .select2-selection__rendered { color: #444; line-height: 28px; } .select2-selection__clear { cursor: pointer; float: right; font-weight: bold; margin-right: 10px; } .select2-selection__placeholder { color: #999; } .select2-selection__arrow { background-color: #ddd; border: none; border-left: 1px solid $border-color; border-top-right-radius: $border-radius; border-bottom-right-radius: $border-radius; height: 26px; position: absolute; top: 1px; right: 1px; width: 20px; @include gradient-vertical(#eeeeee, #cccccc, 50%, 100%); b { border-color: #888 transparent transparent transparent; border-style: solid; border-width: 5px 4px 0 4px; height: 0; left: 50%; margin-left: -4px; margin-top: -2px; position: absolute; top: 50%; width: 0; } } } &[dir="rtl"] { .select2-selection--single { .select2-selection__clear { float: left; } .select2-selection__arrow { border: none; border-right: 1px solid $border-color; border-radius: 0; border-top-left-radius: $border-radius; border-bottom-left-radius: $border-radius; left: 1px; right: auto; } } } &.select2-container--open { .select2-selection--single { border: 1px solid $focus-border-color; .select2-selection__arrow { background: transparent; border: none; b { border-color: transparent transparent #888 transparent; border-width: 0 4px 5px 4px; } } } &.select2-container--above { .select2-selection--single { border-top: none; border-top-left-radius: 0; border-top-right-radius: 0; @include gradient-vertical($selection-opened-bg-bottom-color, $selection-opened-bg-top-color, 0%, 50%); } } &.select2-container--below { .select2-selection--single { border-bottom: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; @include gradient-vertical($selection-opened-bg-top-color, $selection-opened-bg-bottom-color, 50%, 100%); } } } select2-4.0.1/src/scss/theme/classic/layout.scss000066400000000000000000000022661262616323400215670ustar00rootroot00000000000000@import "defaults"; @import "../../mixins/gradients"; .select2-container--classic { @import "single"; @import "multiple"; .select2-search--dropdown { .select2-search__field { border: 1px solid $border-color; outline: 0; } } .select2-search--inline { .select2-search__field { outline: 0; box-shadow: none; } } .select2-dropdown { background-color: $dropdown-bg-color; border: 1px solid transparent; } .select2-dropdown--above { border-bottom: none; } .select2-dropdown--below { border-top: none; } .select2-results > .select2-results__options { max-height: $results-max-height; overflow-y: auto; } .select2-results__option { &[role=group] { padding: 0; } &[aria-disabled=true] { color: $results-choice-fg-unselectable-color; } } .select2-results__option--highlighted[aria-selected] { background-color: $results-choice-bg-hover-color; color: $results-choice-fg-hover-color; } .select2-results__group { cursor: default; display: block; padding: 6px; } &.select2-container--open .select2-dropdown { border-color: $focus-border-color; } } select2-4.0.1/src/scss/theme/default/000077500000000000000000000000001262616323400173525ustar00rootroot00000000000000select2-4.0.1/src/scss/theme/default/_multiple.scss000066400000000000000000000030571262616323400222460ustar00rootroot00000000000000.select2-selection--multiple { background-color: white; border: 1px solid #aaa; border-radius: 4px; cursor: text; .select2-selection__rendered { box-sizing: border-box; list-style: none; margin: 0; padding: 0 5px; width: 100%; } .select2-selection__placeholder { color: #999; margin-top: 5px; float: left; } .select2-selection__clear { cursor: pointer; float: right; font-weight: bold; margin-top: 5px; margin-right: 10px; } .select2-selection__choice { background-color: #e4e4e4; border: 1px solid #aaa; border-radius: 4px; cursor: default; float: left; margin-right: 5px; margin-top: 5px; padding: 0 5px; } .select2-selection__choice__remove { color: #999; cursor: pointer; display: inline-block; font-weight: bold; margin-right: 2px; &:hover { color: #333; } } } &[dir="rtl"] { .select2-selection--multiple { .select2-selection__choice, .select2-selection__placeholder, .select2-search--inline { float: right; } .select2-selection__choice { margin-left: 5px; margin-right: auto; } .select2-selection__choice__remove { margin-left: 2px; margin-right: auto; } } } &.select2-container--focus { .select2-selection--multiple { border: solid black 1px; outline: 0; } } &.select2-container--disabled { .select2-selection--multiple { background-color: #eee; cursor: default; } .select2-selection__choice__remove { display: none; } } select2-4.0.1/src/scss/theme/default/_single.scss000066400000000000000000000024701262616323400216720ustar00rootroot00000000000000.select2-selection--single { background-color: #fff; border: 1px solid #aaa; border-radius: 4px; .select2-selection__rendered { color: #444; line-height: 28px; } .select2-selection__clear { cursor: pointer; float: right; font-weight: bold; } .select2-selection__placeholder { color: #999; } .select2-selection__arrow { height: 26px; position: absolute; top: 1px; right: 1px; width: 20px; b { border-color: #888 transparent transparent transparent; border-style: solid; border-width: 5px 4px 0 4px; height: 0; left: 50%; margin-left: -4px; margin-top: -2px; position: absolute; top: 50%; width: 0; } } } &[dir="rtl"] { .select2-selection--single { .select2-selection__clear { float: left; } .select2-selection__arrow { left: 1px; right: auto; } } } &.select2-container--disabled { .select2-selection--single { background-color: #eee; cursor: default; .select2-selection__clear { display: none; } } } &.select2-container--open { .select2-selection--single { .select2-selection__arrow { b { border-color: transparent transparent #888 transparent; border-width: 0 4px 5px 4px; } } } } select2-4.0.1/src/scss/theme/default/layout.scss000066400000000000000000000036461262616323400215750ustar00rootroot00000000000000.select2-container--default { @import "single"; @import "multiple"; &.select2-container--open.select2-container--above { .select2-selection--single, .select2-selection--multiple { border-top-left-radius: 0; border-top-right-radius: 0; } } &.select2-container--open.select2-container--below { .select2-selection--single, .select2-selection--multiple { border-bottom-left-radius: 0; border-bottom-right-radius: 0; } } .select2-search--dropdown { .select2-search__field { border: 1px solid #aaa; } } .select2-search--inline { .select2-search__field { background: transparent; border: none; outline: 0; box-shadow: none; -webkit-appearance: textfield; } } .select2-results > .select2-results__options { max-height: 200px; overflow-y: auto; } .select2-results__option { &[role=group] { padding: 0; } &[aria-disabled=true] { color: #999; } &[aria-selected=true] { background-color: #ddd; } .select2-results__option { padding-left: 1em; .select2-results__group { padding-left: 0; } .select2-results__option { margin-left: -1em; padding-left: 2em; .select2-results__option { margin-left: -2em; padding-left: 3em; .select2-results__option { margin-left: -3em; padding-left: 4em; .select2-results__option { margin-left: -4em; padding-left: 5em; .select2-results__option { margin-left: -5em; padding-left: 6em; } } } } } } } .select2-results__option--highlighted[aria-selected] { background-color: #5897fb; color: white; } .select2-results__group { cursor: default; display: block; padding: 6px; } } select2-4.0.1/tests/000077500000000000000000000000001262616323400142245ustar00rootroot00000000000000select2-4.0.1/tests/a11y/000077500000000000000000000000001262616323400147775ustar00rootroot00000000000000select2-4.0.1/tests/a11y/search-tests.js000066400000000000000000000027601262616323400177470ustar00rootroot00000000000000module('Accessibility - Search'); var MultipleSelection = require('select2/selection/multiple'); var InlineSearch = require('select2/selection/search'); var $ = require('jquery'); var Utils = require('select2/utils'); var Options = require('select2/options'); var options = new Options({}); test('aria-autocomplete attribute is present', function (assert) { var $select = $('#qunit-fixture .multiple'); var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); var selection = new CustomSelection($select, options); var $selection = selection.render(); // Update the selection so the search is rendered selection.update([]); assert.equal( $selection.find('input').attr('aria-autocomplete'), 'list', 'The search box is marked as autocomplete' ); }); test('aria-activedescendant should be removed when closed', function (assert) { var $select = $('#qunit-fixture .multiple'); var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); var selection = new CustomSelection($select, options); var $selection = selection.render(); var container = new MockContainer(); selection.bind(container, $('')); // Update the selection so the search is rendered selection.update([]); var $search = $selection.find('input'); $search.attr('aria-activedescendant', 'something'); container.trigger('close'); assert.ok( !$search.attr('aria-activedescendant'), 'There is no active descendant when the dropdown is closed' ); }); select2-4.0.1/tests/a11y/selection-tests.js000066400000000000000000000074331262616323400204710ustar00rootroot00000000000000module('Accessibility - All'); var BaseSelection = require('select2/selection/base'); var SingleSelection = require('select2/selection/single'); var MultipleSelection = require('select2/selection/multiple'); var $ = require('jquery'); var Options = require('select2/options'); var options = new Options({}); test('title is carried over from original element', function (assert) { var $select = $('#qunit-fixture .single'); var selection = new BaseSelection($select, options); var $selection = selection.render(); assert.equal( $selection.attr('title'), $select.attr('title'), 'The title should have been copied over from the original element' ); }); test('aria-expanded reflects the state of the container', function (assert) { var $select = $('#qunit-fixture .single'); var selection = new BaseSelection($select, options); var $selection = selection.render(); var container = new MockContainer(); selection.bind(container, $('')); assert.equal( $selection.attr('aria-expanded'), 'false', 'The container should not be expanded when it is closed' ); container.trigger('open'); assert.equal( $selection.attr('aria-expanded'), 'true', 'The container should be expanded when it is opened' ); }); test('static aria attributes are present', function (assert) { var $select = $('#qunit-fixture .single'); var selection = new BaseSelection($select, options); var $selection = selection.render(); assert.equal( $selection.attr('role'), 'combobox', 'The container should identify as a combobox' ); assert.equal( $selection.attr('aria-haspopup'), 'true', 'The dropdown is considered a popup of the container' ); }); test('the container should be in the tab order', function (assert) { var $select = $('#qunit-fixture .single'); var selection = new BaseSelection($select, options); var $selection = selection.render(); var container = new MockContainer(); selection.bind(container, $('')); assert.equal( $selection.attr('tabindex'), '0', 'The tab index should allow it to fit in the natural tab order' ); container.trigger('disable'); assert.equal( $selection.attr('tabindex'), '-1', 'The selection should be dropped out of the tab order when disabled' ); container.trigger('enable'); assert.equal( $selection.attr('tabindex'), '0', 'The tab index should be restored when re-enabled' ); }); test('a custom tabindex is copied', function (assert) { var $select = $('#qunit-fixture .single'); $select.attr('tabindex', '999'); var selection = new BaseSelection($select, options); var $selection = selection.render(); var container = new MockContainer(); selection.bind(container, $('')); assert.equal( $selection.attr('tabindex'), '999', 'The tab index should match the original tab index' ); container.trigger('disable'); assert.equal( $selection.attr('tabindex'), '-1', 'The selection should be dropped out of the tab order when disabled' ); container.trigger('enable'); assert.equal( $selection.attr('tabindex'), '999', 'The tab index should be restored when re-enabled' ); }); module('Accessibility - Single'); test('aria-labelledby should match the rendered container', function (assert) { var $select = $('#qunit-fixture .single'); var selection = new SingleSelection($select, options); var $selection = selection.render(); var container = new MockContainer(); selection.bind(container, $('')); var $rendered = $selection.find('.select2-selection__rendered'); assert.equal( $selection.attr('aria-labelledby'), $rendered.attr('id'), 'The rendered selection should label the container' ); }); module('Accessibility - Multiple'); select2-4.0.1/tests/data/000077500000000000000000000000001262616323400151355ustar00rootroot00000000000000select2-4.0.1/tests/data/array-tests.js000066400000000000000000000130261262616323400177530ustar00rootroot00000000000000module('Data adapters - Array'); var ArrayData = require('select2/data/array'); var $ = require('jquery'); var Options = require('select2/options'); var arrayOptions = new Options({ data: [ { id: 'default', text: 'Default' }, { id: '1', text: 'One' }, { id: '2', text: '2' } ] }); var extraOptions = new Options ({ data: [ { id: 'default', text: 'Default', extra: true }, { id: 'One', text: 'One', extra: true } ] }); var nestedOptions = new Options({ data: [ { text: 'Default', children: [ { text: 'Next', children: [ { id: 'a', text: 'Option' } ] } ] } ] }); test('current gets default for single', function (assert) { var $select = $('#qunit-fixture .single-empty'); var data = new ArrayData($select, arrayOptions); data.current(function (val) { assert.equal( val.length, 1, 'There should always be a selected item for array data.' ); var item = val[0]; assert.equal( item.id, 'default', 'The first item should be selected' ); }); }); test('current gets default for multiple', function (assert) { var $select = $('#qunit-fixture .multiple'); var data = new ArrayData($select, arrayOptions); data.current(function (val) { assert.equal( val.length, 0, 'There should be no default selection.' ); }); }); test('current works with existing selections', function (assert) { var $select = $('#qunit-fixture .multiple'); var data = new ArrayData($select, arrayOptions); $select.val(['One']); data.current(function (val) { assert.equal( val.length, 1, 'There should only be one existing selection.' ); var option = val[0]; assert.equal( option.id, 'One', 'The id should be equal to the value of the option tag.' ); assert.equal( option.text, 'One', 'The text should be equal to the text of the option tag.' ); }); }); test('current works with selected data', function (assert) { var $select = $('#qunit-fixture .single-empty'); var data = new ArrayData($select, arrayOptions); data.select({ id: '2', text: '2' }); data.current(function (val) { assert.equal( val.length, 1, 'There should only be one option selected.' ); var option = val[0]; assert.equal( option.id, '2', 'The id should match the original id from the array.' ); assert.equal( option.text, '2', 'The text should match the original text from the array.' ); }); }); test('select works for single', function (assert) { var $select = $('#qunit-fixture .single-empty'); var data = new ArrayData($select, arrayOptions); assert.equal( $select.val(), 'default', 'There should already be a selection' ); data.select({ id: '1', text: 'One' }); assert.equal( $select.val(), '1', 'The selected value should be the same as the selected id' ); }); test('multiple sets the value', function (assert) { var $select = $('#qunit-fixture .multiple'); var data = new ArrayData($select, arrayOptions); assert.equal($select.val(), null); data.select({ id: 'default', text: 'Default' }); assert.deepEqual($select.val(), ['default']); }); test('multiple adds to the old value', function (assert) { var $select = $('#qunit-fixture .multiple'); var data = new ArrayData($select, arrayOptions); $select.val(['One']); assert.deepEqual($select.val(), ['One']); data.select({ id: 'default', text: 'Default' }); assert.deepEqual($select.val(), ['One', 'default']); }); test('option tags are automatically generated', function (assert) { var $select = $('#qunit-fixture .single-empty'); var data = new ArrayData($select, arrayOptions); assert.equal( $select.find('option').length, 3, 'An element should be created for the two with children' ); }); test('optgroup tags have the right properties', function (assert) { var $select = $('#qunit-fixture .single-empty'); var data = new ArrayData($select, nestedOptions); var $group = $select.children('optgroup'); assert.equal( $group.prop('label'), 'Default', 'An `` label should match the text property' ); assert.equal( $group.children().length, 1, 'The should have one child under it' ); }); select2-4.0.1/tests/data/base-tests.js000066400000000000000000000012331262616323400175440ustar00rootroot00000000000000module('Data adapters - Base'); var BaseData = require('select2/data/base'); var $ = require('jquery'); var Options = require('select2/options'); var options = new Options({}); test('current is required', function (assert) { var data = new BaseData($('#qunit-fixture select'), options); assert.throws( function () { data.current(function () {}); }, 'current has no default implementation' ); }); test('query is required', function (assert) { var data = new BaseData($('#qunit-fixture select'), options); assert.throws( function () { data.query({}, function () {}); }, 'query has no default implementation' ); }); select2-4.0.1/tests/data/inputData-tests.js000066400000000000000000000055111262616323400205660ustar00rootroot00000000000000module('Data adapters - compatibility'); var $ = require('jquery'); var Options = require('select2/options'); var Utils = require('select2/utils'); var ArrayData = require('select2/data/array'); var InputData = require('select2/compat/inputData'); var InputAdapter = Utils.Decorate(ArrayData, InputData); test('test that options can be selected', function (assert) { var options = new Options({ data: [ { id: 'test', text: 'Test' } ] }); var $element = $(''); var adapter = new InputAdapter($element, options); adapter.select({ id: 'test' }); assert.equal( $element.val(), 'test', 'The id of the item should be the value' ); }); test('unselect the single selected option clears the value', function (assert) { var options = new Options({ data: [ { id: 'test', text: 'Test', selected: true } ] }); var $element = $(''); var adapter = new InputAdapter($element, options); adapter.unselect({ id: 'test' }); assert.equal( $element.val(), '', 'The id should no longer be in the value' ); }); test('options can be unselected individually', function (assert) { var options = new Options({ data: [ { id: 'test', text: 'Test' }, { id: 'test2', text: 'Test2' }, { id: 'test3', text: 'Test3' } ] }); var $element = $(''); $element.val('test,test2,test3'); var adapter = new InputAdapter($element, options); adapter.unselect({ id: 'test2' }); assert.equal( $element.val(), 'test,test3', 'The value should contain all the still selected options' ); }); test('default values can be set', function (assert) { expect(4); var options = new Options({ data: [ { id: 'test', text: 'Test' } ] }); var $element = $(''); var adapter = new InputAdapter($element, options); adapter.current(function (data) { assert.equal( data.length, 1, 'There should only be a single selected option' ); var item = data[0]; assert.equal(item.id, 'test'); assert.equal(item.text, 'Test'); }); assert.equal( $element.val(), 'test', 'The value should not have been altered' ); }); test('no default value', function (assert) { expect(2); var options = new Options({ data: [ { id: 'test', text: 'Test' } ] }); var $element = $(''); var adapter = new InputAdapter($element, options); adapter.current(function (data) { assert.equal( data.length, 0, 'There should be no selected options' ); }); assert.equal( $element.val(), '', 'The value should not have been altered' ); }); select2-4.0.1/tests/data/maximumInputLength-tests.js000066400000000000000000000052541262616323400225000ustar00rootroot00000000000000module('Data adapters - Maximum input length'); var MaximumInputLength = require('select2/data/maximumInputLength'); var $ = require('jquery'); var Options = require('select2/options'); var Utils = require('select2/utils'); function MaximumInputStub () { this.called = false; } MaximumInputStub.prototype.query = function (params, callback) { this.called = true; }; var MaximumInputData = Utils.Decorate(MaximumInputStub, MaximumInputLength); test('0 never displays the notice', function (assert) { var zeroOptions = new Options({ maximumInputLength: 0 }); var data = new MaximumInputData(null, zeroOptions); data.trigger = function () { assert.ok(false, 'No events should be triggered'); }; data.query({ term: '' }); assert.ok(data.called); data = new MaximumInputData(null, zeroOptions); data.query({ term: 'test' }); assert.ok(data.called); }); test('< 0 never displays the notice', function (assert) { var negativeOptions = new Options({ maximumInputLength: -1 }); var data = new MaximumInputData(null, negativeOptions); data.trigger = function () { assert.ok(false, 'No events should be triggered'); }; data.query({ term: '' }); assert.ok(data.called); data = new MaximumInputData(null, negativeOptions); data.query({ term: 'test' }); assert.ok(data.called); }); test('triggers when input is too long', function (assert) { var options = new Options({ maximumInputLength: 1 }); var data = new MaximumInputData(null, options); data.trigger = function () { assert.ok(true, 'The event should be triggered.'); }; data.query({ term: 'no' }); assert.ok(!data.called, 'The adapter should not be called'); }); test('does not trigger when equal', function (assert) { var options = new Options({ maximumInputLength: 10 }); var data = new MaximumInputData(null, options); data.trigger = function () { assert.ok(false, 'The event should not be triggered.'); }; data.query({ term: '1234567890' }); assert.ok(data.called); }); test('does not trigger when less', function (assert) { var options = new Options({ maximumInputLength: 10 }); var data = new MaximumInputData(null, options); data.trigger = function () { assert.ok(false, 'The event should not be triggered.'); }; data.query({ term: '123' }); assert.ok(data.called); }); test('works with null term', function (assert) { var options = new Options({ maximumInputLength: 1 }); var data = new MaximumInputData(null, options); data.trigger = function () { assert.ok(false, 'The event should not be triggered'); }; data.query({}); assert.ok(data.called); }); select2-4.0.1/tests/data/maximumSelectionLength-tests.js000066400000000000000000000072721262616323400233300ustar00rootroot00000000000000module('Data adapters - Maximum selection length'); var MaximumSelectionLength = require('select2/data/maximumSelectionLength'); var $ = require('jquery'); var Options = require('select2/options'); var Utils = require('select2/utils'); function MaximumSelectionStub () { this.called = false; this.currentData = []; } MaximumSelectionStub.prototype.current = function (callback) { callback(this.currentData); }; MaximumSelectionStub.prototype.val = function (val) { this.currentData.push(val); }; MaximumSelectionStub.prototype.query = function (params, callback) { this.called = true; }; var MaximumSelectionData = Utils.Decorate( MaximumSelectionStub, MaximumSelectionLength ); test('0 never displays the notice', function (assert) { var zeroOptions = new Options({ maximumSelectionLength: 0 }); var data = new MaximumSelectionData(null, zeroOptions); data.trigger = function () { assert.ok(false, 'No events should be triggered'); }; data.query({ term: '' }); assert.ok(data.called); data = new MaximumSelectionData(null, zeroOptions); data.trigger = function () { assert.ok(false, 'No events should be triggered'); }; data.val('1'); data.query({ term: '' }); assert.ok(data.called); data = new MaximumSelectionData(null, zeroOptions); data.trigger = function () { assert.ok(false, 'No events should be triggered'); }; data.val('1'); data.val('2'); data.query({ term: '' }); assert.ok(data.called); }); test('< 0 never displays the notice', function (assert) { var negativeOptions = new Options({ maximumSelectionLength: -1 }); var data = new MaximumSelectionData(null, negativeOptions); data.trigger = function () { assert.ok(false, 'No events should be triggered'); }; data.query({ term: '' }); assert.ok(data.called); data = new MaximumSelectionData(null, negativeOptions); data.trigger = function () { assert.ok(false, 'No events should be triggered'); }; data.val('1'); data.query({ term: '' }); assert.ok(data.called); data = new MaximumSelectionData(null, negativeOptions); data.trigger = function () { assert.ok(false, 'No events should be triggered'); }; data.val('1'); data.val('2'); data.query({ term: '' }); assert.ok(data.called); }); test('triggers when >= 1 selection' , function (assert) { var maxOfOneOptions = new Options({ maximumSelectionLength: 1 }); var data = new MaximumSelectionData(null, maxOfOneOptions); data.trigger = function () { assert.ok(false, 'No events should be triggered'); }; data.query({ term: '' }); assert.ok(data.called); data = new MaximumSelectionData(null, maxOfOneOptions); data.trigger = function () { assert.ok(true, 'The event should be triggered.'); }; data.val('1'); data.query({ term: '' }); assert.ok(!data.called); }); test('triggers when >= 2 selections' , function (assert) { var maxOfTwoOptions = new Options({ maximumSelectionLength: 2 }); var data = new MaximumSelectionData(null, maxOfTwoOptions); data.trigger = function () { assert.ok(false, 'No events should be triggered'); }; data.query({ term: '' }); assert.ok(data.called); data = new MaximumSelectionData(null, maxOfTwoOptions); data.trigger = function () { assert.ok(false, 'No events should be triggered'); }; data.val('1'); data.query({ term: '' }); assert.ok(data.called); data = new MaximumSelectionData(null, maxOfTwoOptions); data.trigger = function () { assert.ok(true, 'The event should be triggered.'); }; data.val('1'); data.val('2'); data.query({ term: '' }); assert.ok(!data.called); }); select2-4.0.1/tests/data/minimumInputLength-tests.js000066400000000000000000000051221262616323400224700ustar00rootroot00000000000000module('Data adapters - Minimum input length'); var MinimumInputLength = require('select2/data/minimumInputLength'); var $ = require('jquery'); var Options = require('select2/options'); var Utils = require('select2/utils'); function StubData () { this.called = false; } StubData.prototype.query = function (params, callback) { this.called = true; }; var MinimumData = Utils.Decorate(StubData, MinimumInputLength); test('0 never displays the notice', function (assert) { var zeroOptions = new Options({ minimumInputLength: 0 }); var data = new MinimumData(null, zeroOptions); data.trigger = function () { assert.ok(false, 'No events should be triggered'); }; data.query({ term: '' }); assert.ok(data.called); data = new MinimumData(null, zeroOptions); data.query({ term: 'test' }); assert.ok(data.called); }); test('< 0 never displays the notice', function (assert) { var negativeOptions = new Options({ minimumInputLength: -1 }); var data = new MinimumData(null, negativeOptions); data.trigger = function () { assert.ok(false, 'No events should be triggered'); }; data.query({ term: '' }); assert.ok(data.called); data = new MinimumData(null, negativeOptions); data.query({ term: 'test' }); assert.ok(data.called); }); test('triggers when input is not long enough', function (assert) { var options = new Options({ minimumInputLength: 10 }); var data = new MinimumData(null, options); data.trigger = function () { assert.ok(true, 'The event should be triggered.'); }; data.query({ term: 'no' }); assert.ok(!data.called); }); test('does not trigger when equal', function (assert) { var options = new Options({ minimumInputLength: 10 }); var data = new MinimumData(null, options); data.trigger = function () { assert.ok(false, 'The event should not be triggered.'); }; data.query({ term: '1234567890' }); assert.ok(data.called); }); test('does not trigger when greater', function (assert) { var options = new Options({ minimumInputLength: 10 }); var data = new MinimumData(null, options); data.trigger = function () { assert.ok(false, 'The event should not be triggered.'); }; data.query({ term: '12345678901' }); assert.ok(data.called); }); test('works with null term', function (assert) { var options = new Options({ minimumInputLength: 1 }); var data = new MinimumData(null, options); data.trigger = function () { assert.ok(true, 'The event should be triggered'); }; data.query({}); assert.ok(!data.called); }); select2-4.0.1/tests/data/select-tests.js000066400000000000000000000224431262616323400201170ustar00rootroot00000000000000module('Data adapters - Select - current'); var SelectData = require('select2/data/select'); var $ = require('jquery'); var Options = require('select2/options'); var selectOptions = new Options({}); test('current gets default for single', function (assert) { var $select = $('#qunit-fixture .single'); var data = new SelectData($select, selectOptions); data.current(function (data) { assert.equal( data.length, 1, 'There should only be one selected option' ); var option = data[0]; assert.equal( option.id, 'One', 'The value of the option tag should be the id' ); assert.equal( option.text, 'One', 'The text within the option tag should be the text' ); }); }); test('current gets default for multiple', function (assert) { var $select = $('#qunit-fixture .multiple'); var data = new SelectData($select, selectOptions); data.current(function (data) { assert.equal( data.length, 0, 'Multiple selects have no default selection.' ); }); }); test('current gets options with explicit value', function (assert) { var $select = $('#qunit-fixture .single'); var $option = $(''); $select.append($option); var data = new SelectData($select, selectOptions); $select.val('1'); data.current(function (data) { assert.equal( data.length, 1, 'There should be one selected option' ); var option = data[0]; assert.equal( option.id, '1', 'The option value should be the selected id' ); assert.equal( option.text, 'One', 'The text should match the text for the option tag' ); }); }); test('current gets options with implicit value', function (assert) { var $select = $('#qunit-fixture .single'); var data = new SelectData($select, selectOptions); $select.val('One'); data.current(function (val) { assert.equal( val.length, 1, 'There should only be one selected value' ); var option = val[0]; assert.equal( option.id, 'One', 'The id should be the same as the option text' ); assert.equal( option.text, 'One', 'The text should be the same as the option text' ); }); }); test('select works for single', function (assert) { var $select = $('#qunit-fixture .single-with-placeholder'); var data = new SelectData($select, selectOptions); assert.equal($select.val(), 'placeholder'); data.select({ id: 'One', text: 'One' }); assert.equal($select.val(), 'One'); }); test('multiple sets the value', function (assert) { var $select = $('#qunit-fixture .multiple'); var data = new SelectData($select, selectOptions); assert.equal($select.val(), null); data.select({ id: 'Two', text: 'Two' }); assert.deepEqual($select.val(), ['Two']); }); test('multiple adds to the old value', function (assert) { var $select = $('#qunit-fixture .multiple'); var data = new SelectData($select, selectOptions); $select.val(['Two']); assert.deepEqual($select.val(), ['Two']); data.select({ id: 'One', text: 'One' }); assert.deepEqual($select.val(), ['One', 'Two']); }); test('duplicates - single - same id on select triggers change', function (assert) { var $select = $('#qunit-fixture .duplicates'); var data = new SelectData($select, data); var second = $('#qunit-fixture .duplicates option')[2]; var changeTriggered = false; assert.equal($select.val(), 'one'); $select.on('change', function () { changeTriggered = true; }); data.select({ id: 'one', text: 'Uno', element: second }); assert.equal( $select.val(), 'one', 'The value never changed' ); assert.ok( changeTriggered, 'The change event should be triggered' ); assert.ok( second.selected, 'The second duplicate is selected, not the first' ); }); test('duplicates - single - different id on select triggers change', function (assert) { var $select = $('#qunit-fixture .duplicates'); var data = new SelectData($select, data); var second = $('#qunit-fixture .duplicates option')[2]; var changeTriggered = false; $select.val('two'); $select.on('change', function () { changeTriggered = true; }); data.select({ id: 'one', text: 'Uno', element: second }); assert.equal( $select.val(), 'one', 'The value changed to the duplicate id' ); assert.ok( changeTriggered, 'The change event should be triggered' ); assert.ok( second.selected, 'The second duplicate is selected, not the first' ); }); test('duplicates - multiple - same id on select triggers change', function (assert) { var $select = $('#qunit-fixture .duplicates-multi'); var data = new SelectData($select, data); var second = $('#qunit-fixture .duplicates-multi option')[2]; var changeTriggered = false; $select.val(['one']); $select.on('change', function () { changeTriggered = true; }); data.select({ id: 'one', text: 'Uno', element: second }); assert.deepEqual( $select.val(), ['one', 'one'], 'The value now has duplicates' ); assert.ok( changeTriggered, 'The change event should be triggered' ); assert.ok( second.selected, 'The second duplicate is selected, not the first' ); }); test('duplicates - multiple - different id on select triggers change', function (assert) { var $select = $('#qunit-fixture .duplicates-multi'); var data = new SelectData($select, data); var second = $('#qunit-fixture .duplicates-multi option')[2]; var changeTriggered = false; $select.val(['two']); $select.on('change', function () { changeTriggered = true; }); data.select({ id: 'one', text: 'Uno', element: second }); assert.deepEqual( $select.val(), ['two', 'one'], 'The value has the new id' ); assert.ok( changeTriggered, 'The change event should be triggered' ); assert.ok( second.selected, 'The second duplicate is selected, not the first' ); }); module('Data adapter - Select - query'); test('all options are returned with no term', function (assert) { var $select = $('#qunit-fixture .single'); var data = new SelectData($select, selectOptions); data.query({}, function (data) { assert.equal( data.results.length, 1, 'The number of items returned should be equal to the number of options' ); }); }); test('the matcher checks the text', function (assert) { var $select = $('#qunit-fixture .single'); var data = new SelectData($select, selectOptions); data.query({ term: 'One' }, function (data) { assert.equal( data.results.length, 1, 'Only the "One" option should be found' ); }); }); test('the matcher ignores case', function (assert) { var $select = $('#qunit-fixture .single'); var data = new SelectData($select, selectOptions); data.query({ term: 'one' }, function (data) { assert.equal( data.results.length, 1, 'The "One" option should still be found' ); }); }); test('no options may be returned with no matches', function (assert) { var $select = $('#qunit-fixture .single'); var data = new SelectData($select, selectOptions); data.query({ term: 'qwerty' }, function (data) { assert.equal( data.results.length, 0, 'Only matching items should be returned' ); }); }); test('optgroup tags are marked with children', function (assert) { var $select = $('#qunit-fixture .groups'); var data = new SelectData($select, selectOptions); data.query({}, function (data) { assert.ok( 'children' in data.results[0], 'The optgroup element should have children when queried' ); }); }); test('empty optgroups are still shown when queried', function (assert) { var $select = $('#qunit-fixture .groups'); var data = new SelectData($select, selectOptions); data.query({}, function (data) { assert.equal( data.results.length, 2, 'The empty optgroup element should still be returned when queried' ); var item = data.results[1]; assert.equal( item.text, 'Empty', 'The text of the empty optgroup should match the label' ); assert.equal( item.children.length, 0, 'There should be no children in the empty opgroup' ); }); }); test('multiple options with the same value are returned', function (assert) { var $select = $('#qunit-fixture .duplicates'); var data = new SelectData($select, selectOptions); data.query({}, function (data) { assert.equal( data.results.length, 3, 'The duplicate option should still be returned when queried' ); var first = data.results[0]; var duplicate = data.results[2]; assert.equal( first.id, duplicate.id, 'The duplicates should have the same id' ); assert.notEqual( first.text, duplicate.text, 'The duplicates do not have the same text' ); }); }); test('data objects use the text of the option', function (assert) { var $select = $('#qunit-fixture .duplicates'); var data = new SelectData($select, selectOptions); var $option = $(''); var item = data.item($option); assert.equal(item.id, '&'); assert.equal(item.text, '&'); }); select2-4.0.1/tests/data/tags-tests.js000066400000000000000000000122121262616323400175670ustar00rootroot00000000000000module('Data adapters - Tags'); var SelectData = require('select2/data/select'); var Tags = require('select2/data/tags'); var $ = require('jquery'); var Options = require('select2/options'); var Utils = require('select2/utils'); var SelectTags = Utils.Decorate(SelectData, Tags); var options = new Options({ tags: true }); test('does not trigger on blank or null terms', function (assert) { var data = new SelectTags($('#qunit-fixture .single'), options); data.query({ term: '' }, function (data) { assert.equal(data.results.length, 1); var item = data.results[0]; assert.equal(item.id, 'One'); assert.equal(item.text, 'One'); }); data.query({ term: null }, function (data) { assert.equal(data.results.length, 1); var item = data.results[0]; assert.equal(item.id, 'One'); assert.equal(item.text, 'One'); }); }); test('white space is trimmed by default', function (assert) { var data = new SelectTags($('#qunit-fixture .single'), options); data.query({ term: ' ' }, function (data) { assert.equal(data.results.length, 1); var item = data.results[0]; assert.equal(item.id, 'One'); assert.equal(item.text, 'One'); }); data.query({ term: ' One ' }, function (data) { assert.equal(data.results.length, 1); var item = data.results[0]; assert.equal(item.id, 'One'); assert.equal(item.text, 'One'); }); }); test('does not trigger for additional pages', function (assert) { var data = new SelectTags($('#qunit-fixture .single'), options); data.query({ page: 2 }, function (data) { assert.equal(data.results.length, 1); var item = data.results[0]; assert.equal(item.id, 'One'); assert.equal(item.text, 'One'); }); }); test('creates tag at beginning', function (assert) { var data = new SelectTags($('#qunit-fixture .single'), options); data.query({ term: 'o' }, function (data) { assert.equal(data.results.length, 2); var first = data.results[0]; assert.equal(first.id, 'o'); assert.equal(first.text, 'o'); }); }); test('tags can be the only result', function (assert) { var data = new SelectTags($('#qunit-fixture .single'), options); data.query({ term: 'test' }, function (data) { assert.equal(data.results.length, 1); var item = data.results[0]; assert.equal(item.id, 'test'); assert.equal(item.text, 'test'); }); }); test('tags are injected as options', function (assert) { var data = new SelectTags($('#qunit-fixture .single'), options); data.query({ term: 'test' }, function (data) { assert.equal(data.results.length, 1); var $children = $('#qunit-fixture .single option'); assert.equal($children.length, 2); var $tag = $children.last(); assert.equal($tag.val(), 'test'); assert.equal($tag.text(), 'test'); }); }); test('old tags are removed automatically', function (assert) { var data = new SelectTags($('#qunit-fixture .single'), options); data.query({ term: 'first' }, function (data) { assert.equal(data.results.length, 1); var $children = $('#qunit-fixture .single option'); assert.equal($children.length, 2); }); data.query({ term: 'second' }, function (data) { assert.equal(data.results.length, 1); var $children = $('#qunit-fixture .single option'); assert.equal($children.length, 2); var $tag = $children.last(); assert.equal($tag.val(), 'second'); assert.equal($tag.text(), 'second'); }); }); test('insertTag controls the tag location', function (assert) { var data = new SelectTags($('#qunit-fixture .single'), options); data.insertTag = function (data, tag) { data.push(tag); }; data.query({ term: 'o' }, function (data) { assert.equal(data.results.length, 2); var item = data.results[1]; assert.equal(item.id, 'o'); assert.equal(item.text, 'o'); }); }); test('createTag controls the tag object', function (assert) { var data = new SelectTags($('#qunit-fixture .single'), options); data.createTag = function (params) { return { id: 0, text: params.term }; }; data.query({ term: 'test' }, function (data) { assert.equal(data.results.length, 1); var item = data.results[0]; assert.equal(item.id, 0); assert.equal(item.text, 'test'); }); }); test('createTag returns null for no tag', function (assert) { var data = new SelectTags($('#qunit-fixture .single'), options); data.createTag = function (params) { return null; }; data.query({ term: 'o' }, function (data) { assert.equal(data.results.length, 1); }); }); test('the createTag options customizes the function', function (assert) { var data = new SelectTags( $('#qunit-fixture .single'), new Options({ tags: true, createTag: function (params) { return { id: params.term, text: params.term, tag: true }; } }) ); data.query({ term: 'test' }, function (data) { assert.equal(data.results.length, 1); var item = data.results[0]; assert.equal(item.id, 'test'); assert.equal(item.text, 'test'); assert.equal(item.tag, true); }); }); select2-4.0.1/tests/data/tokenizer-tests.js000066400000000000000000000076051262616323400206550ustar00rootroot00000000000000module('Data adaptor - Tokenizer'); test('triggers the select event', function (assert) { expect(2); var SelectData = require('select2/data/select'); var Tokenizer = require('select2/data/tokenizer'); var Tags = require('select2/data/tags'); var Options = require('select2/options'); var Utils = require('select2/utils'); var $ = require('jquery'); var TokenizedSelect = Utils.Decorate( Utils.Decorate(SelectData, Tags), Tokenizer ); var $select = $('#qunit-fixture .single'); var options = new Options({ tags: true, tokenSeparators: [','] }); var container = new MockContainer(); container.dropdown = container.selection = {}; var $container = $('
          '); var data = new TokenizedSelect($select, options); data.bind(container, $container); data.on('select', function () { assert.ok(true, 'The select event should be triggered'); }); data.query({ term: 'first,second' }, function () { assert.ok(true, 'The callback should have succeeded'); }); }); test('createTag can return null', function (assert) { expect(3); var SelectData = require('select2/data/select'); var Tokenizer = require('select2/data/tokenizer'); var Tags = require('select2/data/tags'); var Options = require('select2/options'); var Utils = require('select2/utils'); var $ = require('jquery'); var TokenizedSelect = Utils.Decorate( Utils.Decorate(SelectData, Tags), Tokenizer ); var $select = $('#qunit-fixture .single'); var options = new Options({ tags: true, tokenSeparators: [','], createTag: function () { assert.ok(true, 'createTag should have been called'); return null; } }); var container = new MockContainer(); container.dropdown = container.selection = {}; var $container = $('
          '); var data = new TokenizedSelect($select, options); data.bind(container, $container); data.on('select', function (params) { if (params.data == null) { assert.ok(false, 'Null data should never be selected'); } }); data.query({ term: 'first,second' }, function () { assert.ok(true, 'The callback should have succeeded'); }); }); test('createTag returning null does not cut the term', function (assert) { expect(4); var SelectData = require('select2/data/select'); var Tokenizer = require('select2/data/tokenizer'); var Tags = require('select2/data/tags'); var Options = require('select2/options'); var Utils = require('select2/utils'); var $ = require('jquery'); var TokenizedSelect = Utils.Decorate( Utils.Decorate(SelectData, Tags), Tokenizer ); var $select = $('#qunit-fixture .single'); var options = new Options({ tags: true, tokenSeparators: [',', '"'], createTag: function (params) { var term = params.term; // Ignore blanks if (term.length === 0) { return null; } // Ignore the leading quote if (term === '"') { return null; } // If there is a leading quote, check for a second one if (term[0] === '"' && term[term.length - 1] !== '"') { return null; } var text = term.substr(1, term.length - 2); return { id: term, text: text }; } }); var container = new MockContainer(); container.dropdown = container.selection = {}; var $container = $('
          '); var data = new TokenizedSelect($select, options); data.bind(container, $container); data.on('select', function (params) { assert.ok(params.data, 'Data should not be null'); assert.equal( params.data.id, '"first, second"', 'The id should have the quotes' ); assert.equal( params.data.text, 'first, second', 'The text should not have the quotes' ); }); data.query({ term: '"first, second",abc' }, function () { assert.ok(true, 'The callback should have succeeded'); }); });select2-4.0.1/tests/dropdown/000077500000000000000000000000001262616323400160605ustar00rootroot00000000000000select2-4.0.1/tests/dropdown/dropdownCss-tests.js000066400000000000000000000056461262616323400220760ustar00rootroot00000000000000module('Dropdown - dropdownCssClass compatibility'); var $ = require('jquery'); var Utils = require('select2/utils'); var Options = require('select2/options'); var Dropdown = require('select2/dropdown'); var DropdownCSS = Utils.Decorate( Dropdown, require('select2/compat/dropdownCss') ); test('all classes will be copied if :all: is used', function (assert) { var $element = $(''); var options = new Options({ dropdownCssClass: ':all:' }); var select = new DropdownCSS($element, options); var $dropdown = select.render(); assert.ok($dropdown.hasClass('test')); assert.ok($dropdown.hasClass('copy')); assert.ok($dropdown.hasClass('works')); assert.ok(!$dropdown.hasClass(':all:')); }); test(':all: can be used with other classes', function (assert) { var $element = $(''); var options = new Options({ dropdownCssClass: ':all: other' }); var select = new DropdownCSS($element, options); var $dropdown = select.render(); assert.ok($dropdown.hasClass('test')); assert.ok($dropdown.hasClass('copy')); assert.ok($dropdown.hasClass('works')); assert.ok($dropdown.hasClass('other')); assert.ok(!$dropdown.hasClass(':all:')); }); test('classes can be passed in as a string', function (assert) { var $element = $(''); var options = new Options({ dropdownCssClass: 'other' }); var select = new DropdownCSS($element, options); var $dropdown = select.render(); assert.ok($dropdown.hasClass('other')); }); test('a function can be used based on the element', function (assert){ var $element = $(''); var options = new Options({ dropdownCssClass: function ($element) { return 'function'; } }); var select = new DropdownCSS($element, options); var $dropdown = select.render(); assert.ok($dropdown.hasClass('function')); assert.ok(!$dropdown.hasClass('test')); }); test(':all: works around custom adapters', function (assert) { var $element = $(''); var options = new Options({ dropdownCssClass: ':all: something', adaptDropdownCssClass: function (clazz) { return clazz + '-modified'; } }); var select = new DropdownCSS($element, options); var $dropdown = select.render(); assert.ok($dropdown.hasClass('something')); assert.ok($dropdown.hasClass('test')); assert.ok($dropdown.hasClass('test-modified')); }); module('Dropdown - adaptDropdownCss compatibility'); test('only return when adapted', function (assert) { var $element = $(''); var options = new Options({ adaptDropdownCssClass: function (clazz) { return 'modified'; } }); var select = new DropdownCSS($element, options); var $dropdown = select.render(); assert.ok(!$dropdown.hasClass('original')); assert.ok($dropdown.hasClass('modified')); }); select2-4.0.1/tests/dropdown/selectOnClose-tests.js000066400000000000000000000060671262616323400223310ustar00rootroot00000000000000module('Dropdown - selectOnClose'); var $ = require('jquery'); var Utils = require('select2/utils'); var Options = require('select2/options'); var SelectData = require('select2/data/select'); var Results = require('select2/results'); var SelectOnClose = require('select2/dropdown/selectOnClose'); var ModifiedResults = Utils.Decorate(Results, SelectOnClose); var options = new Options({ selectOnClose: true }); test('will not trigger if no results were given', function (assert) { expect(0); var $element = $(''); var select = new ModifiedResults($element, options, new SelectData($element)); var $dropdown = select.render(); var container = new MockContainer(); select.bind(container, $('
          ')); select.on('select', function () { assert.ok(false, 'The select event should not have been triggered'); }); container.trigger('close'); }); test('will not trigger if the results list is empty', function (assert) { expect(1); var $element = $(''); var select = new ModifiedResults($element, options, new SelectData($element)); var $dropdown = select.render(); var container = new MockContainer(); select.bind(container, $('
          ')); select.on('select', function () { assert.ok(false, 'The select event should not have been triggered'); }); select.append({ results: [] }); assert.equal( $dropdown.find('li').length, 0, 'There should not be any results in the dropdown' ); container.trigger('close'); }); test('will not trigger if no results here highlighted', function (assert) { expect(2); var $element = $(''); var select = new ModifiedResults($element, options, new SelectData($element)); var $dropdown = select.render(); var container = new MockContainer(); select.bind(container, $('
          ')); select.on('select', function () { assert.ok(false, 'The select event should not have been triggered'); }); select.append({ results: [ { id: '1', text: 'Test' } ] }); assert.equal( $dropdown.find('li').length, 1, 'There should be one result in the dropdown' ); assert.equal( $.trim($dropdown.find('li').text()), 'Test', 'The result should be the same as the one we appended' ); container.trigger('close'); }); test('will trigger if there is a highlighted result', function (assert) { expect(2); var $element = $(''); var select = new ModifiedResults($element, options, new SelectData($element)); var $dropdown = select.render(); var container = new MockContainer(); select.bind(container, $('
          ')); select.on('select', function () { assert.ok(true, 'The select event should have been triggered'); }); select.append({ results: [ { id: '1', text: 'Test' } ] }); assert.equal( $dropdown.find('li').length, 1, 'There should be one result in the dropdown' ); $dropdown.find('li').addClass('select2-results__option--highlighted'); container.trigger('close'); }); select2-4.0.1/tests/dropdown/stopPropagation-tests.js000066400000000000000000000016341262616323400227530ustar00rootroot00000000000000module('Dropdown - Stoping event propagation'); var Dropdown = require('select2/dropdown'); var StopPropagation = require('select2/dropdown/stopPropagation'); var $ = require('jquery'); var Options = require('select2/options'); var Utils = require('select2/utils'); var CustomDropdown = Utils.Decorate(Dropdown, StopPropagation); var options = new Options(); test('click event does not propagate', function (assert) { expect(1); var $container = $('#qunit-fixture .event-container'); var container = new MockContainer(); var dropdown = new CustomDropdown($('#qunit-fixture select'), options); var $dropdown = dropdown.render(); dropdown.bind(container, $container); $container.append($dropdown); $container.on('click', function () { assert.ok(false, 'The click event should have been stopped'); }); $dropdown.trigger('click'); assert.ok(true, 'Something went wrong if this failed'); }); select2-4.0.1/tests/helpers.js000066400000000000000000000017511262616323400162300ustar00rootroot00000000000000// Restore the require/define var require = $.fn.select2.amd.require; var define = $.fn.select2.amd.define; // Disable jQuery's binding to $ jQuery.noConflict(); var Utils = require('select2/utils'); function MockContainer () { MockContainer.__super__.constructor.call(this); } Utils.Extend(MockContainer, Utils.Observable); MockContainer.prototype.isOpen = function () { return this.isOpen; }; var log = []; var testName; QUnit.done(function (test_results) { var tests = []; for(var i = 0, len = log.length; i < len; i++) { var details = log[i]; tests.push({ name: details.name, result: details.result, expected: details.expected, actual: details.actual, source: details.source }); } test_results.tests = tests; window.global_test_results = test_results; }); QUnit.testStart(function(testDetails){ QUnit.log(function(details){ if (!details.result) { details.name = testDetails.name; log.push(details); } }); }); select2-4.0.1/tests/integration.html000066400000000000000000000012251262616323400174350ustar00rootroot00000000000000
          select2-4.0.1/tests/integration/000077500000000000000000000000001262616323400165475ustar00rootroot00000000000000select2-4.0.1/tests/integration/select2-methods.js000066400000000000000000000052071262616323400221130ustar00rootroot00000000000000module('select2(data)'); var $ = require('jquery'); var Select2 = require('select2/core'); var Options = require('select2/options'); test('single default selection returned', function (assert) { var $select = $( '' ); var options = new Options({}); var select = new Select2($select, options); var items = select.data(); assert.equal( items.length, 1, 'The one selected item should be returned' ); var first = items[0]; assert.equal( first.id, '3', 'The first option was correct' ); assert.equal( first.text, 'Three', 'The first option was correct' ); }); test('multiple default selections returned', function (assert) { var $select = $( '' ); var options = new Options({}); var select = new Select2($select, options); var items = select.data(); assert.equal( items.length, 2, 'The two selected items should be returned' ); var first = items[0]; assert.equal( first.id, 'One', 'The first option was correct' ); var second = items[1]; assert.equal( second.id, '3', 'The option value should be pulled correctly' ); }); module('select2(val)'); test('single value matches jquery value', function (assert) { var $select = $( '' ); var options = new Options({}); var select = new Select2($select, options); var value = select.val(); assert.equal( value, '3', 'The value should match the option tag attribute' ); assert.equal( value, $select.val(), 'The value should match the jquery value' ); }); test('multiple value matches the jquery value', function (assert) { var $select = $( '' ); var options = new Options({}); var select = new Select2($select, options); var value = select.val(); assert.equal( value.length, 2, 'Two options should be selected' ); assert.deepEqual( value, ['One', '3'], 'The values should match the option tag attribute' ); assert.deepEqual( value, $select.val(), 'The values should match the jquery values' ); }); select2-4.0.1/tests/options/000077500000000000000000000000001262616323400157175ustar00rootroot00000000000000select2-4.0.1/tests/options/data-tests.js000066400000000000000000000020451262616323400203270ustar00rootroot00000000000000module('Options - Attributes'); var $ = require('jquery'); var Options = require('select2/options'); test('no nesting', function (assert) { var $test = $(''); var options = new Options({}, $test); assert.equal(options.get('test'), 'test'); }); test('with nesting', function (assert) { var $test = $(''); if ($test[0].dataset == null) { assert.ok( true, 'We can not run this test with jQuery 1.x if dataset is not implemented' ); return; } var options = new Options({}, $test); assert.ok(!(options.get('first-Second'))); assert.equal(options.get('first').second, 'test'); }); test('overrides initialized data', function (assert) { var $test = $(''); var options = new Options({ options: 'yes', override: 'no' }, $test); assert.equal(options.get('options'), 'yes'); assert.equal(options.get('override'), 'yes'); assert.equal(options.get('data'), 'yes'); }); select2-4.0.1/tests/options/deprecated-tests.js000066400000000000000000000121161262616323400215160ustar00rootroot00000000000000module('Options - Deprecated - initSelection'); var $ = require('jquery'); var Options = require('select2/options'); test('converted into dataAdapter.current', function (assert) { expect(5); var $test = $(''); var called = false; var options = new Options({ initSelection: function ($element, callback) { called = true; callback([{ id: '1', text: '2' }]); } }, $test); assert.ok(!called, 'initSelection should not have been called'); var DataAdapter = options.get('dataAdapter'); var data = new DataAdapter($test, options); data.current(function (data) { assert.equal( data.length, 1, 'There should have only been one object selected' ); var item = data[0]; assert.equal( item.id, '1', 'The id should have been set by initSelection' ); assert.equal( item.text, '2', 'The text should have been set by initSelection' ); }); assert.ok(called, 'initSelection should have been called'); }); test('single option converted to array automatically', function (assert) { expect(2); var $test = $(''); var called = false; var options = new Options({ initSelection: function ($element, callback) { called = true; callback({ id: '1', text: '2' }); } }, $test); var DataAdapter = options.get('dataAdapter'); var data = new DataAdapter($test, options); data.current(function (data) { assert.ok( $.isArray(data), 'The data should have been converted to an array' ); }); assert.ok(called, 'initSelection should have been called'); }); test('only called once', function (assert) { expect(8); var $test = $(''); var called = 0; var options = new Options({ initSelection: function ($element, callback) { called++; callback([{ id: '1', text: '2' }]); } }, $test); var DataAdapter = options.get('dataAdapter'); var data = new DataAdapter($test, options); data.current(function (data) { assert.equal( data.length, 1, 'There should have only been a single option' ); var item = data[0]; assert.equal( item.id, '1', 'The id should match the one given by initSelection' ); assert.equal( item.text, '2', 'The text should match the one given by initSelection' ); }); assert.equal( called, 1, 'initSelection should have been called' ); data.current(function (data) { assert.equal( data.length, 1, 'There should have only been a single option' ); var item = data[0]; assert.equal( item.id, '3', 'The id should match the value given in the DOM' ); assert.equal( item.text, '4', 'The text should match the text given in the DOM' ); }); assert.equal( called, 1, 'initSelection should have only been called once' ); }); module('Options - Deprecated - query'); test('converted into dataAdapter.query automatically', function (assert) { expect(6); var $test = $(''); var called = false; var options = new Options({ query: function (params) { called = true; params.callback({ results: [ { id: 'test', text: params.term } ] }); } }, $test); assert.ok(!called, 'The query option should not have been called'); var DataAdapter = options.get('dataAdapter'); var data = new DataAdapter($test, options); data.query({ term: 'term' }, function (data) { assert.ok( 'results' in data, 'It should have included the results key' ); assert.equal( data.results.length, 1, 'There should have only been a single result returned' ); var item = data.results[0]; assert.equal( item.id, 'test', 'The id should have been returned from the query function' ); assert.equal( item.text, 'term', 'The text should have matched the term that was passed in' ); }); assert.ok(called, 'The query function should have been called'); }); module('Options - deprecated - data-ajax-url'); test('converted ajax-url to ajax--url automatically', function (assert) { var $test = $(''); var options = new Options({}, $test); assert.ok( options.get('ajax'), 'The `ajax` key was automatically created' ); assert.equal( options.get('ajax').url, 'test://url', 'The `url` property for the `ajax` option was filled in correctly' ); }); test('converted select2-tags to data/tags automatically', function (assert) { var $test = $(''); var options = new Options({}, $test); assert.ok( options.get('tags'), 'The `tags` key is automatically set to true' ); assert.equal( options.get('data'), 'original data', 'The `data` key is created with the original data' ); }); select2-4.0.1/tests/options/translation-tests.js000066400000000000000000000011711262616323400217530ustar00rootroot00000000000000module('Options - Translations'); var $ = require('jquery'); var Options = require('select2/options'); test('partial dictionaries can be passed', function (assert) { var options = new Options({ language: { searching: function () { return 'Something'; } } }); var translations = options.get('translations'); assert.equal( translations.get('searching')(), 'Something', 'The partial dictionary still overrides translations' ); assert.equal( translations.get('noResults')(), 'No results found', 'You can still get English translations for keys not passed in' ); }); select2-4.0.1/tests/options/width-tests.js000066400000000000000000000032741262616323400205420ustar00rootroot00000000000000module('Options - Width'); var $ = require('jquery'); var Select2 = require('select2/core'); var select = new Select2($('')); test('string passed as width', function (assert) { var $test = $(''); var width = select._resolveWidth($test, '80%'); assert.equal(width, '80%'); }); test('width from style attribute', function (assert) { var $test = $(''); var width = select._resolveWidth($test, 'style'); assert.equal(width, null); }); test('width from computed element width', function (assert) { var $style = $( '' ); var $test = $(''); $('#qunit-fixture').append($style); $('#qunit-fixture').append($test); var width = select._resolveWidth($test, 'element'); assert.equal(width, '500px'); }); test('resolve gets the style if it is there', function (assert) { var $test = $(''); $('#qunit-fixture').append($style); $('#qunit-fixture').append($test); var width = select._resolveWidth($test, 'resolve'); assert.equal(width, '500px'); }); select2-4.0.1/tests/selection/000077500000000000000000000000001262616323400162115ustar00rootroot00000000000000select2-4.0.1/tests/selection/allowClear-tests.js000066400000000000000000000112731262616323400220000ustar00rootroot00000000000000module('Selection containers - Placeholders - Allow clear'); var Placeholder = require('select2/selection/placeholder'); var AllowClear = require('select2/selection/allowClear'); var SingleSelection = require('select2/selection/single'); var $ = require('jquery'); var Options = require('select2/options'); var Utils = require('select2/utils'); var AllowClearPlaceholder = Utils.Decorate( Utils.Decorate(SingleSelection, Placeholder), AllowClear ); var allowClearOptions = new Options({ placeholder: { id: 'placeholder', text: 'This is the placeholder' }, allowClear: true }); test('clear is not displayed for single placeholder', function (assert) { var selection = new AllowClearPlaceholder( $('#qunit-fixture .single-with-placeholder'), allowClearOptions ); var $selection = selection.render(); selection.update([{ id: 'placeholder' }]); assert.equal( $selection.find('.select2-selection__clear').length, 0, 'The clear icon should not be displayed' ); }); test('clear is not displayed for multiple placeholder', function (assert) { var selection = new AllowClearPlaceholder( $('#qunit-fixture .single-with-placeholder'), allowClearOptions ); var $selection = selection.render(); selection.update([]); assert.equal( $selection.find('.select2-selection__clear').length, 0, 'The clear icon should not be displayed' ); }); test('clear is displayed for placeholder', function (assert) { var selection = new AllowClearPlaceholder( $('#qunit-fixture .single-with-placeholder'), allowClearOptions ); var $selection = selection.render(); selection.update([{ id: 'one', test: 'one' }]); assert.equal( $selection.find('.select2-selection__clear').length, 1, 'The clear icon should be displayed' ); }); test('clicking clear will set the placeholder value', function (assert) { var $element = $('#qunit-fixture .single-with-placeholder'); var selection = new AllowClearPlaceholder( $element, allowClearOptions ); var container = new MockContainer(); var $selection = selection.render(); selection.bind(container, $('
          '); var options = new Options({ containerCssClass: ':all:' }); var select = new ContainerCSS($element, options); var $container = select.render(); assert.ok($container.hasClass('test')); assert.ok($container.hasClass('copy')); assert.ok($container.hasClass('works')); assert.ok(!$container.hasClass(':all:')); }); test(':all: can be used with other classes', function (assert) { var $element = $(''); var options = new Options({ containerCssClass: ':all: other' }); var select = new ContainerCSS($element, options); var $container = select.render(); assert.ok($container.hasClass('test')); assert.ok($container.hasClass('copy')); assert.ok($container.hasClass('works')); assert.ok($container.hasClass('other')); assert.ok(!$container.hasClass(':all:')); }); test('classes can be passed in as a string', function (assert) { var $element = $(''); var options = new Options({ containerCssClass: 'other' }); var select = new ContainerCSS($element, options); var $container = select.render(); assert.ok($container.hasClass('other')); }); test('a function can be used based on the element', function (assert){ var $element = $(''); var options = new Options({ containerCssClass: function ($element) { return 'function'; } }); var select = new ContainerCSS($element, options); var $container = select.render(); assert.ok($container.hasClass('function')); assert.ok(!$container.hasClass('test')); }); test(':all: works around custom adapters', function (assert) { var $element = $(''); var options = new Options({ containerCssClass: ':all: something', adaptContainerCssClass: function (clazz) { return clazz + '-modified'; } }); var select = new ContainerCSS($element, options); var $container = select.render(); assert.ok($container.hasClass('something')); assert.ok($container.hasClass('test')); assert.ok($container.hasClass('test-modified')); }); module('Selection - adaptContainerCss compatibility'); test('only return when adapted', function (assert) { var $element = $(''); var options = new Options({ adaptContainerCssClass: function (clazz) { return 'modified'; } }); var select = new ContainerCSS($element, options); var $container = select.render(); assert.ok(!$container.hasClass('original')); assert.ok($container.hasClass('modified')); }); select2-4.0.1/tests/selection/multiple-tests.js000066400000000000000000000062711262616323400215500ustar00rootroot00000000000000module('Selection containers - Multiple'); var MultipleSelection = require('select2/selection/multiple'); var $ = require('jquery'); var Options = require('select2/options'); var Utils = require('select2/utils'); var options = new Options({}); test('display uses templateSelection', function (assert) { var called = false; var templateOptions = new Options({ templateSelection: function (data) { called = true; return data.text; } }); var selection = new MultipleSelection( $('#qunit-fixture .multiple'), templateOptions ); var out = selection.display({ text: 'test' }); assert.ok(called); assert.equal(out, 'test'); }); test('templateSelection can addClass', function (assert) { var called = false; var templateOptions = new Options({ templateSelection: function (data, container) { called = true; container.addClass('testclass'); return data.text; } }); var selection = new MultipleSelection( $('#qunit-fixture .multiple'), templateOptions ); var $container = selection.selectionContainer(); var out = selection.display({ text: 'test' }, $container); assert.ok(called); assert.equal(out, 'test'); assert.ok($container.hasClass('testclass')); }); test('empty update clears the selection', function (assert) { var selection = new MultipleSelection( $('#qunit-fixture .multiple'), options ); var $selection = selection.render(); var $rendered = $selection.find('.select2-selection__rendered'); $rendered.text('testing'); selection.update([]); assert.equal($rendered.text(), ''); }); test('escapeMarkup is being used', function (assert) { var selection = new MultipleSelection( $('#qunit-fixture .multiple'), options ); var $selection = selection.render(); var $rendered = $selection.find('.select2-selection__rendered'); var unescapedText = ''; selection.update([{ text: unescapedText }]); assert.equal( $rendered.text().substr(1), unescapedText, 'The text should be escaped by default to prevent injection' ); }); test('clear button respects the disabled state', function (assert) { var options = new Options({ disabled: true }); var $select = $('#qunit-fixture .multiple'); var container = new MockContainer(); var $container = $('
          '); var selection = new MultipleSelection( $select, options ); var $selection = selection.render(); $container.append($selection); selection.bind(container, $container); // Select an option selection.update([{ text: 'Test' }]); var $rendered = $selection.find('.select2-selection__rendered'); var $pill = $rendered.find('.select2-selection__choice'); assert.equal($pill.length, 1, 'There should only be one selection'); var $remove = $pill.find('.select2-selection__choice__remove'); assert.equal( $remove.length, 1, 'The remove icon is displayed for the selection' ); // Set up the unselect handler selection.on('unselect', function (params) { assert.ok(false, 'The unselect handler should not be triggered'); }); // Trigger the handler for the remove icon $remove.trigger('click'); }); select2-4.0.1/tests/selection/placeholder-tests.js000066400000000000000000000034021262616323400221700ustar00rootroot00000000000000module('Selection containers - Placeholders'); var Placeholder = require('select2/selection/placeholder'); var SingleSelection = require('select2/selection/single'); var $ = require('jquery'); var Options = require('select2/options'); var Utils = require('select2/utils'); var SinglePlaceholder = Utils.Decorate(SingleSelection, Placeholder); var placeholderOptions = new Options({ placeholder: { id: 'placeholder', text: 'This is the placeholder' } }); test('normalizing placeholder ignores objects', function (assert) { var selection = new SinglePlaceholder( $('#qunit-fixture .single'), placeholderOptions ); var original = { id: 'test', text: 'testing' }; var normalized = selection.normalizePlaceholder(original); assert.equal(original, normalized); }); test('normalizing placeholder gives object for string', function (assert) { var selection = new SinglePlaceholder( $('#qunit-fixture .single'), placeholderOptions ); var normalized = selection.normalizePlaceholder('placeholder'); assert.equal(normalized.id, ''); assert.equal(normalized.text, 'placeholder'); }); test('text is shown for placeholder option on single', function (assert) { var selection = new SinglePlaceholder( $('#qunit-fixture .single'), placeholderOptions ); var $selection = selection.render(); selection.update([{ id: 'placeholder' }]); assert.equal($selection.text(), 'This is the placeholder'); }); test('placeholder is shown when no options are selected', function (assert) { var selection = new SinglePlaceholder( $('#qunit-fixture .multiple'), placeholderOptions ); var $selection = selection.render(); selection.update([]); assert.equal($selection.text(), 'This is the placeholder'); }); select2-4.0.1/tests/selection/search-tests.js000066400000000000000000000073661262616323400211700ustar00rootroot00000000000000module('Selection containers - Inline search'); var MultipleSelection = require('select2/selection/multiple'); var InlineSearch = require('select2/selection/search'); var $ = require('jquery'); var Options = require('select2/options'); var Utils = require('select2/utils'); var options = new Options({}); test('backspace will remove a choice', function (assert) { expect(3); var KEYS = require('select2/keys'); var $container = $('#qunit-fixture .event-container'); var container = new MockContainer(); var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); var $element = $('#qunit-fixture .multiple'); var selection = new CustomSelection($element, options); var $selection = selection.render(); selection.bind(container, $container); // The unselect event should be triggered at some point selection.on('unselect', function () { assert.ok(true, 'A choice was unselected'); }); // Add some selections and render the search selection.update([ { id: '1', text: 'One' } ]); var $search = $selection.find('input'); var $choices = $selection.find('.select2-selection__choice'); assert.equal($search.length, 1, 'The search was visible'); assert.equal($choices.length, 1, 'The choice was rendered'); // Trigger the backspace on the search var backspace = $.Event('keydown', { which: KEYS.BACKSPACE }); $search.trigger(backspace); }); test('backspace will set the search text', function (assert) { expect(3); var KEYS = require('select2/keys'); var $container = $('#qunit-fixture .event-container'); var container = new MockContainer(); var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); var $element = $('#qunit-fixture .multiple'); var selection = new CustomSelection($element, options); var $selection = selection.render(); selection.bind(container, $container); // Add some selections and render the search selection.update([ { id: '1', text: 'One' } ]); var $search = $selection.find('input'); var $choices = $selection.find('.select2-selection__choice'); assert.equal($search.length, 1, 'The search was visible'); assert.equal($choices.length, 1, 'The choice was rendered'); // Trigger the backspace on the search var backspace = $.Event('keydown', { which: KEYS.BACKSPACE }); $search.trigger(backspace); assert.equal($search.val(), 'One', 'The search text was set'); }); test('updating selection does not shift the focus', function (assert) { // Check for IE 8, which triggers a false negative during testing if (window.attachEvent && !window.addEventListener) { // We must expect 0 assertions or the test will fail expect(0); return; } var $container = $('#qunit-fixture .event-container'); var container = new MockContainer(); var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch); var $element = $('#qunit-fixture .multiple'); var selection = new CustomSelection($element, options); var $selection = selection.render(); selection.bind(container, $container); // Update the selection so the search is rendered selection.update([]); // Make it visible so the browser can place focus on the search $container.append($selection); var $search = $selection.find('input'); $search.trigger('focus'); assert.equal($search.length, 1, 'The search was not visible'); assert.equal( document.activeElement, $search[0], 'The search did not have focus originally' ); // Trigger an update, this should redraw the search box selection.update([]); assert.equal($search.length, 1, 'The search box disappeared'); assert.equal( document.activeElement, $search[0], 'The search did not have focus after the selection was updated' ); }); select2-4.0.1/tests/selection/single-tests.js000066400000000000000000000046421262616323400211760ustar00rootroot00000000000000module('Selection containers - Single'); var SingleSelection = require('select2/selection/single'); var $ = require('jquery'); var Options = require('select2/options'); var Utils = require('select2/utils'); var options = new Options({}); test('display uses templateSelection', function (assert) { var called = false; var templateOptions = new Options({ templateSelection: function (data) { called = true; return data.text; } }); var selection = new SingleSelection( $('#qunit-fixture .single'), templateOptions ); var out = selection.display({ text: 'test' }); assert.ok(called); assert.equal(out, 'test'); }); test('templateSelection can addClass', function (assert) { var called = false; var templateOptions = new Options({ templateSelection: function (data, container) { called = true; container.addClass('testclass'); return data.text; } }); var selection = new SingleSelection( $('#qunit-fixture .single'), templateOptions ); var $container = selection.selectionContainer(); var out = selection.display({ text: 'test' }, $container); assert.ok(called); assert.equal(out, 'test'); assert.ok($container.hasClass('testclass')); }); test('empty update clears the selection', function (assert) { var selection = new SingleSelection( $('#qunit-fixture .single'), options ); var $selection = selection.render(); var $rendered = $selection.find('.select2-selection__rendered'); $rendered.text('testing'); selection.update([]); assert.equal($rendered.text(), ''); }); test('update renders the data text', function (assert) { var selection = new SingleSelection( $('#qunit-fixture .single'), options ); var $selection = selection.render(); var $rendered = $selection.find('.select2-selection__rendered'); selection.update([{ text: 'test' }]); assert.equal($rendered.text(), 'test'); }); test('escapeMarkup is being used', function (assert) { var selection = new SingleSelection( $('#qunit-fixture .single'), options ); var $selection = selection.render(); var $rendered = $selection.find('.select2-selection__rendered'); var unescapedText = ''; selection.update([{ text: unescapedText }]); assert.equal( $rendered.text(), unescapedText, 'The text should be escaped by default to prevent injection' ); }); select2-4.0.1/tests/selection/stopPropagation-tests.js000066400000000000000000000017051262616323400231030ustar00rootroot00000000000000module('Selection containers - Stoping event propagation'); var SingleSelection = require('select2/selection/single'); var StopPropagation = require('select2/selection/stopPropagation'); var $ = require('jquery'); var Options = require('select2/options'); var Utils = require('select2/utils'); var CutomSelection = Utils.Decorate(SingleSelection, StopPropagation); var options = new Options(); test('click event does not propagate', function (assert) { expect(1); var $container = $('#qunit-fixture .event-container'); var container = new MockContainer(); var selection = new CutomSelection($('#qunit-fixture select'), options); var $selection = selection.render(); selection.bind(container, $container); $container.append($selection); $container.on('click', function () { assert.ok(false, 'The click event should have been stopped'); }); $selection.trigger('click'); assert.ok(true, 'Something went wrong if this failed'); }); select2-4.0.1/tests/unit.html000066400000000000000000000072561262616323400161030ustar00rootroot00000000000000
          select2-4.0.1/tests/utils/000077500000000000000000000000001262616323400153645ustar00rootroot00000000000000select2-4.0.1/tests/utils/decorator-tests.js000066400000000000000000000100221262616323400210370ustar00rootroot00000000000000module('Decorators'); var Utils = require('select2/utils'); test('overridden - method', function (assert) { function BaseClass () {} BaseClass.prototype.hello = function () { return 'A'; }; function DecoratorClass () {} DecoratorClass.prototype.hello = function () { return 'B'; }; var DecoratedClass = Utils.Decorate(BaseClass, DecoratorClass); var inst = new DecoratedClass(); assert.strictEqual(inst.hello(), 'B'); }); test('overridden - constructor', function (assert) { function BaseClass () { this.inherited = true; } BaseClass.prototype.hello = function () { return 'A'; }; function DecoratorClass (decorated) { this.called = true; } DecoratorClass.prototype.other = function () { return 'B'; }; var DecoratedClass = Utils.Decorate(BaseClass, DecoratorClass); var inst = new DecoratedClass(); assert.ok(inst.called); assert.ok(!inst.inherited); }); test('not overridden - method', function (assert) { function BaseClass () {} BaseClass.prototype.hello = function () { return 'A'; }; function DecoratorClass () {} DecoratorClass.prototype.other = function () { return 'B'; }; var DecoratedClass = Utils.Decorate(BaseClass, DecoratorClass); var inst = new DecoratedClass(); assert.strictEqual(inst.hello(), 'A'); }); test('not overridden - constructor', function (assert) { function BaseClass () { this.called = true; } BaseClass.prototype.hello = function () { return 'A'; }; function DecoratorClass () {} DecoratorClass.prototype.other = function () { return 'B'; }; var DecoratedClass = Utils.Decorate(BaseClass, DecoratorClass); var inst = new DecoratedClass(); assert.ok(inst.called); }); test('inherited - method', function (assert) { function BaseClass () {} BaseClass.prototype.hello = function () { return 'A'; }; function DecoratorClass (decorated) {} DecoratorClass.prototype.hello = function (decorated) { return 'B' + decorated.call(this) + 'C'; }; var DecoratedClass = Utils.Decorate(BaseClass, DecoratorClass); var inst = new DecoratedClass(); assert.strictEqual(inst.hello(), 'BAC'); }); test('inherited - constructor', function (assert) { function BaseClass () { this.inherited = true; } BaseClass.prototype.hello = function () { return 'A'; }; function DecoratorClass (decorated) { this.called = true; decorated.call(this); } DecoratorClass.prototype.other = function () { return 'B'; }; var DecoratedClass = Utils.Decorate(BaseClass, DecoratorClass); var inst = new DecoratedClass(); assert.ok(inst.called); assert.ok(inst.inherited); }); test('inherited - three levels', function (assert) { function BaseClass (testArgument) { this.baseCalled = true; this.baseTestArgument = testArgument; } BaseClass.prototype.test = function (a) { return a + 'c'; }; function MiddleClass (decorated, testArgument) { this.middleCalled = true; this.middleTestArgument = testArgument; decorated.call(this, testArgument); } MiddleClass.prototype.test = function (decorated, a) { return decorated.call(this, a + 'b'); }; function DecoratorClass (decorated, testArgument) { this.decoratorCalled = true; this.decoratorTestArgument = testArgument; decorated.call(this, testArgument); } DecoratorClass.prototype.test = function (decorated, a) { return decorated.call(this, a + 'a'); }; var DecoratedClass = Utils.Decorate( Utils.Decorate(BaseClass, MiddleClass), DecoratorClass ); var inst = new DecoratedClass('test'); assert.ok(inst.baseCalled, 'The base class contructor was called'); assert.ok(inst.middleCalled, 'The middle class constructor was called'); assert.ok(inst.decoratorCalled, 'The decorator constructor was called'); assert.strictEqual(inst.baseTestArgument, 'test'); assert.strictEqual(inst.middleTestArgument, 'test'); assert.strictEqual(inst.decoratorTestArgument, 'test'); var out = inst.test('test'); assert.strictEqual(out, 'testabc'); }); select2-4.0.1/tests/utils/escapeMarkup-tests.js000066400000000000000000000016721262616323400215100ustar00rootroot00000000000000module('Utils - escapeMarkup'); var Utils = require('select2/utils'); test('text passes through', function (assert) { var text = 'testing this'; var escaped = Utils.escapeMarkup(text); assert.equal(text, escaped); }); test('html tags are escaped', function (assert) { var text = ''; var escaped = Utils.escapeMarkup(text); assert.notEqual(text, escaped); assert.equal(escaped.indexOf('