├── MIT-LICENSE.txt
├── README.md
├── css
├── common.css
└── jquery.uix.multiselect.css
├── index.html
└── js
├── jquery.uix.multiselect.js
├── jquery.uix.multiselect.min.js
└── locales
├── jquery.uix.multiselect_de.js
├── jquery.uix.multiselect_en.js
├── jquery.uix.multiselect_es.js
├── jquery.uix.multiselect_et.js
├── jquery.uix.multiselect_fr.js
├── jquery.uix.multiselect_it.js
├── jquery.uix.multiselect_nl.js
├── jquery.uix.multiselect_pt.js
├── jquery.uix.multiselect_ru.js
└── jquery.uix.multiselect_sv.js
/MIT-LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012 yanick.rochon at gmail.com
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | jQuery UIx Multiselect
2 | ==================
3 | Version 2.0
4 |
5 | 
6 |
7 | Introduction
8 | ------------
9 |
10 | This widget is a complete rewrite of the [previous version](https://github.com/michael/multiselect). Why a new rewrite? Because the original widget's attempt was to create a all-in-one-out-of-the-box-multi-featured SELECT replacement and thus failed to be compliant with the DOMElement's behavior and limitations. Notably, it failed to :
11 |
12 | * update the option items when modifying the SELECT element directly
13 | * didn't support disabled items
14 | * didn't support item groups
15 | * etc.
16 |
17 | Also, it quickly became slow when loading a few hundred items and some branches had [drag](https://github.com/michael/multiselect/issues/91) [and](https://github.com/michael/multiselect/issues/124) [drop](https://github.com/michael/multiselect/issues/8) issues.
18 |
19 | Release notes
20 | -------------
21 |
22 | This widget is stable enough to be used in staging environments. However it is *still* under development, in testing phase, as some features may require more feedbacks yet! (Mainly browser compatiblity.) At this point, expect minor bug fixes within 72 hours, and there will be no more features planned at this point.
23 |
24 | The compressed (minified) version is created using the [YUI Compressor](http://refresh-sf.com/yui/).
25 |
26 | Requirements
27 | ------------
28 |
29 | * jQuery 1.8+
30 | * jQuery UI 1.9+
31 |
32 | Features
33 | --------
34 |
35 | * Support for disabled options
36 | * Support for option groups
37 | * Option group collapsable
38 | * Draggable drop and/or sortable enabled
39 | * Mouse selection mode (click, dblclick)
40 | * Support for predefined or custom sort functions
41 | * Searchable
42 | * List layout and select direction (horizontal or vertical)
43 | * Custom item renderer
44 |
45 |
46 | Usage
47 | -----
48 |
49 | **Note :** Even though it is a complete rewrite of the widget, I kept the `multiselect` widget name (but it is declared as `uix.multiselect` instead of [`ui.multiselect`](http://ajpiano.com/widgetfactory/#slide22)).
50 |
51 | $('selector').multiselect();
52 |
53 | To programmatically select/deselect, add/modify/remove items, you may access and modify the DOMElement directly, then call the `refresh` widget method to update it.
54 |
55 | $('selector').append("My Item 1 ")
56 | .multiselect('refresh');
57 |
58 | // manually filter available options
59 | // This will only render visible the available items containing 'My Item' (case insensitive)
60 | $('selector').multiselect('search', 'my item');
61 |
62 | $('selector').multiselect('destroy'); // restore original element
63 |
64 | See [wiki documentation](https://github.com/yanickrochon/jquery.uix.multiselect/wiki) for more information.
65 |
66 |
67 | TODO
68 | ----
69 |
70 | * add custom item rendering support *(needs more tests)*
71 | * HTML5 ARIA attributes
72 | * Make all options as mutable as possible after initialization.
73 | * Test in all major browsers *(not fully tested)*
74 | * Mobile support
75 | * Code cleanup
76 | * etc.
77 |
78 |
79 | Limitations
80 | -----------
81 |
82 | * When setting `sortable` option to `true`, options can only be reordered within their own groups. That is, an option cannot be
83 | reordered between two options of a different group. As this widget's purpose is not to extend the original element's behaviour
84 | beyound user interaction and presentation, this limitation shall not be lifted for the time being.
85 | * This widget was designed for modern browsers usage. It is working fine in IE7+, Firefox and Chrome. Note that it
86 | *will not work* in quirks mode. There will be little to no support for [non standards compliant browsers](http://www.ie6countdown.com/).
87 |
--------------------------------------------------------------------------------
/css/common.css:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | Copyright (c) 2007, Yahoo! Inc. All rights reserved.
4 | Code licensed under the BSD License:
5 | http://developer.yahoo.net/yui/license.txt
6 | version: 2.2.0
7 | */
8 | body {font:13px 'Helvetica',arial,clean,sans-serif;*font-size:small;*font:x-small;}table {font-size:inherit;font:100%;}select, input, textarea {font:99% arial,helvetica,clean,sans-serif;}pre, code {font:115% monospace;*font-size:100%;}body * {line-height:1.22em;}
9 | body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}/*ol,ul {list-style:none;}*/caption,th {text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym {border:0;}
10 |
11 | /* end of yahoo reset and fonts */
12 |
13 | body {color:#333; background: #232f2e; line-height:1.3;}
14 | p {margin:0 0 20px;}
15 | a {color:#636363;}
16 | a:hover {text-decoration:none;}
17 | strong {font-weight:bold;}
18 | em {font-style: italic;}
19 | h1,h2,h3,h4,h5,h6 {font-weight:bold;}
20 | h1 {font-size:197%; margin:30px 0; color: #4f6f6c;}
21 | h2 {font-size:174%; margin:20px 0; color:#4f6f6c;}
22 | h3 {font-size:152%; margin:10px 0;}
23 | h4 {font-size:129%; margin:10px 0;}
24 | pre {background:#eee; margin:0 0 20px; padding:20px; border:1px solid #ccc; font-size:100%; overflow:auto;}
25 | code {font-size:100%; margin:0; padding:0;}
26 | ul, ol {margin:10px 0 10px 25px;}
27 | ol li {margin:0 0 10px;}
28 |
29 | div#wrapper {background:#fff; width:560px; margin:0 auto; padding:20px; border:10px solid #0f1616; border-width:0 10px 10px 10px;}
30 | div#header {position:relative; border-bottom:1px dotted; margin:0 0 10px; padding:0 0 10px;}
31 | div#header p {margin:0; padding:0;}
32 | div#header h1 {margin:0; padding:0;}
33 | ul#nav {position:absolute; top:0; right:0; list-style:none; margin:0; padding:0;}
34 | ul#nav li {display:inline; padding:0 0 0 5px;}
35 | ul#nav li a {}
36 | div#content {}
37 | div#footer {margin:40px 0 0; border-top:1px dotted; padding:10px 0 0;}
38 | .left {float:left;}
39 | .right {float:right;}
40 | .clear {clear:both;}
41 |
42 |
43 | #content { width: 900px; margin: auto; padding: 1px 16px 64px 16px; background-color: white; }
44 |
45 | /* multiselect styles */
46 | #switcher {
47 |
48 | }
49 |
50 | form {margin: 0; padding: 0;}
51 |
--------------------------------------------------------------------------------
/css/jquery.uix.multiselect.css:
--------------------------------------------------------------------------------
1 |
2 |
3 | .uix-multiselect-original { position: absolute; left:-999999px; }
4 | .uix-multiselect { position: relative; float:left; }
5 | .uix-multiselect .multiselect-selected-list, .uix-multiselect .multiselect-available-list { position:absolute; overflow:hidden; }
6 | .uix-multiselect .ui-widget-header { overflow:hidden; white-space:nowrap; padding:2px 4px; }
7 | .uix-multiselect .ui-widget-header div.header-text { white-space: nowrap; }
8 | .uix-multiselect .ui-widget-header .uix-control-right, .uix-multiselect .ui-widget-header .uix-control-left { width:16px; height:16px; }
9 | .uix-multiselect .ui-widget-header .uix-control-right { float:right; }
10 | .uix-multiselect .ui-widget-header .uix-control-left { float:left; }
11 | .uix-multiselect .ui-widget-header .uix-search { float:right; height:14px; font-size:80%; }
12 | .uix-multiselect .uix-list-container { position:relative; overflow:auto; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }
13 | .uix-multiselect .uix-list-container .ui-priority-secondary { padding-right:0; }
14 | .uix-multiselect .group-element { position:relative; padding-left:0; white-space:nowrap; overflow:hidden; }
15 | .uix-multiselect .group-element-collapsable { padding-left:16px; }
16 | .uix-multiselect .group-element span.collapse-handle { position:absolute; margin-top:-8px; top:50%; left:0; }
17 | .uix-multiselect .group-element .label { margin:0 3px; white-space:nowrap; overflow:hidden; }
18 | .uix-multiselect .group-element .ui-icon { float:left; cursor:pointer; }
19 | .uix-multiselect .option-element, .dragged-element { cursor:pointer; padding:0 2px; }
20 | .uix-multiselect .option-element.ui-state-disabled { font-style:italic; }
21 | .dragged-element, .dragged-grouped-element { padding:1px 3px; }
22 | .dragged-grouped-element { padding-left:16px; }
23 | .uix-multiselect .grouped-option { position:relative; padding-left:16px }
24 | .uix-multiselect .grouped-option .ui-icon { position:absolute; left:0; }
25 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | jQuery Multiselect 2.0 Example Page
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
120 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
Welcome to the jQuery Multiselect 2.0 Widget !
151 |
152 |
153 |
154 | Change locale :
155 |
156 |
157 |
420 |
421 |
526 |
527 |
755 |
756 |
775 |
776 |
777 |
778 |
779 |
780 |
781 |
--------------------------------------------------------------------------------
/js/jquery.uix.multiselect.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UIx Multiselect 2.0
3 | *
4 | * Authors:
5 | * Yanick Rochon (yanick.rochon[at]gmail[dot]com)
6 | *
7 | * Licensed under the MIT (MIT-LICENSE.txt) license.
8 | *
9 | * http://mind2soft.com/labs/jquery/multiselect/
10 | *
11 | *
12 | * Depends:
13 | * jQuery UI 1.8+
14 | *
15 | */
16 |
17 | ;(function($, window, undefined) {
18 | // ECMAScript 5 Strict Mode: [John Resig Blog Post](http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/)
19 | "use strict";
20 |
21 | // Each instance must have their own drag and drop scope. We use a global page scope counter
22 | // so we do not create two instances with mistankenly the same scope! We do not support
23 | // cross instance drag and drop; this would require also copying the OPTION element and it
24 | // would slow the component down. This is not the widget's contract anyhow.
25 | var globalScope = 0;
26 |
27 | var DEF_OPTGROUP = '';
28 | var PRE_OPTGROUP = 'group-';
29 |
30 | // these events will trigger on the original element
31 | //var NATIVE_EVENTS = ["change"]; // for version 2.1
32 |
33 | // a list of predefined events
34 | //var EVENT_CHANGE = 'change'; // for version 2.1
35 | var EVENT_CHANGE = 'multiselectChange';
36 | //var EVENT_SEARCH = 'beforesearch'; // for version 2.1
37 | var EVENT_SEARCH = 'multiselectSearch';
38 | var EVENT_REORDERED = 'multiselectReordered';
39 |
40 | // The jQuery.uix namespace will automatically be created if it doesn't exist
41 | $.widget("uix.multiselect", {
42 | options: {
43 | availableListPosition: 'right',// 'top', 'right', 'bottom', 'left'; the position of the available list (default: 'right')
44 | // beforesearch: null, // a funciton called before searching. If the default is prevented, search will not happen (for version 2.1)
45 | collapsableGroups: true, // tells whether the option groups can be collapsed or not (default: true)
46 | created: null, // a function called when the widget is done loading (default: null)
47 | defaultGroupName: '', // the name of the default option group (default: '')
48 | filterSelected: false, // when searching, filter selected options also? (default: false)
49 | locale: 'auto', // any valid locale, 'auto', or '' for default built-in strings (default: 'auto')
50 | moveEffect: null, // 'blind','bounce','clip','drop','explode','fold','highlight','puff','pulsate','shake','slide' (default: null)
51 | moveEffectOptions: {}, // effect options (see jQuery UI documentation) (default: {})
52 | moveEffectSpeed: null, // string ('slow','fast') or number in millisecond (ignored if moveEffect is 'show') (default: null)
53 | optionRenderer: false, // a function that will return the item element to be rendered in the list (default: false)
54 | optionGroupRenderer: false, // a function that will return the group item element to be rendered (default: false)
55 | searchDelay: 500, // the search delay in ms (default: 500)
56 | searchField: 'toggle', // false, true, 'toggle'; set the search field behaviour (default: 'toggle')
57 | searchPreFilter: null, // prepare the search term before filtering.
58 | searchFilter: null, // a search filter. Will receive the term and OPTION element and should return a boolean value.
59 | searchHeader: 'available', // 'available', 'selected'; set the list header that will host the search field (default: 'available')
60 | selectionMode: 'click,d&d', // how options can be selected separated by commas: 'click', "dblclick" and 'd&d' (default: 'click,d&d')
61 | showDefaultGroupHeader: false, // show the default option group header (default: false)
62 | showEmptyGroups: false, // always display option groups even if empty (default: false)
63 | splitRatio: 0.55, // % of the left list's width of the widget total width (default 0.55)
64 | sortable: false, // if the selected list should be user sortable or not
65 | sortMethod: null, // null, 'standard', 'natural'; a sort function name (see ItemComparators), or a custom function (default: null)
66 | selectAll: 'both' // 'available', 'selected', 'both', 'none' - Whether or not to display a select or deselect all icon (default: 'both')
67 | },
68 |
69 | _create: function() {
70 | var that = this;
71 | var selListHeader, selListContent, avListHeader, avListContent;
72 | var btnSelectAll, btnDeselectAll;
73 |
74 | this.scope = 'multiselect' + (globalScope++);
75 | this.optionGroupIndex = 1;
76 | this._setLocale(this.options.locale);
77 |
78 | this.element.addClass('uix-multiselect-original');
79 | this._elementWrapper = $('
').addClass('uix-multiselect ui-widget')
80 | .css({
81 | width: this.element.css('width'),
82 | height: this.element.css('height')
83 | })
84 | .append(
85 | $('
').addClass('multiselect-selected-list')
86 | .append( $('
').addClass('ui-widget-header')
87 | .append( btnDeselectAll = $(' ', { type:"button" }).addClass('uix-control-right')
88 | .attr('data-localekey', 'deselectAll')
89 | .attr('title', this._t('deselectAll'))
90 | .button({icons:{primary:'ui-icon-arrowthickstop-1-e'}, text:false})
91 | .click(function(e) { e.preventDefault(); e.stopPropagation(); that.optionCache.setSelectedAll(false); return false; })
92 | ['both,selected'.indexOf(this.options.selectAll)>=0 ? 'show' : 'hide']()
93 | )
94 | .append( selListHeader = $('
').addClass('header-text') )
95 | )
96 | .append( selListContent = $('
').addClass('uix-list-container ui-widget-content') )
97 | )
98 | ['right,top'.indexOf(this.options.availableListPosition)>=0?'prepend':'append'](
99 | $('
').addClass('multiselect-available-list')
100 | .append( $('
').addClass('ui-widget-header')
101 | .append( btnSelectAll = $(' ', { type:"button" }).addClass('uix-control-right')
102 | .attr('data-localekey', 'selectAll')
103 | .attr('title', this._t('selectAll'))
104 | .button({icons:{primary:'ui-icon-arrowthickstop-1-w'}, text:false})
105 | .click(function(e) { e.preventDefault(); e.stopPropagation(); that.optionCache.setSelectedAll(true); return false; })
106 | ['both,available'.indexOf(this.options.selectAll)>=0 ? 'show' : 'hide']()
107 | )
108 | .append( avListHeader = $('
').addClass('header-text') )
109 |
110 | )
111 | .append( avListContent = $('
').addClass('uix-list-container ui-widget-content') )
112 | )
113 | .insertAfter(this.element)
114 | ;
115 |
116 | this._buttons = {
117 | 'selectAll': btnSelectAll,
118 | 'deselectAll': btnDeselectAll
119 | };
120 | this._headers = {
121 | 'selected': selListHeader,
122 | 'available': avListHeader
123 | };
124 | this._lists = {
125 | 'selected': selListContent.attr('id', this.scope+'_selListContent'),
126 | 'available': avListContent.attr('id', this.scope+'_avListContent')
127 | };
128 |
129 | this.optionCache = new OptionCache(this);
130 | this._searchDelayed = new SearchDelayed(this);
131 |
132 | this._initSearchable();
133 |
134 | this._applyListDroppable();
135 |
136 | this.refresh(this.options.created);
137 | },
138 |
139 | /**
140 | * ***************************************
141 | * PUBLIC
142 | * ***************************************
143 | */
144 |
145 | /**
146 | * Refresh all the lists from the underlaying element. This method is executed
147 | * asynchronously from the call, therefore it returns immediately. However, the
148 | * method accepts a callback parameter which will be executed when the refresh is
149 | * complete.
150 | *
151 | * @param callback function a callback function called when the refresh is complete
152 | */
153 | refresh: function(callback) {
154 | this._resize(); // just make sure we display the widget right without delay
155 | asyncFunction(function() {
156 | this.optionCache.cleanup();
157 |
158 | var opt, options = this.element[0].childNodes;
159 |
160 | for (var i=0, l1=options.length; i').addClass('uix-search ui-widget-content ui-corner-' + (isToggle ? 'left' : 'all'))[isToggle ? 'hide' : 'show']()
281 | .insertBefore( this._headers[searchHeader] )
282 | .focus(function() { $(this).select(); })
283 | .on("keydown keypress", function(e) { if (e.keyCode == 13) { e.preventDefault(); e.stopPropagation(); return false; } })
284 | .keyup($.proxy(this._searchDelayed.request, this._searchDelayed));
285 | }
286 | },
287 |
288 | _applyListDroppable: function() {
289 | if (this.options.selectionMode.indexOf('d&d') == -1) return;
290 |
291 | var _optionCache = this.optionCache;
292 | var currentScope = this.scope;
293 |
294 | var getElementData = function(d) {
295 | return _optionCache._elements[d.data('element-index')];
296 | };
297 |
298 | var initDroppable = function(e, s) {
299 | e.droppable({
300 | accept: function(draggable) {
301 | var eData = getElementData(draggable);
302 | return eData && (eData.selected != s); // from different seleciton only
303 | },
304 | activeClass: 'ui-state-highlight',
305 | scope: currentScope,
306 | drop: function(evt, ui) {
307 | ui.draggable.removeClass('ui-state-disabled');
308 | ui.helper.remove();
309 | _optionCache.setSelected(getElementData(ui.draggable), s);
310 | }
311 | });
312 | }
313 |
314 | initDroppable(this._lists['selected'], true);
315 | initDroppable(this._lists['available'], false);
316 |
317 | if (this.options.sortable) {
318 | var that = this;
319 | this._lists['selected'].sortable({
320 | appendTo: 'parent',
321 | axis: "y",
322 | containment: $('.multiselect-selected-list', this._elementWrapper), //"parent",
323 | items: '.multiselect-element-wrapper',
324 | handle: '.group-element',
325 | revert: true,
326 | stop: $.proxy(function(evt, ui) {
327 | var prevGroup;
328 | $('.multiselect-element-wrapper', that._lists['selected']).each(function() {
329 | var currGroup = that.optionCache._groups.get($(this).data('option-group'));
330 | if (!prevGroup) {
331 | that.element.append(currGroup.groupElement);
332 | } else {
333 | currGroup.groupElement.insertAfter(prevGroup.groupElement);
334 | }
335 | prevGroup = currGroup;
336 | });
337 | }, this)
338 | });
339 | }
340 | },
341 |
342 | _search: function(term, silent) {
343 | if (this._searchField.is(':visible')) {
344 | if (typeof term === "string") { // issue #36
345 | this._searchField.val(term);
346 | } else {
347 | term = this._searchField.val();
348 | }
349 | }
350 |
351 | this.optionCache.filter(term, silent);
352 | },
353 |
354 | _setLocale: function(locale) {
355 | if (locale == 'auto') {
356 | locale = navigator.userLanguage ||
357 | navigator.language ||
358 | navigator.browserLanguage ||
359 | navigator.systemLanguage ||
360 | '';
361 | }
362 | if (!$.uix.multiselect.i18n[locale]) {
363 | locale = ''; // revert to default is not supported auto locale
364 | }
365 | this.options.locale = locale;
366 | },
367 |
368 | _t: function(key, plural, data) {
369 | return _({locale:this.options.locale, key:key, plural:plural, data:data});
370 | },
371 |
372 | _updateControls: function() {
373 | var that = this;
374 | $('.uix-control-left,.uix-control-right', this._elementWrapper).each(function() {
375 | $(this).attr('title', that._t( $(this).attr('data-localekey') ));
376 | });
377 | },
378 |
379 | _updateHeaders: function() {
380 | var t, info = this.optionCache.getSelectionInfo();
381 |
382 | this._headers['selected']
383 | .text( t = this._t('itemsSelected', info.selected.total, {count:info.selected.total}) )
384 | .parent().attr('title',
385 | this.options.filterSelected
386 | ? this._t('itemsSelected', info.selected.count, {count:info.selected.count}) + ", " +
387 | this._t('itemsFiltered', info.selected.filtered, {count:info.selected.filtered})
388 | : t
389 | );
390 | this._headers['available']
391 | .text( this._t('itemsAvailable', info.available.total, {count:info.available.total}) )
392 | .parent().attr('title',
393 | this._t('itemsAvailable', info.available.count, {count:info.available.count}) + ", " +
394 | this._t('itemsFiltered', info.available.filtered, {count:info.available.filtered}) );
395 | },
396 |
397 | // call this method whenever the widget resizes
398 | // NOTE : the widget MUST be visible and have a width and height when calling this
399 | _resize: function() {
400 | var pos = this.options.availableListPosition.toLowerCase(); // shortcut
401 | var sSize = ('left,right'.indexOf(pos) >= 0) ? 'Width' : 'Height'; // split size fn
402 | var tSize = ('left,right'.indexOf(pos) >= 0) ? 'Height' : 'Width'; // total size fn
403 | var cSl = this.element['outer'+sSize]() * this.options.splitRatio; // list container size selected
404 | var cAv = this.element['outer'+sSize]() - cSl; // ... available
405 | var hSl = (tSize === 'Width') ? cSl : this.element.outerHeight(); // scrollable area size selected
406 | var hAv = (tSize === 'Width') ? cAv : this.element.outerHeight(); // ... available
407 | var styleRule = ('left,right'.indexOf(pos) >= 0) ? 'left' : 'top'; // CSS rule for offsetting
408 | var swap = ('left,top'.indexOf(pos) >= 0); // true if we swap left-right or top-bottom
409 | var isToggle = ('toggle' === this.options.searchField); // true if search field is toggle-able
410 | var headerBordersBoth = 'ui-corner-tl ui-corner-tr ui-corner-bl ui-corner-br ui-corner-top';
411 | var hSlCls = (tSize === 'Width') ? (swap ? '' : 'ui-corner-top') : (swap ? 'ui-corner-tr' : 'ui-corner-tl');
412 | var hAvCls = (tSize === 'Width') ? (swap ? 'ui-corner-top' : '') : (swap ? 'ui-corner-tl' : 'ui-corner-tr');
413 |
414 | // calculate outer lists dimensions
415 | this._elementWrapper.find('.multiselect-available-list')
416 | [sSize.toLowerCase()](cAv).css(styleRule, swap ? 0 : cSl)
417 | [tSize.toLowerCase()](this.element['outer'+tSize]() + 1); // account for borders
418 | this._elementWrapper.find('.multiselect-selected-list')
419 | [sSize.toLowerCase()](cSl).css(styleRule, swap ? cAv : 0)
420 | [tSize.toLowerCase()](this.element['outer'+tSize]() + 1); // account for borders
421 |
422 | // selection all button
423 | this._buttons['selectAll'].button('option', 'icons', {primary: transferIcon(pos, 'ui-icon-arrowthickstop-1-', false) });
424 | this._buttons['deselectAll'].button('option', 'icons', {primary: transferIcon(pos, 'ui-icon-arrowthickstop-1-', true) });
425 |
426 | // header borders
427 | this._headers['available'].parent().removeClass(headerBordersBoth).addClass(hAvCls);
428 | this._headers['selected'].parent().removeClass(headerBordersBoth).addClass(hSlCls);
429 |
430 | // make both headers equal!
431 | if (!isToggle) {
432 | var h = Math.max(this._headers['selected'].parent().height(), this._headers['available'].parent().height());
433 | this._headers['available'].parent().height(h);
434 | this._headers['selected'].parent().height(h);
435 | }
436 | // adjust search field width
437 | if (this._searchField) {
438 | this._searchField.width( (sSize === 'Width' ? cAv : this.element.width()) - (isToggle ? 52 : 26) ); // issue #50
439 | }
440 |
441 | // calculate inner lists height
442 | this._lists['available'].height(hAv - this._headers['available'].parent().outerHeight() - 2); // account for borders
443 | this._lists['selected'].height(hSl - this._headers['selected'].parent().outerHeight() - 2); // account for borders
444 | },
445 |
446 | /**
447 | * return false if the event was prevented by an handler, true otherwise
448 | */
449 | _triggerUIEvent: function(event, ui) {
450 | var eventType;
451 |
452 | if (typeof event === 'string') {
453 | eventType = event;
454 | event = $.Event(event);
455 | } else {
456 | eventType = event.type;
457 | }
458 |
459 | //console.log($.inArray(event.type, NATIVE_EVENTS));
460 |
461 | //if ($.inArray(event.type, NATIVE_EVENTS) > -1) {
462 | this.element.trigger(event, ui);
463 | //} else {
464 | // this._trigger(eventType, event, ui);
465 | //}
466 |
467 | return !event.isDefaultPrevented();
468 | },
469 |
470 | _setOption: function(key, value) {
471 | // Use the _setOption method to respond to changes to options
472 | switch(key) {
473 | // TODO
474 | }
475 | if (typeof(this._superApply) == 'function'){
476 | this._superApply(arguments);
477 | }else{
478 | $.Widget.prototype._setOption.apply(this, arguments);
479 | }
480 | }
481 | });
482 |
483 |
484 |
485 | /**
486 | * Comparator registry.
487 | *
488 | * function(a, b, g) where a is compared to b and g is true if they are groups
489 | */
490 | var ItemComparators = {
491 | /**
492 | * Naive general implementation
493 | */
494 | standard: function(a, b) {
495 | if (a > b) return 1;
496 | if (a < b) return -1;
497 | return 0;
498 | },
499 | /*
500 | * Natural Sort algorithm for Javascript - Version 0.7 - Released under MIT license
501 | * Author: Jim Palmer (based on chunking idea from Dave Koelle)
502 | */
503 | natural: function naturalSort(a, b) {
504 | var re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi,
505 | sre = /(^[ ]*|[ ]*$)/g,
506 | dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,
507 | hre = /^0x[0-9a-f]+$/i,
508 | ore = /^0/,
509 | i = function(s) { return naturalSort.insensitive && (''+s).toLowerCase() || ''+s },
510 | // convert all to strings strip whitespace
511 | x = i(a).replace(sre, '') || '',
512 | y = i(b).replace(sre, '') || '',
513 | // chunk/tokenize
514 | xN = x.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
515 | yN = y.replace(re, '\0$1\0').replace(/\0$/,'').replace(/^\0/,'').split('\0'),
516 | // numeric, hex or date detection
517 | xD = parseInt(x.match(hre)) || (xN.length != 1 && x.match(dre) && Date.parse(x)),
518 | yD = parseInt(y.match(hre)) || xD && y.match(dre) && Date.parse(y) || null,
519 | oFxNcL, oFyNcL;
520 | // first try and sort Hex codes or Dates
521 | if (yD)
522 | if ( xD < yD ) return -1;
523 | else if ( xD > yD ) return 1;
524 | // natural sorting through split numeric strings and default strings
525 | for(var cLoc=0, numS=Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {
526 | // find floats not starting with '0', string or 0 if not defined (Clint Priest)
527 | oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0;
528 | oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0;
529 | // handle numeric vs string comparison - number < string - (Kyle Adams)
530 | if (isNaN(oFxNcL) !== isNaN(oFyNcL)) { return (isNaN(oFxNcL)) ? 1 : -1; }
531 | // rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'
532 | else if (typeof oFxNcL !== typeof oFyNcL) {
533 | oFxNcL += '';
534 | oFyNcL += '';
535 | }
536 | if (oFxNcL < oFyNcL) return -1;
537 | if (oFxNcL > oFyNcL) return 1;
538 | }
539 | return 0;
540 | }
541 | };
542 |
543 |
544 | var transferDirection = ['n','e','s','w']; // button icon direction
545 | var transferOrientation = ['bottom','left','top','right']; // list of matching directions with icons
546 | var transferIcon = function(pos, prefix, selected) {
547 | return prefix + transferDirection[($.inArray(pos.toLowerCase(), transferOrientation) + (selected ? 2 : 0)) % 4];
548 | };
549 |
550 | /**
551 | * setTimeout on steroids!
552 | */
553 | var asyncFunction = function(callback, timeout, self) {
554 | var args = Array.prototype.slice.call(arguments, 3);
555 | return setTimeout(function() {
556 | callback.apply(self || window, args);
557 | }, timeout);
558 | };
559 |
560 |
561 | var SearchDelayed = function(widget, options) {
562 | this._widget = widget;
563 | this._options = options;
564 | this._lastSearchValue = null;
565 | };
566 |
567 | SearchDelayed.prototype = {
568 | request: function() {
569 | if (this._widget._searchField.val() == this._lastSearchValue) return; // prevent searching twice same term
570 |
571 | this.cancelLastRequest();
572 |
573 | this._timeout = asyncFunction(function() {
574 | this._timeout = null;
575 | this._lastSearchValue = this._widget._searchField.val();
576 |
577 | this._widget._search();
578 | }, this._widget.options.searchDelay, this);
579 | },
580 | cancelLastRequest: function() {
581 | if (this._timeout) {
582 | clearTimeout(this._timeout);
583 | }
584 | }
585 | };
586 |
587 | /**
588 | * Map of all option groups
589 | */
590 | var GroupCache = function(comp) {
591 | // private members
592 |
593 | var keys = [];
594 | var items = {};
595 | var comparator = comp;
596 |
597 | // public methods
598 |
599 | this.setComparator = function(comp) {
600 | comparator = comp;
601 | return this;
602 | };
603 |
604 | this.clear = function() {
605 | keys = [];
606 | items = {};
607 | return this;
608 | };
609 |
610 | this.containsKey = function(key) {
611 | return !!items[key];
612 | };
613 |
614 | this.get = function(key) {
615 | return items[key];
616 | };
617 |
618 | this.put = function(key, val) {
619 | if (!items[key]) {
620 | if (comparator) {
621 | keys.splice((function() {
622 | var low = 0, high = keys.length;
623 | var mid = -1, c = 0;
624 | while (low < high) {
625 | mid = parseInt((low + high)/2);
626 | var a = items[keys[mid]].groupElement;
627 | var b = val.groupElement;
628 | c = comparator(a ? a.attr('label') : DEF_OPTGROUP, b ? b.attr('label') : DEF_OPTGROUP);
629 | if (c < 0) {
630 | low = mid + 1;
631 | } else if (c > 0) {
632 | high = mid;
633 | } else {
634 | return mid;
635 | }
636 | }
637 | return low;
638 | })(), 0, key);
639 | } else {
640 | keys.push(key);
641 | }
642 | }
643 |
644 | items[key] = val;
645 | return this;
646 | };
647 |
648 | this.remove = function(key) {
649 | delete items[key];
650 | return keys.splice(keys.indexOf(key), 1);
651 | };
652 |
653 | this.each = function(callback) {
654 | var args = Array.prototype.slice.call(arguments, 1);
655 | args.splice(0, 0, null, null);
656 | for (var i=0, len=keys.length; i').appendTo(this._widget._lists['selected']),
670 | 'available': $('
').appendTo(this._widget._lists['available'])
671 | };
672 |
673 | this._elements = [];
674 | this._groups = new GroupCache();
675 |
676 | this._moveEffect = {
677 | fn: widget.options.moveEffect,
678 | options: widget.options.moveEffectOptions,
679 | speed: widget.options.moveEffectSpeed
680 | };
681 |
682 | this._selectionMode = this._widget.options.selectionMode.indexOf('dblclick') > -1 ? 'dblclick'
683 | : this._widget.options.selectionMode.indexOf('click') > -1 ? 'click' : false;
684 |
685 | this.reset();
686 | };
687 |
688 | OptionCache.Options = {
689 | batchCount: 200,
690 | batchDelay: 50
691 | };
692 |
693 | OptionCache.prototype = {
694 | _createGroupElement: function(grpElement, optGroup, selected) {
695 | var that = this;
696 | var gData;
697 |
698 | var getLocalData = function() {
699 | if (!gData) gData = that._groups.get(optGroup);
700 | return gData;
701 | };
702 |
703 | var getGroupName = function() {
704 | return grpElement ? grpElement.attr('label') : that._widget.options.defaultGroupName;
705 | };
706 |
707 | var labelCount = $(' ').addClass('label')
708 | .text(getGroupName() + ' (0)')
709 | .attr('title', getGroupName() + ' (0)');
710 |
711 | var fnUpdateCount = function() {
712 | var gDataDst = getLocalData()[selected?'selected':'available'];
713 |
714 | gDataDst.listElement[(!selected && (gDataDst.count || that._widget.options.showEmptyGroups)) || (gDataDst.count && ((gData.optionGroup != DEF_OPTGROUP) || that._widget.options.showDefaultGroupHeader)) ? 'show' : 'hide']();
715 |
716 | var t = getGroupName() + ' (' + gDataDst.count + ')';
717 | labelCount.text(t).attr('title', t);
718 | };
719 |
720 | var e = $('
')
721 | .addClass('ui-widget-header ui-priority-secondary group-element')
722 | .append( $(' ', { type:"button" }).addClass('uix-control-right')
723 | .attr('data-localekey', (selected?'de':'')+'selectAllGroup')
724 | .attr('title', this._widget._t((selected?'de':'')+'selectAllGroup'))
725 | .button({icons:{primary:transferIcon(this._widget.options.availableListPosition, 'ui-icon-arrowstop-1-', selected)}, text:false})
726 | .click(function(e) {
727 | e.preventDefault(); e.stopPropagation();
728 |
729 | var gDataDst = getLocalData()[selected?'selected':'available'];
730 |
731 | if (gData.count > 0) {
732 | var _transferedOptions = [];
733 |
734 | that._bufferedMode(true);
735 | for (var i=gData.startIndex, len=gData.startIndex+gData.count, eData; i').addClass('ui-icon collapse-handle')
763 | .attr('data-localekey', 'collapseGroup')
764 | .attr('title', this._widget._t('collapseGroup'))
765 | .addClass(grpCollapseIcon)
766 | .mousedown(function(e) { e.stopPropagation(); })
767 | .click(function(e) { e.preventDefault(); e.stopPropagation(); fnToggle(grpElement); return false; })
768 | .prependTo(e.addClass('group-element-collapsable'))
769 | ;
770 |
771 | fnToggle = function(grpElement) {
772 | var gDataDst = getLocalData()[selected?'selected':'available'],
773 | collapseIconAttr = (grpElement) ? grpElement.attr('data-collapse-icon') : null,
774 | expandIconAttr = (grpElement) ? grpElement.attr('data-expand-icon') : null,
775 | collapseIcon = (collapseIconAttr) ? 'ui-icon ' + collapseIconAttr : 'ui-icon ui-icon-triangle-1-s',
776 | expandIcon = (expandIconAttr) ? 'ui-icon ' + expandIconAttr : 'ui-icon ui-icon-triangle-1-e';
777 | gDataDst.collapsed = !gDataDst.collapsed;
778 | gDataDst.listContainer.slideToggle(); // animate options?
779 | h.removeClass(gDataDst.collapsed ? collapseIcon : expandIcon)
780 | .addClass(gDataDst.collapsed ? expandIcon : collapseIcon);
781 | };
782 | }else{
783 | if (groupIcon) {
784 | $(' ').addClass('collapse-handle '+groupIcon)
785 | .css('cursor','default')
786 | .prependTo(e.addClass('group-element-collapsable'));
787 | }
788 | }
789 | return $('
')
790 | // create an utility function to update group element count
791 | .data('fnUpdateCount', fnUpdateCount)
792 | .data('fnToggle', fnToggle || $.noop)
793 | .append(e)
794 | ;
795 | },
796 |
797 | _createGroupContainerElement: function(grpElement, optGroup, selected) {
798 | var that = this;
799 | var e = $('
');
800 | var _received_index;
801 |
802 | if (this._widget.options.sortable && selected) {
803 | e.sortable({
804 | tolerance: "pointer",
805 | appendTo: this._widget._elementWrapper,
806 | connectWith: this._widget._lists['available'].attr('id'),
807 | scope: this._widget.scope,
808 | helper: 'clone',
809 | receive: function(evt, ui) {
810 | var e = that._elements[_received_index = ui.item.data('element-index')];
811 |
812 | e.selected = true;
813 | e.optionElement.prop('selected', true);
814 | e.listElement.removeClass('ui-state-active');
815 | },
816 | stop: function(evt, ui) {
817 | var e;
818 | if (_received_index != undefined) {
819 | e = that._elements[_received_index];
820 | _received_index = undefined;
821 | ui.item.replaceWith(e.listElement.addClass('ui-state-highlight option-selected'));
822 | that._widget._updateHeaders();
823 | that._widget._triggerUIEvent(EVENT_CHANGE, { optionElements:[e.optionElement[0]], selected:true } );
824 | } else {
825 | e = that._elements[ui.item.data('element-index')];
826 | if (e && !e.selected) {
827 | that._bufferedMode(true);
828 | that._appendToList(e);
829 | that._bufferedMode(false);
830 | }
831 | }
832 | if (e) that._reorderSelected(e.optionGroup);
833 | },
834 | revert: true
835 | });
836 | }
837 |
838 | if (this._selectionMode) {
839 | $(e).on(this._selectionMode, 'div.option-element', function() {
840 | var eData = that._elements[$(this).data('element-index')];
841 | eData.listElement.removeClass('ui-state-hover');
842 | that.setSelected(eData, !selected);
843 | });
844 | }
845 |
846 | return e;
847 | },
848 |
849 | _createElement: function(optElement, optGroup) {
850 | var o = this._widget.options.optionRenderer
851 | ? this._widget.options.optionRenderer(optElement, optGroup)
852 | : $('
').text(optElement.text());
853 | var optIcon = optElement.attr("data-option-icon");
854 | var e = $('
').append(o).addClass('ui-state-default option-element')
855 | .attr("unselectable", "on") // disable text selection on this element (IE, Opera)
856 | .data('element-index', -1)
857 | .hover(
858 | function() {
859 | if (optElement.prop('selected')) $(this).removeClass('ui-state-highlight');
860 | $(this).addClass('ui-state-hover');
861 | },
862 | function() {
863 | $(this).removeClass('ui-state-hover');
864 | if (optElement.prop('selected')) $(this).addClass('ui-state-highlight');
865 | }
866 | );
867 | if (this._widget.options.selectionMode.indexOf('d&d') > -1) {
868 | var that = this;
869 | e.draggable({
870 | addClasses: false,
871 | cancel: (this._widget.options.sortable ? '.option-selected, ' : '') + '.ui-state-disabled',
872 | appendTo: this._widget._elementWrapper,
873 | scope: this._widget.scope,
874 | start: function(evt, ui) {
875 | $(this).addClass('ui-state-disabled ui-state-active');
876 | ui.helper.width($(this).width()).height($(this).height());
877 | },
878 | stop: function(evt, ui) {
879 | $(this).removeClass('ui-state-disabled ui-state-active');
880 | },
881 | helper: 'clone',
882 | revert: 'invalid',
883 | zIndex: 99999,
884 | disabled: optElement.prop('disabled')
885 | });
886 | if (optElement.prop('disabled')) {
887 | e.addClass('ui-state-disabled');
888 | }
889 | if (this._widget.options.sortable) {
890 | e.draggable('option', 'connectToSortable', this._groups.get(optGroup)['selected'].listContainer);
891 | }
892 | } else if (optElement.prop('disabled')) {
893 | e[(optElement.prop('disabled') ? "add" : "remove") + "Class"]('ui-state-disabled');
894 | }
895 | if (optIcon) {
896 | e.addClass('grouped-option').prepend($(' ').addClass('ui-icon ' + optIcon));
897 | }
898 | return e;
899 | },
900 |
901 | _isOptionCollapsed: function(eData) {
902 | return this._groups.get(eData.optionGroup)[eData.selected?'selected':'available'].collapsed;
903 | },
904 |
905 | _updateGroupElements: function(gData) {
906 | if (gData) {
907 | gData['selected'].count = 0;
908 | gData['available'].count = 0;
909 | for (var i=gData.startIndex, len=gData.startIndex+gData.count; i= gData.startIndex) &&
938 | (this._elements[insertIndex].selected != eData.selected)) {
939 | insertIndex--;
940 | }
941 |
942 | if (insertIndex < gData.startIndex) {
943 | gDataDst.listContainer.prepend(eData.listElement);
944 | } else {
945 | var prev = this._elements[insertIndex].listElement;
946 | // FIX : if previous element is animated, get it's animated parent as reference
947 | if (prev.parent().hasClass('ui-effects-wrapper')) {
948 | prev = prev.parent();
949 | }
950 | eData.listElement.insertAfter(prev);
951 | }
952 | eData.listElement[(eData.selected?'add':'remove')+'Class']('ui-state-highlight option-selected');
953 |
954 | if ((eData.selected || !eData.filtered) && !this._isOptionCollapsed(eData) && this._moveEffect && this._moveEffect.fn) {
955 | eData.listElement.hide().show(this._moveEffect.fn, this._moveEffect.options, this._moveEffect.speed);
956 | } else if (eData.filtered) {
957 | eData.listElement.hide();
958 | }
959 | },
960 |
961 | _reorderSelected: function(optGroup) {
962 | var e = this._elements;
963 | var g = this._groups.get(optGroup);
964 | var container = g.groupElement ? g.groupElement : this._widget.element;
965 | var prevElement;
966 | $('.option-element', g['selected'].listContainer).each(function() {
967 | var currElement = e[$(this).data('element-index')].optionElement;
968 | if (!prevElement) {
969 | container.prepend(currElement);
970 | } else {
971 | currElement.insertAfter(prevElement);
972 | }
973 | prevElement = currElement;
974 | });
975 | this._widget._triggerUIEvent(EVENT_REORDERED, { selectElement:container.context } );
976 | },
977 |
978 | _bufferedMode: function(enabled) {
979 | if (enabled) {
980 | this._oldMoveEffect = this._moveEffect; this._moveEffect = null;
981 |
982 | // backup lists' scroll position before going into buffered mode
983 | this._widget._lists['selected'].data('scrollTop', this._widget._lists['selected'].scrollTop());
984 | this._widget._lists['available'].data('scrollTop', this._widget._lists['available'].scrollTop());
985 |
986 | this._listContainers['selected'].detach();
987 | this._listContainers['available'].detach();
988 | } else {
989 | // restore scroll position (if available)
990 | this._widget._lists['selected'].append(this._listContainers['selected'])
991 | .scrollTop( this._widget._lists['selected'].data('scrollTop') || 0 );
992 | this._widget._lists['available'].append(this._listContainers['available'])
993 | .scrollTop( this._widget._lists['available'].data('scrollTop') || 0 );
994 |
995 | this._moveEffect = this._oldMoveEffect;
996 |
997 | delete this._oldMoveEffect;
998 | }
999 |
1000 | },
1001 |
1002 | reset: function(destroy) {
1003 | this._groups.clear();
1004 | this._listContainers['selected'].empty();
1005 | this._listContainers['available'].empty();
1006 |
1007 | if (destroy) {
1008 | for (var i=0, e=this._elements, len=e.length; i -1)) {
1033 | this._elements.splice(i--, 1)[0].listElement.remove();
1034 | }
1035 | }
1036 | for (var i=0, len=_groupsRemoved.length; i').addClass('multiselect-element-wrapper').data('option-group', g);
1123 | var wrapper_available = $('
').addClass('multiselect-element-wrapper').data('option-group', g);
1124 | wrapper_selected.append(v.selected.listElement.hide());
1125 | if (g != DEF_OPTGROUP || (g == DEF_OPTGROUP && showDefGroupName)) {
1126 | wrapper_available.append(v['available'].listElement.show());
1127 | }
1128 | wrapper_selected.append(v['selected'].listContainer);
1129 | wrapper_available.append(v['available'].listContainer);
1130 |
1131 | l['selected'].append(wrapper_selected);
1132 | l['available'].append(wrapper_available);
1133 | }
1134 | v.count = 0;
1135 | }, this._listContainers, this._widget.options.showDefaultGroupHeader);
1136 |
1137 | for (var i=0, eData, gData, len=this._elements.length; i= i) {
1143 | gData.startIndex = i;
1144 | gData.count = 1;
1145 | } else {
1146 | gData.count++;
1147 | }
1148 |
1149 | // save element index for back ref
1150 | eData.listElement.data('element-index', eData.index = i);
1151 |
1152 | if (eData.optionElement.data('element-index') == undefined || eData.selected != eData.optionElement.prop('selected')) {
1153 | eData.selected = eData.optionElement.prop('selected');
1154 | eData.optionElement.data('element-index', i); // also save for back ref here
1155 |
1156 | this._appendToList(eData);
1157 | }
1158 | }
1159 |
1160 | this._updateGroupElements();
1161 | this._widget._updateHeaders();
1162 | this._groups.each(function(g,v,t) { t._reorderSelected(g); }, this);
1163 |
1164 | this._bufferedMode(false);
1165 |
1166 | },
1167 |
1168 | filter: function(term, silent) {
1169 |
1170 | if (term && !silent) {
1171 | var ui = { term:term };
1172 | if (this._widget._triggerUIEvent(EVENT_SEARCH, ui )) {
1173 | term = ui.term; // update term
1174 | } else {
1175 | return;
1176 | }
1177 | }
1178 |
1179 | this._bufferedMode(true);
1180 |
1181 | var filterSelected = this._widget.options.filterSelected;
1182 | var filterFn = this._widget.options.searchFilter || function(term, opt) {
1183 | return opt.innerHTML.toLocaleLowerCase().indexOf(term) > -1;
1184 | };
1185 | term = (this._widget.options.searchPreFilter || function(term) {
1186 | return term ? (term+"").toLocaleLowerCase() : false;
1187 | })(term);
1188 |
1189 | for (var i=0, eData, len=this._elements.length, filtered; i 1 && i18n[p.key+'_plural']) {
1287 | t = i18n[p.key+'_plural'];
1288 | } else if (plural === 0 && i18n[p.key+'_nil']) {
1289 | t = i18n[p.key+'_nil'];
1290 | } else {
1291 | t = i18n[p.key] || '';
1292 | }
1293 |
1294 | return t.replace(/\{([^\}]+)\}/g, function(m, n) { return data[n]; });
1295 | };
1296 |
1297 | /**
1298 | * Default translation
1299 | */
1300 | $.uix.multiselect.i18n = {
1301 | '': {
1302 | itemsSelected_nil: 'No options selected', // 0
1303 | itemsSelected: '{count} selected option', // 0, 1
1304 | itemsSelected_plural: '{count} options selected', // n
1305 | //itemsSelected_plural_two: ... // 2
1306 | //itemsSelected_plural_few: ... // 3, 4
1307 | itemsAvailable_nil: 'No items available',
1308 | itemsAvailable: '{count} options available',
1309 | itemsAvailable_plural: '{count} options available',
1310 | //itemsAvailable_plural_two: ...
1311 | //itemsAvailable_plural_few: ...
1312 | itemsFiltered_nil: 'No options found',
1313 | itemsFiltered: '{count} option found',
1314 | itemsFiltered_plural: '{count} options found',
1315 | //itemsFiltered_plural_two: ...
1316 | //itemsFiltered_plural_few: ...
1317 | selectAll: 'Select All',
1318 | deselectAll: 'Deselect All',
1319 | search: 'Search Options',
1320 | collapseGroup: 'Collapse Group',
1321 | expandGroup: 'Expand Group',
1322 | selectAllGroup: 'Select All Group',
1323 | deselectAllGroup: 'Deselect All Group'
1324 | }
1325 | };
1326 |
1327 | })(jQuery, window);
1328 |
--------------------------------------------------------------------------------
/js/jquery.uix.multiselect.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UIx Multiselect 2.0
3 | *
4 | * Authors:
5 | * Yanick Rochon (yanick.rochon[at]gmail[dot]com)
6 | *
7 | * Licensed under the MIT (MIT-LICENSE.txt) license.
8 | *
9 | * http://mind2soft.com/labs/jquery/multiselect/
10 | *
11 | *
12 | * Depends:
13 | * jQuery UI 1.8+
14 | *
15 | */
16 |
17 | (function(d,i,g){var k=0;var l="";var b="group-";var h="multiselectChange";var f="multiselectSearch";d.widget("uix.multiselect",{options:{availableListPosition:"right",collapsableGroups:true,defaultGroupName:"",filterSelected:false,locale:"auto",moveEffect:null,moveEffectOptions:{},moveEffectSpeed:null,optionRenderer:false,optionGroupRenderer:false,searchField:"toggle",searchFilter:null,searchHeader:"available",selectionMode:"click,d&d",showDefaultGroupHeader:false,showEmptyGroups:false,splitRatio:0.55,sortable:false,sortMethod:null},_create:function(){var x=this;
18 | var u,s,y,w;var t,v;this.scope="multiselect"+(k++);this.optionGroupIndex=1;this._setLocale(this.options.locale);this.element.addClass("uix-multiselect-original");this._elementWrapper=d("
").addClass("uix-multiselect ui-widget").css({width:this.element.outerWidth(),height:this.element.outerHeight()}).append(d("
").addClass("multiselect-selected-list").append(d("
").addClass("ui-widget-header").append(v=d(" ",{type:"button"}).addClass("uix-control-right").attr("data-localekey","deselectAll").attr("title",this._t("deselectAll")).button({icons:{primary:"ui-icon-arrowthickstop-1-e"},text:false}).click(function(z){z.preventDefault();
19 | z.stopPropagation();x.optionCache.setSelectedAll(false);return false})).append(u=d("
").addClass("header-text"))).append(s=d("
").addClass("uix-list-container ui-widget-content")))["right,top".indexOf(this.options.availableListPosition)>=0?"prepend":"append"](d("
").addClass("multiselect-available-list").append(d("
").addClass("ui-widget-header").append(t=d(" ",{type:"button"}).addClass("uix-control-right").attr("data-localekey","selectAll").attr("title",this._t("selectAll")).button({icons:{primary:"ui-icon-arrowthickstop-1-w"},text:false}).click(function(z){z.preventDefault();
20 | z.stopPropagation();x.optionCache.setSelectedAll(true);return false})).append(y=d("
").addClass("header-text"))).append(w=d("
").addClass("uix-list-container ui-widget-content"))).insertAfter(this.element);this._buttons={selectAll:t,deselectAll:v};
21 | this._headers={selected:u,available:y};this._lists={selected:s.attr("id",this.scope+"_selListContent"),available:w.attr("id",this.scope+"_avListContent")};this.optionCache=new a(this);this._searchDelayed=new o(this,{delay:500});this._initSearchable();this._applyListDroppable();
22 | this.refresh()},refresh:function(s){this._resize();n(function(){this.optionCache.cleanup();var y,w=this.element[0].childNodes;for(var x=0,u=w.length;x').addClass("uix-search ui-widget-content ui-corner-"+(u?"left":"all"))[u?"hide":"show"]().insertBefore(this._headers[t]).focus(function(){d(this).select()
30 | }).on("keydown keypress",function(v){if(v.keyCode==13){v.preventDefault();v.stopPropagation();return false}}).keyup(d.proxy(this._searchDelayed.request,this._searchDelayed))}},_applyListDroppable:function(){if(this.options.selectionMode.indexOf("d&d")==-1){return
31 | }var s=this.optionCache;var t=this.scope;var w=function(x){return s._elements[x.data("element-index")]};var v=function(y,x){y.droppable({accept:function(z){var A=w(z);return A&&(A.selected!=x)},activeClass:"ui-state-highlight",scope:t,drop:function(z,A){A.draggable.removeClass("ui-state-disabled");
32 | A.helper.remove();s.setSelected(w(A.draggable),x)}})};v(this._lists.selected,true);v(this._lists.available,false);if(this.options.sortable){var u=this;this._lists.selected.sortable({appendTo:"parent",axis:"y",containment:d(".multiselect-selected-list",this._elementWrapper),items:".multiselect-element-wrapper",handle:".group-element",revert:true,stop:d.proxy(function(x,y){var z;
33 | d(".multiselect-element-wrapper",u._lists.selected).each(function(){var A=u.optionCache._groups.get(d(this).data("option-group"));if(!z){u.element.append(A.groupElement)}else{A.groupElement.insertAfter(z.groupElement)}z=A})},this)})}},_search:function(t,s){if(this._searchField.is(":visible")){if(typeof t==="string"){this._searchField.val(t)
34 | }else{t=this._searchField.val()}}this.optionCache.filter(t,s)},_setLocale:function(s){if(s=="auto"){s=navigator.userLanguage||navigator.language||navigator.browserLanguage||navigator.systemLanguage||""}if(!d.uix.multiselect.i18n[s]){s=""}this.options.locale=s
35 | },_t:function(t,s,u){return r({locale:this.options.locale,key:t,plural:s,data:u})},_updateControls:function(){var s=this;d(".uix-control-left,.uix-control-right",this._elementWrapper).each(function(){d(this).attr("title",s._t(d(this).attr("data-localekey")))
36 | })},_updateHeaders:function(){var s,u=this.optionCache.getSelectionInfo();this._headers.selected.text(s=this._t("itemsSelected",u.selected.total,{count:u.selected.total})).parent().attr("title",this.options.filterSelected?this._t("itemsSelected",u.selected.count,{count:u.selected.count})+", "+this._t("itemsFiltered",u.selected.filtered,{count:u.selected.filtered}):s);
37 | this._headers.available.text(this._t("itemsAvailable",u.available.total,{count:u.available.total})).parent().attr("title",this._t("itemsAvailable",u.available.count,{count:u.available.count})+", "+this._t("itemsFiltered",u.available.filtered,{count:u.available.filtered}))
38 | },_resize:function(){var B=this.options.availableListPosition.toLowerCase();var w=("left,right".indexOf(B)>=0)?"Width":"Height";var v=("left,right".indexOf(B)>=0)?"Height":"Width";var F=this.element["outer"+w]()*this.options.splitRatio;var C=this.element["outer"+w]()-F;
39 | var s=(v==="Width")?F:this.element.outerHeight();var D=(v==="Width")?C:this.element.outerHeight();var E=("left,right".indexOf(B)>=0)?"left":"top";var u=("left,top".indexOf(B)>=0);var t=("toggle"===this.options.searchField);var x="ui-corner-tl ui-corner-tr ui-corner-bl ui-corner-br ui-corner-top";
40 | var A=(v==="Width")?(u?"":"ui-corner-top"):(u?"ui-corner-tr":"ui-corner-tl");var z=(v==="Width")?(u?"ui-corner-top":""):(u?"ui-corner-tl":"ui-corner-tr");this._elementWrapper.find(".multiselect-available-list")[w.toLowerCase()](C).css(E,u?0:F)[v.toLowerCase()](this.element["outer"+v]()+1);
41 | this._elementWrapper.find(".multiselect-selected-list")[w.toLowerCase()](F).css(E,u?C:0)[v.toLowerCase()](this.element["outer"+v]()+1);this._buttons.selectAll.button("option","icons",{primary:q(B,"ui-icon-arrowthickstop-1-",false)});this._buttons.deselectAll.button("option","icons",{primary:q(B,"ui-icon-arrowthickstop-1-",true)});
42 | this._headers.available.parent().removeClass(x).addClass(z);this._headers.selected.parent().removeClass(x).addClass(A);if(!t){var y=Math.max(this._headers.selected.parent().height(),this._headers.available.parent().height());this._headers.available.parent().height(y);
43 | this._headers.selected.parent().height(y)}if(this._searchField){this._searchField.width((w==="Width"?C:this.element.width())-(t?52:26))}this._lists.available.height(D-this._headers.available.parent().outerHeight()-2);this._lists.selected.height(s-this._headers.selected.parent().outerHeight()-2)
44 | },_triggerUIEvent:function(t,u){var s;if(typeof t==="string"){s=t;t=d.Event(t)}else{s=t.type}this.element.trigger(t,u);return !t.isDefaultPrevented()},_setOption:function(s,t){switch(s){}if(typeof(this._superApply)=="function"){this._superApply(arguments)}else{d.Widget.prototype._setOption.apply(this,arguments)
45 | }}});var m={standard:function(t,s){if(t>s){return 1}if(tG){return 1}}}for(var D=0,B=Math.max(u.length,E.length);Ds){return 1}}return 0}};var c=["n","e","s","w"];var j=["bottom","left","top","right"];var q=function(u,t,s){return t+c[(d.inArray(u.toLowerCase(),j)+(s?2:0))%4]};var n=function(v,u,s){var t=Array.prototype.slice.call(arguments,3);
49 | return setTimeout(function(){v.apply(s||i,t)},u)};var o=function(t,s){this._widget=t;this._options=s;this._lastSearchValue=null};o.prototype={request:function(){if(this._widget._searchField.val()==this._lastSearchValue){return}this.cancelLastRequest();this._timeout=n(function(){this._timeout=null;
50 | this._lastSearchValue=this._widget._searchField.val();this._widget._search()},this._options.delay,this)},cancelLastRequest:function(){if(this._timeout){clearTimeout(this._timeout)}}};var p=function(u){var v=[];var t={};var s=u;this.setComparator=function(w){s=w;
51 | return this};this.clear=function(){v=[];t={};return this};this.containsKey=function(w){return !!t[w]};this.get=function(w){return t[w]};this.put=function(w,x){if(!t[w]){if(s){v.splice((function(){var z=0,C=v.length;var B=-1,D=0;while(z0){C=B}else{return B}}}return z})(),0,w)}else{v.push(w)}}t[w]=x;return this};this.remove=function(w){delete t[w];return v.splice(v.indexOf(w),1)
53 | };this.each=function(z){var x=Array.prototype.slice.call(arguments,1);x.splice(0,0,null,null);for(var y=0,w=v.length;y").appendTo(this._widget._lists.selected),available:d("
").appendTo(this._widget._lists.available)};
54 | this._elements=[];this._groups=new p();this._moveEffect={fn:s.options.moveEffect,options:s.options.moveEffectOptions,speed:s.options.moveEffectSpeed};this._selectionMode=this._widget.options.selectionMode.indexOf("dblclick")>-1?"dblclick":this._widget.options.selectionMode.indexOf("click")>-1?"click":false;
55 | this.reset()};a.Options={batchCount:200,batchDelay:50};a.prototype={_createGroupElement:function(y,G,v){var A=this;var E;var u=function(){if(!E){E=A._groups.get(G)}return E};var z=function(){return y?y.attr("label"):A._widget.options.defaultGroupName};var t=d(" ").addClass("label").text(z()+" (0)").attr("title",z()+" (0)");
56 | var x=function(){var I=u()[v?"selected":"available"];I.listElement[(!v&&(I.count||A._widget.options.showEmptyGroups))||(I.count&&((E.optionGroup!=l)||A._widget.options.showDefaultGroupHeader))?"show":"hide"]();var H=z()+" ("+I.count+")";t.text(H).attr("title",H)
57 | };var C=d("
").addClass("ui-widget-header ui-priority-secondary group-element").append(d(" ",{type:"button"}).addClass("uix-control-right").attr("data-localekey",(v?"de":"")+"selectAllGroup").attr("title",this._widget._t((v?"de":"")+"selectAllGroup")).button({icons:{primary:q(this._widget.options.availableListPosition,"ui-icon-arrowstop-1-",v)},text:false}).click(function(M){M.preventDefault();
58 | M.stopPropagation();var L=u()[v?"selected":"available"];if(E.count>0){var I=[];A._bufferedMode(true);for(var J=E.startIndex,H=E.startIndex+E.count,K;J").addClass("ui-icon collapse-handle").attr("data-localekey","collapseGroup").attr("title",this._widget._t("collapseGroup")).addClass(F).mousedown(function(H){H.stopPropagation()}).click(function(H){H.preventDefault();H.stopPropagation();
61 | s(y);return false}).prependTo(C.addClass("group-element-collapsable"));s=function(M){var L=u()[v?"selected":"available"],J=(M)?M.attr("data-collapse-icon"):null,H=(M)?M.attr("data-expand-icon"):null,K=(J)?"ui-icon "+J:"ui-icon ui-icon-triangle-1-s",I=(H)?"ui-icon "+H:"ui-icon ui-icon-triangle-1-e";
62 | L.collapsed=!L.collapsed;L.listContainer.slideToggle();w.removeClass(L.collapsed?K:I).addClass(L.collapsed?I:K)}}else{if(B){d(" ").addClass("collapse-handle "+B).css("cursor","default").prependTo(C.addClass("group-element-collapsable"))}}return d("
").data("fnUpdateCount",x).data("fnToggle",s||d.noop).append(C)
63 | },_createGroupContainerElement:function(x,w,t){var u=this;var v=d("
");var s;if(this._widget.options.sortable&&t){v.sortable({tolerance:"pointer",appendTo:this._widget._elementWrapper,connectWith:this._widget._lists.available.attr("id"),scope:this._widget.scope,helper:"clone",receive:function(y,z){var A=u._elements[s=z.item.data("element-index")];
64 | A.selected=true;A.optionElement.prop("selected",true);A.listElement.removeClass("ui-state-active")},stop:function(y,z){var A;if(s){A=u._elements[s];s=g;z.item.replaceWith(A.listElement.addClass("ui-state-highlight option-selected"));u._widget._updateHeaders();
65 | u._widget._triggerUIEvent(h,{optionElements:[A.optionElement[0]],selected:true})}else{A=u._elements[z.item.data("element-index")];if(A&&!A.selected){u._bufferedMode(true);u._appendToList(A);u._bufferedMode(false)}}if(A){u._reorderSelected(A.optionGroup)}},revert:true})
66 | }if(this._selectionMode){d(v).on(this._selectionMode,"div.option-element",function(){var y=u._elements[d(this).data("element-index")];y.listElement.removeClass("ui-state-hover");u.setSelected(y,!t)})}return v},_createElement:function(t,x){var w=this._widget.options.optionRenderer?this._widget.options.optionRenderer(t,x):d("
").text(t.text());
67 | var s=t.attr("data-option-icon");var v=d("
").append(w).addClass("ui-state-default option-element").attr("unselectable","on").data("element-index",-1).hover(function(){if(t.prop("selected")){d(this).removeClass("ui-state-highlight")}d(this).addClass("ui-state-hover")
68 | },function(){d(this).removeClass("ui-state-hover");if(t.prop("selected")){d(this).addClass("ui-state-highlight")}});if(this._widget.options.selectionMode.indexOf("d&d")>-1){var u=this;v.draggable({addClasses:false,cancel:(this._widget.options.sortable?".option-selected, ":"")+".ui-state-disabled",appendTo:this._widget._elementWrapper,scope:this._widget.scope,start:function(y,z){d(this).addClass("ui-state-disabled ui-state-active");
69 | z.helper.width(d(this).width()).height(d(this).height())},stop:function(y,z){d(this).removeClass("ui-state-disabled ui-state-active")},helper:"clone",revert:"invalid",zIndex:99999,disabled:t.prop("disabled")});if(t.prop("disabled")){v.addClass("ui-state-disabled")
70 | }if(this._widget.options.sortable){v.draggable("option","connectToSortable",this._groups.get(x)["selected"].listContainer)}}else{if(t.prop("disabled")){v[(t.prop("disabled")?"add":"remove")+"Class"]("ui-state-disabled")}}if(s){v.addClass("grouped-option").prepend(d(" ").addClass("ui-icon "+s))
71 | }return v},_isOptionCollapsed:function(s){return this._groups.get(s.optionGroup)[s.selected?"selected":"available"].collapsed},_updateGroupElements:function(u){if(u){u.selected.count=0;u.available.count=0;for(var t=u.startIndex,s=u.startIndex+u.count;t=v.startIndex)&&(this._elements[s].selected!=t.selected)){s--
74 | }if(s-1)){this._elements.splice(t--,1)[0].listElement.remove()}}for(var t=0,s=v.length;t").addClass("multiselect-element-wrapper").data("option-group",C);
86 | var D=d("
").addClass("multiselect-element-wrapper").data("option-group",C);B.append(A.selected.listElement.hide());if(C!=l||(C==l&&y)){D.append(A.available.listElement.show())}B.append(A.selected.listContainer);D.append(A.available.listContainer);
87 | z.selected.append(B);z.available.append(D)}A.count=0},this._listContainers,this._widget.options.showDefaultGroupHeader);for(var u=0,w,x,s=this._elements.length;u=u){x.startIndex=u;
88 | x.count=1}else{x.count++}w.listElement.data("element-index",w.index=u);if(w.optionElement.data("element-index")==g||w.selected!=w.optionElement.prop("selected")){w.selected=w.optionElement.prop("selected");w.optionElement.data("element-index",u);this._appendToList(w)
89 | }}this._updateGroupElements();this._widget._updateHeaders();this._groups.each(function(A,y,z){z._reorderSelected(A)},this);this._bufferedMode(false)},filter:function(t,x){if(t&&!x){var y={term:t};if(this._widget._triggerUIEvent(f,y)){t=y.term}else{return}}this._bufferedMode(true);
90 | var s=this._widget.options.filterSelected;var z=this._widget.options.searchFilter||function(C,B){return B.innerHTML.toLowerCase().indexOf(C)>-1};t=(this._widget.options.searchPreFilter||function(B){return B?(B+"").toLowerCase():false})(t);for(var u=0,A,v=this._elements.length,w;
91 | u1&&x[y.key+"_plural"]){v=x[y.key+"_plural"]}else{if(u===0&&x[y.key+"_nil"]){v=x[y.key+"_nil"]}else{v=x[y.key]||""}}}}return v.replace(/\{([^\}]+)\}/g,function(t,z){return w[z]})}d.uix.multiselect.i18n={"":{itemsSelected_nil:"no selected option",itemsSelected:"{count} selected option",itemsSelected_plural:"{count} selected options",itemsAvailable_nil:"no item available",itemsAvailable:"{count} available option",itemsAvailable_plural:"{count} available options",itemsFiltered_nil:"no option filtered",itemsFiltered:"{count} option filtered",itemsFiltered_plural:"{count} options filtered",selectAll:"Select All",deselectAll:"Deselect All",search:"Search Options",collapseGroup:"Collapse Group",expandGroup:"Expand Group",selectAllGroup:"Select All Group",deselectAllGroup:"Deselect All Group"}}
98 | })(jQuery,window);
99 |
--------------------------------------------------------------------------------
/js/locales/jquery.uix.multiselect_de.js:
--------------------------------------------------------------------------------
1 | /**
2 | * jQuery UI Multiselect 2.0
3 | *
4 | * Authors:
5 | * Yanick Rochon (yanick.rochon[at]gmail[dot]com)
6 | *
7 | * Dual licensed under the MIT (MIT-LICENSE.txt)
8 | * and GPL (GPL-LICENSE.txt) licenses.
9 | *
10 | * http://mind2soft.com/labs/jquery/multiselect/
11 | *
12 | *
13 | * Localization : DE
14 | */
15 |
16 | (function($) {
17 |
18 | $.uix.multiselect.i18n['de'] = {
19 | itemsSelected_nil: 'keine Option ausgewählt', // 0
20 | itemsSelected: 'eine Option ausgewählt', // 0, 1
21 | itemsSelected_plural: '{count} Optionen ausgewählt', // n
22 | itemsSelected_plural_two: '2 Optionen ausgewählt', // 2
23 | itemsSelected_plural_few: '{count} Optionen ausgewählt', // 3, 4
24 | itemsAvailable_nil: 'keine Option verfügbar',
25 | itemsAvailable: 'eine Option verfügbar',
26 | itemsAvailable_plural: '{count} Optionen verfügbar',
27 | itemsAvailable_plural_two: '2 Optionen verfügbar',
28 | itemsAvailable_plural_few: '{count} Optionen verfügbar',
29 | itemsFiltered_nil: 'keine Option gefiltert',
30 | itemsFiltered: 'eine Option gefiltert',
31 | itemsFiltered_plural: '{count} Optionen gefiltert',
32 | itemsFiltered_plural_two: '2 Optionen gefiltert',
33 | itemsFiltered_plural_few: '{count} Optionen gefiltert',
34 | selectAll: 'Alle Optionen auswählen',
35 | deselectAll: 'Komplette Auswahl aufheben',
36 | search: 'Suchen',
37 | collapseGroup: 'Gruppe ausblenden',
38 | expandGroup: 'Gruppe anzeigen',
39 | selectAllGroup: 'Gruppe auswählen',
40 | deselectAllGroup: 'Gruppenauswahl aufheben'
41 | };
42 |
43 | // link locales
44 | $.uix.multiselect.i18n['de_DE'] = $.uix.multiselect.i18n['de'];
45 | $.uix.multiselect.i18n['de_CH'] = $.uix.multiselect.i18n['de'];
46 | $.uix.multiselect.i18n['de_AT'] = $.uix.multiselect.i18n['de'];
47 | // ...
48 |
49 | })(jQuery);
50 |
--------------------------------------------------------------------------------
/js/locales/jquery.uix.multiselect_en.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UI Multiselect 2.0
3 | *
4 | * Authors:
5 | * Yanick Rochon (yanick.rochon[at]gmail[dot]com)
6 | *
7 | * Dual licensed under the MIT (MIT-LICENSE.txt)
8 | * and GPL (GPL-LICENSE.txt) licenses.
9 | *
10 | * http://mind2soft.com/labs/jquery/multiselect/
11 | *
12 | *
13 | * Localization : EN
14 | *
15 | */
16 |
17 | (function($) {
18 |
19 | $.uix.multiselect.i18n['en'] = {
20 | itemsSelected_nil: 'No options selected', // 0
21 | itemsSelected: '{count} selected option', // 0, 1
22 | itemsSelected_plural: '{count} options selected', // n
23 | //itemsSelected_plural_two: ... // 2
24 | //itemsSelected_plural_few: ... // 3, 4
25 | itemsAvailable_nil: 'No items available',
26 | itemsAvailable: '{count} options available',
27 | itemsAvailable_plural: '{count} options available',
28 | //itemsAvailable_plural_two: ...
29 | //itemsAvailable_plural_few: ...
30 | itemsFiltered_nil: 'No options found',
31 | itemsFiltered: '{count} option found',
32 | itemsFiltered_plural: '{count} options found',
33 | //itemsFiltered_plural_two: ...
34 | //itemsFiltered_plural_few: ...
35 | selectAll: 'Select All',
36 | deselectAll: 'Deselect All',
37 | search: 'Search Options',
38 | collapseGroup: 'Collapse Group',
39 | expandGroup: 'Expand Group',
40 | selectAllGroup: 'Select All Group',
41 | deselectAllGroup: 'Deselect All Group'
42 | };
43 |
44 | // link locales
45 | $.uix.multiselect.i18n['en_CA'] = $.uix.multiselect.i18n['en'];
46 | $.uix.multiselect.i18n['en_GB'] = $.uix.multiselect.i18n['en'];
47 | $.uix.multiselect.i18n['en_US'] = $.uix.multiselect.i18n['en'];
48 | // ...
49 |
50 | })(jQuery);
51 |
--------------------------------------------------------------------------------
/js/locales/jquery.uix.multiselect_es.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UI Multiselect 2.0
3 | *
4 | * Authors:
5 | * Yanick Rochon (yanick.rochon[at]gmail[dot]com)
6 | *
7 | * Dual licensed under the MIT (MIT-LICENSE.txt)
8 | * and GPL (GPL-LICENSE.txt) licenses.
9 | *
10 | * http://mind2soft.com/labs/jquery/multiselect/
11 | *
12 | *
13 | * Localization : ES
14 | *
15 | */
16 |
17 | (function($) {
18 |
19 | $.uix.multiselect.i18n['es'] = {
20 | itemsSelected_nil: 'no hay opciones seleccionadas', // 0
21 | itemsSelected: '{count} opción seleccionada', // 0, 1
22 | itemsSelected_plural: '{count} opciones seleccionadas', // n
23 | //itemsSelected_plural_two: ... // 2
24 | //itemsSelected_plural_few: ... // 3, 4
25 | itemsAvailable_nil: 'no hay opciones disponibles',
26 | itemsAvailable: '{count} opción disponible',
27 | itemsAvailable_plural: '{count} opciones disponibles',
28 | //itemsAvailable_plural_two: ...
29 | //itemsAvailable_plural_few: ...
30 | itemsFiltered_nil: 'ninguna opción filtrada',
31 | itemsFiltered: '{count} opción filtrada',
32 | itemsFiltered_plural: '{count} opciones filtradas',
33 | //itemsFiltered_plural_two: ...
34 | //itemsFiltered_plural_few: ...
35 | selectAll: 'Seleccionar Todo',
36 | deselectAll: 'Deseleccionar Todo',
37 | search: 'Buscar opciones',
38 | collapseGroup: 'Plegar Grupo',
39 | expandGroup: 'Expandir Grupo',
40 | selectAllGroup: 'Seleccionar Grupo Entero',
41 | deselectAllGroup: 'Deseleccionar Grupo Entero'
42 | };
43 |
44 | // link locales
45 | $.uix.multiselect.i18n['es_ES'] = $.uix.multiselect.i18n['es'];
46 | $.uix.multiselect.i18n['es_AR'] = $.uix.multiselect.i18n['es'];
47 | // ...
48 |
49 | })(jQuery);
50 |
--------------------------------------------------------------------------------
/js/locales/jquery.uix.multiselect_et.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UI Multiselect 2.0
3 | *
4 | * Authors:
5 | * Yanick Rochon (yanick.rochon[at]gmail[dot]com)
6 | * karmux (https://github.com/karmux)
7 | *
8 | * Dual licensed under the MIT (MIT-LICENSE.txt)
9 | * and GPL (GPL-LICENSE.txt) licenses.
10 | *
11 | * http://mind2soft.com/labs/jquery/multiselect/
12 | *
13 | *
14 | * Localization : ET
15 | *
16 | */
17 |
18 | (function($) {
19 |
20 | $.uix.multiselect.i18n['et'] = {
21 | itemsSelected_nil: 'midagi pole valitud', // 0
22 | itemsSelected: '{count} valitud', // 0, 1
23 | itemsSelected_plural: '{count} valitud', // n
24 | //itemsSelected_plural_two: ... // 2
25 | //itemsSelected_plural_few: ... // 3, 4
26 | itemsAvailable_nil: 'valikuid pole saadaval',
27 | itemsAvailable: '{count} valik saadaval',
28 | itemsAvailable_plural: '{count} valikut saadaval',
29 | //itemsAvailable_plural_two: ...
30 | //itemsAvailable_plural_few: ...
31 | itemsFiltered_nil: 'valikuid pole filtreeritud',
32 | itemsFiltered: '{count} valik filtreeritud',
33 | itemsFiltered_plural: '{count} valikut filtreeritud',
34 | //itemsFiltered_plural_two: ...
35 | //itemsFiltered_plural_few: ...
36 | selectAll: 'Vali kõik',
37 | deselectAll: 'Tühista kõik',
38 | search: 'Otsi',
39 | collapseGroup: 'Kahanda grupp',
40 | expandGroup: 'Laienda grupp',
41 | selectAllGroup: 'Vali kogu grupp',
42 | deselectAllGroup: 'Tühista kogu grupp'
43 | };
44 |
45 | // link locales
46 | $.uix.multiselect.i18n['et_EE'] = $.uix.multiselect.i18n['et'];
47 | // ...
48 |
49 | })(jQuery);
50 |
--------------------------------------------------------------------------------
/js/locales/jquery.uix.multiselect_fr.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UI Multiselect 2.0
3 | *
4 | * Authors:
5 | * Yanick Rochon (yanick.rochon[at]gmail[dot]com)
6 | *
7 | * Dual licensed under the MIT (MIT-LICENSE.txt)
8 | * and GPL (GPL-LICENSE.txt) licenses.
9 | *
10 | * http://mind2soft.com/labs/jquery/multiselect/
11 | *
12 | *
13 | * Localization : FR
14 | *
15 | */
16 |
17 | (function($) {
18 |
19 | $.uix.multiselect.i18n['fr'] = {
20 | itemsSelected_nil: 'aucune option sélectionnée', // 0
21 | itemsSelected: '{count} option sélectionnée', // 0, 1
22 | itemsSelected_plural: '{count} options sélectionnées', // n
23 | //itemsSelected_plural_two: ... // 2
24 | //itemsSelected_plural_few: ... // 3, 4
25 | itemsAvailable_nil: 'aucune option disponible',
26 | itemsAvailable: '{count} option disponible',
27 | itemsAvailable_plural: '{count} options disponibles',
28 | //itemsAvailable_plural_two: ...
29 | //itemsAvailable_plural_few: ...
30 | itemsFiltered_nil: 'aucune option masquée',
31 | itemsFiltered: '{count} option masquée',
32 | itemsFiltered_plural: '{count} options masquées',
33 | //itemsFiltered_plural_two: ...
34 | //itemsFiltered_plural_few: ...
35 | selectAll: 'Sélectionner tout',
36 | deselectAll: 'Désélectionner tout',
37 | search: 'Rechercher les options',
38 | collapseGroup: 'Masquer le groupe',
39 | expandGroup: 'Afficher le groupe',
40 | selectAllGroup: 'Sélectionner tout le groupe',
41 | deselectAllGroup: 'Déselectionner tout le groupe'
42 | };
43 |
44 | // link locales
45 | $.uix.multiselect.i18n['fr_CA'] = $.uix.multiselect.i18n['fr'];
46 | $.uix.multiselect.i18n['fr_FR'] = $.uix.multiselect.i18n['fr'];
47 | // ...
48 |
49 | })(jQuery);
50 |
--------------------------------------------------------------------------------
/js/locales/jquery.uix.multiselect_it.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UI Multiselect 2.0
3 | *
4 | * Authors:
5 | * Yanick Rochon (yanick.rochon[at]gmail[dot]com)
6 | * Manuel Dalla Lana (endelwar[at]aregar[dot]it)
7 | *
8 | * Dual licensed under the MIT (MIT-LICENSE.txt)
9 | * and GPL (GPL-LICENSE.txt) licenses.
10 | *
11 | * http://mind2soft.com/labs/jquery/multiselect/
12 | *
13 | *
14 | * Localization : IT
15 | *
16 | */
17 |
18 | (function($) {
19 |
20 | $.uix.multiselect.i18n['it'] = {
21 | itemsSelected_nil: 'nessuna opzione selezionata', // 0
22 | itemsSelected: '{count} opzione selezionata', // 0, 1
23 | itemsSelected_plural: '{count} opzioni selezionate', // n
24 | //itemsSelected_plural_two: ... // 2
25 | //itemsSelected_plural_few: ... // 3, 4
26 | itemsAvailable_nil: 'nessuna opzione disponibile',
27 | itemsAvailable: '{count} opzione disponibile',
28 | itemsAvailable_plural: '{count} opzioni disponibili',
29 | //itemsAvailable_plural_two: ...
30 | //itemsAvailable_plural_few: ...
31 | itemsFiltered_nil: 'nessuna opzione filtrata',
32 | itemsFiltered: '{count} opzione filtrata',
33 | itemsFiltered_plural: '{count} opzioni filtrate',
34 | //itemsFiltered_plural_two: ...
35 | //itemsFiltered_plural_few: ...
36 | selectAll: 'Seleziona Tutto',
37 | deselectAll: 'Deseleziona Tutto',
38 | search: 'Cerca Opzioni',
39 | collapseGroup: 'Collassa Gruppo',
40 | expandGroup: 'Espandi Gruppo',
41 | selectAllGroup: 'Seleziona Tutto il Gruppo',
42 | deselectAllGroup: 'Deseleziona Tutto il Gruppo'
43 | };
44 |
45 | // link locales
46 | $.uix.multiselect.i18n['it_IT'] = $.uix.multiselect.i18n['it'];
47 | $.uix.multiselect.i18n['it_CH'] = $.uix.multiselect.i18n['it'];
48 | // ...
49 |
50 | })(jQuery);
51 |
--------------------------------------------------------------------------------
/js/locales/jquery.uix.multiselect_nl.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UI Multiselect 2.0
3 | *
4 | * Authors:
5 | * Yanick Rochon (yanick.rochon[at]gmail[dot]com)
6 | *
7 | * Dual licensed under the MIT (MIT-LICENSE.txt)
8 | * and GPL (GPL-LICENSE.txt) licenses.
9 | *
10 | * http://mind2soft.com/labs/jquery/multiselect/
11 | *
12 | *
13 | * Localization : NL
14 | *
15 | */
16 |
17 | (function($) {
18 |
19 | $.uix.multiselect.i18n['nl'] = {
20 | itemsSelected_nil: 'Geen geselecteerde items', // 0
21 | itemsSelected: '{count} geselecteerde item', // 0, 1
22 | itemsSelected_plural: '{count} geselecteerde items', // n
23 | //itemsSelected_plural_two: ... // 2
24 | //itemsSelected_plural_few: ... // 3, 4
25 | itemsAvailable_nil: 'Geen item beschikbaar',
26 | itemsAvailable: '{count} beschikbare item',
27 | itemsAvailable_plural: '{count} beschikbare items',
28 | //itemsAvailable_plural_two: ...
29 | //itemsAvailable_plural_few: ...
30 | itemsFiltered_nil: 'Geen gefilterde item',
31 | itemsFiltered: '{count} item gefilterd',
32 | itemsFiltered_plural: '{count} items fgeilterd',
33 | //itemsFiltered_plural_two: ...
34 | //itemsFiltered_plural_few: ...
35 | selectAll: 'Selecteer Alles',
36 | deselectAll: 'Deselecteer Alles',
37 | search: 'Zoek opties',
38 | collapseGroup: 'Klap groep in',
39 | expandGroup: 'Klap Group uit',
40 | selectAllGroup: 'Selecteer alle groepen',
41 | deselectAllGroup: 'Deselecteer alle groepen'
42 | };
43 |
44 | // link locales
45 | $.uix.multiselect.i18n['nl_NL'] = $.uix.multiselect.i18n['nl'];
46 | // ...
47 |
48 | })(jQuery);
49 |
--------------------------------------------------------------------------------
/js/locales/jquery.uix.multiselect_pt.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UI Multiselect 2.0
3 | *
4 | * Authors:
5 | * Yanick Rochon (yanick.rochon[at]gmail[dot]com)
6 | * Translation: Alexander Bulei
7 | *
8 | * Dual licensed under the MIT (MIT-LICENSE.txt)
9 | * and GPL (GPL-LICENSE.txt) licenses.
10 | *
11 | * http://mind2soft.com/labs/jquery/multiselect/
12 | *
13 | *
14 | * Localization : PT
15 | *
16 | */
17 |
18 | (function($) {
19 |
20 | $.uix.multiselect.i18n['pt'] = {
21 | itemsSelected_nil: 'Nenhuma opção selecionada', // 0
22 | itemsSelected: '{count} opção seleccionada', // 0, 1
23 | itemsSelected_plural: '{count} opções seleccionadas', // n
24 | //itemsSelected_plural_two: ... // 2
25 | //itemsSelected_plural_few: ... // 3, 4
26 | itemsAvailable_nil: 'Nenhuma opção disponível',
27 | itemsAvailable: '{count} opção disponível',
28 | itemsAvailable_plural: '{count} opções disponíveis',
29 | //itemsAvailable_plural_two: ...
30 | //itemsAvailable_plural_few: ...
31 | itemsFiltered_nil: 'Nenhuma opção filtrada',
32 | itemsFiltered: '{count} opção filtrada',
33 | itemsFiltered_plural: '{count} opções filtradas',
34 | //itemsFiltered_plural_two: ...
35 | //itemsFiltered_plural_few: ...
36 | selectAll: 'Seleccionar todos',
37 | deselectAll: 'Desseleccionar todos',
38 | search: 'Opções de pesquisa',
39 | collapseGroup: 'Ocultar grupo',
40 | expandGroup: 'Expandir grupo',
41 | selectAllGroup: 'Seleccionar grupo',
42 | deselectAllGroup: 'Desseleccionar grupo'
43 | };
44 |
45 | // link locales
46 | $.uix.multiselect.i18n['pt_PT'] = $.uix.multiselect.i18n['pt'];
47 | $.uix.multiselect.i18n['pt_BR'] = $.uix.multiselect.i18n['pt'];
48 | // ...
49 |
50 | })(jQuery);
51 |
--------------------------------------------------------------------------------
/js/locales/jquery.uix.multiselect_ru.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UI Multiselect 2.0
3 | *
4 | * Authors:
5 | * Yanick Rochon (yanick.rochon[at]gmail[dot]com)
6 | *
7 | * Dual licensed under the MIT (MIT-LICENSE.txt)
8 | * and GPL (GPL-LICENSE.txt) licenses.
9 | *
10 | * http://mind2soft.com/labs/jquery/multiselect/
11 | *
12 | *
13 | * Localization : RU
14 | *
15 | */
16 |
17 | (function($) {
18 |
19 | $.uix.multiselect.i18n['ru'] = {
20 | itemsSelected_nil: 'Варианты не выбраны', // 0
21 | itemsSelected: 'Выбран 1 вариант', // 1
22 | itemsSelected_plural: 'Выбрано {count} вариантов', // n
23 | itemsSelected_plural_two: 'Выбрано 2 варианта', // 2
24 | itemsSelected_plural_few: 'Выбрано {count} варианта',// 3, 4
25 | itemsAvailable_nil: 'Нет вариантов для выбора',
26 | itemsAvailable: 'Доступен один вариант',
27 | itemsAvailable_plural: 'Доступно {count} вариантов',
28 | itemsAvailable_plural_two: 'Доступно 2 варианта',
29 | itemsAvailable_plural_few: 'Доступно {count} варианта',
30 | itemsFiltered_nil: 'Нет отфильтрованных вариантов',
31 | itemsFiltered: 'Отфильтрован 1 вариант',
32 | itemsFiltered_plural: 'Отфильтровано {count} вариантов',
33 | itemsFiltered_plural_two: 'Отфильтровано 2 варианта',
34 | itemsFiltered_plural_few: 'Отфильтровано {count} варианта',
35 | selectAll: 'Выбрать все',
36 | deselectAll: 'Отменить выбор для всех',
37 | search: 'Поиск...',
38 | collapseGroup: 'Свернуть группу',
39 | expandGroup: 'Развернуть группу',
40 | selectAllGroup: 'Выбрать всю группу',
41 | deselectAllGroup: 'Отменить выбор группы'
42 | };
43 |
44 | // link locales
45 | $.uix.multiselect.i18n['ru_RU'] = $.uix.multiselect.i18n['ru'];
46 |
47 | })(jQuery);
48 |
--------------------------------------------------------------------------------
/js/locales/jquery.uix.multiselect_sv.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery UI Multiselect 2.0
3 | *
4 | * Authors:
5 | * Yanick Rochon (yanick.rochon[at]gmail[dot]com)
6 | *
7 | * Dual licensed under the MIT (MIT-LICENSE.txt)
8 | * and GPL (GPL-LICENSE.txt) licenses.
9 | *
10 | * http://mind2soft.com/labs/jquery/multiselect/
11 | *
12 | *
13 | * Localization : EN
14 | *
15 | */
16 |
17 | (function($) {
18 |
19 | $.uix.multiselect.i18n['sv'] = {
20 | itemsSelected_nil: 'inga alternativ valda', // 0
21 | itemsSelected: '{count} valt alternativ', // 0, 1
22 | itemsSelected_plural: '{count} valda alternativ', // n
23 | //itemsSelected_plural_two: ... // 2
24 | //itemsSelected_plural_few: ... // 3, 4
25 | itemsAvailable_nil: 'inga alternativ tillgängliga',
26 | itemsAvailable: '{count} tillgängligt alternativ',
27 | itemsAvailable_plural: '{count} tillgängliga alternativ',
28 | //itemsAvailable_plural_two: ...
29 | //itemsAvailable_plural_few: ...
30 | itemsFiltered_nil: 'inga alternativ filtrerade',
31 | itemsFiltered: '{count} alternativ filtrerat',
32 | itemsFiltered_plural: '{count} alternativ filtrerade',
33 | //itemsFiltered_plural_two: ...
34 | //itemsFiltered_plural_few: ...
35 | selectAll: 'Markera alla',
36 | deselectAll: 'Avmarkera alla',
37 | search: 'Sök alternativ',
38 | collapseGroup: 'Dölj grupp',
39 | expandGroup: 'Visa grupp',
40 | selectAllGroup: 'Markera alla i gruppen',
41 | deselectAllGroup: 'Avmarkera alla i gruppen'
42 | };
43 |
44 | // link locales
45 | $.uix.multiselect.i18n['sv_SE'] = $.uix.multiselect.i18n['sv'];
46 | // ...
47 |
48 | })(jQuery);
49 |
--------------------------------------------------------------------------------