├── version.txt ├── js ├── locale │ ├── ui-multiselect-ja.js │ ├── ui-multiselect-en.js │ ├── ui-multiselect-es.js │ ├── ui-multiselect-ru.js │ ├── ui-multiselect-fr.js │ ├── ui.multiselect.pt-br.js │ ├── ui-multiselect-de.js │ ├── ui-multiselect-hu.js │ └── ui-multiselect-it.js ├── plugins │ ├── localisation │ │ ├── jquery.localisation-min.js │ │ ├── jquery.localisation-pack.js │ │ └── jquery.localisation.js │ └── scrollTo │ │ ├── jquery.scrollTo-min.js │ │ ├── README.txt │ │ ├── changes.txt │ │ └── jquery.scrollTo.js └── ui.multiselect.js ├── .gitignore ├── README.md ├── MIT-LICENSE.txt ├── css ├── ui.multiselect.css └── common.css └── index.html /version.txt: -------------------------------------------------------------------------------- 1 | 0.3 -------------------------------------------------------------------------------- /js/locale/ui-multiselect-ja.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Localization strings for the UI Multiselect widget 3 | * 4 | * @locale ja, ja-JP 5 | */ 6 | 7 | $.extend($.ui.multiselect.locale, { 8 | addAll:'すべて選択', 9 | removeAll:'すべて削除', 10 | itemsCount:'個選択' 11 | }); 12 | -------------------------------------------------------------------------------- /js/locale/ui-multiselect-en.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Localization strings for the UI Multiselect widget 3 | * 4 | * @locale en, en-US 5 | */ 6 | 7 | $.extend($.ui.multiselect.locale, { 8 | addAll:'Add all', 9 | removeAll:'Remove all', 10 | itemsCount:'items selected' 11 | }); 12 | -------------------------------------------------------------------------------- /js/locale/ui-multiselect-es.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Localization strings for the UI Multiselect widget 3 | * 4 | * @locale es, es-ES 5 | */ 6 | 7 | $.extend($.ui.multiselect.locale, { 8 | addAll:'Agregar todos', 9 | removeAll:'Remover todos', 10 | itemsCount:'Objetos seleccionados' 11 | }); -------------------------------------------------------------------------------- /js/locale/ui-multiselect-ru.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Localization strings for the UI Multiselect widget 3 | * 4 | * @locale ru, ru-RU 5 | */ 6 | 7 | $.extend($.ui.multiselect.locale, { 8 | addAll:'Добавить все', 9 | removeAll:'Удалить все', 10 | itemsCount:'элементов выбрано' 11 | }); 12 | -------------------------------------------------------------------------------- /js/locale/ui-multiselect-fr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Localization strings for the UI Multiselect widget 3 | * 4 | * @locale fr, fr-FR, fr-CA 5 | */ 6 | 7 | $.extend($.ui.multiselect.locale, { 8 | addAll:'Ajouter tout', 9 | removeAll:'Supprimer tout', 10 | itemsCount:'items sélectionnés' 11 | }); 12 | -------------------------------------------------------------------------------- /js/locale/ui.multiselect.pt-br.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Localization strings for the UI Multiselect widget 3 | * 4 | * @locale pt, pt-BR 5 | */ 6 | 7 | $.extend($.ui.multiselect.locale, { 8 | addAll:'Adicionar todos', 9 | removeAll:'Remover todos', 10 | itemsCount:'Itens selecionados' 11 | }); 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | test_log 2 | pkg 3 | pkg/* 4 | */pkg/* 5 | bundle 6 | bundle/* 7 | doc 8 | *.log 9 | log 10 | !log*.rb 11 | */log 12 | log/* 13 | */log/* 14 | coverage 15 | */coverage 16 | lib/dm-more.rb 17 | *.db 18 | nbproject 19 | .DS_Store 20 | rspec_report.html 21 | *.swp 22 | _Yardoc 23 | */ri 24 | 25 | -------------------------------------------------------------------------------- /js/locale/ui-multiselect-de.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Localization strings for the UI Multiselect widget 3 | * 4 | * @locale de, de-DE, de-AT, de-CH 5 | */ 6 | 7 | $.extend($.ui.multiselect.locale, { 8 | addAll:'Alle hinzufügen', 9 | removeAll:'Alle entfernen', 10 | itemsCount:'Einträge ausgewählt' 11 | }); 12 | -------------------------------------------------------------------------------- /js/locale/ui-multiselect-hu.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Localization strings for the UI Multiselect widget 3 | * 4 | * @locale hu, hu-HU 5 | */ 6 | 7 | $.extend($.ui.multiselect.locale, { 8 | addAll: 'Összes hozzáadása', 9 | removeAll: 'Összes eltávolítása', 10 | itemsCount: 'kiválasztott elem' 11 | }); 12 | -------------------------------------------------------------------------------- /js/locale/ui-multiselect-it.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Localization strings for the UI Multiselect widget 3 | * 4 | * @locale it, it-IT 5 | */ 6 | 7 | $.extend($.ui.multiselect, { 8 | locale: { 9 | addAll:'Aggiungi tutti', 10 | removeAll:'Rimuovi tutti', 11 | itemsCount:'elementi selezionati' 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## jQuery UI Multiselect 2 | 3 | This repository is no longer actively maintained by the author. However, pull requests are always welcome. If there's someone interested in officially maintaining the plugin, please let me know. 4 | 5 | In case you are looking for an AJAX version, please also consider "Yanick Rochon's":http://github.com/michael/multiselect/tree/next version, or also check the official "version 2.0":https://github.com/yanickrochon/jquery.uix.multiselect currently in development. 6 | 7 | To get the order of the selected items as selected, you can do like 8 | ```javascript 9 | var form = $("form#my_form"); 10 | $(form).on('submit', function(){ 11 | $("ul.selected li").each(function(){ 12 | var selected_value = $(this).attr('data-selected-value'); 13 | if(selected_value){ 14 | $(form).append(""); 15 | } 16 | }); 17 | }); 18 | ``` 19 | -------------------------------------------------------------------------------- /MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 Michael Aufreiter, http://www.quasipartikel.at 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. -------------------------------------------------------------------------------- /js/plugins/localisation/jquery.localisation-min.js: -------------------------------------------------------------------------------- 1 | /* http://keith-wood.name/localisation.html 2 | Localisation assistance for jQuery v1.0.4. 3 | Written by Keith Wood (kbwood{at}iinet.com.au) June 2007. 4 | Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and 5 | MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. 6 | Please attribute the author if you use it. */ 7 | (function($){$.localise=function(c,d,e,f,g){if(typeof d!='object'&&typeof d!='string'){g=f;f=e;e=d;d=''}if(typeof e!='boolean'){g=f;f=e;e=false}if(typeof f!='string'&&!isArray(f)){g=f;f=['','']}var h={async:$.ajaxSettings.async,timeout:$.ajaxSettings.timeout};d=(typeof d!='string'?d||{}:{language:d,loadBase:e,path:f,timeout:g});var j=(!d.path?['','']:(isArray(d.path)?d.path:[d.path,d.path]));$.ajaxSetup({async:false,timeout:(d.timeout||500)});var k=function(a,b){if(d.loadBase){$.getScript(j[0]+a+'.js')}if(b.length>=2){$.getScript(j[1]+a+'-'+b.substring(0,2)+'.js')}if(b.length>=5){$.getScript(j[1]+a+'-'+b.substring(0,5)+'.js')}};var l=normaliseLang(d.language||$.localise.defaultLanguage);c=(isArray(c)?c:[c]);for(i=0;i3){a=a.substring(0,3)+a.substring(3).toUpperCase()}return a}function isArray(a){return(a&&a.constructor==Array)}})(jQuery); -------------------------------------------------------------------------------- /js/plugins/localisation/jquery.localisation-pack.js: -------------------------------------------------------------------------------- 1 | /* http://keith-wood.name/localisation.html 2 | Localisation assistance for jQuery v1.0.4. 3 | Written by Keith Wood (kbwood{at}iinet.com.au) June 2007. 4 | Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and 5 | MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. 6 | Please attribute the author if you use it. */ 7 | eval(function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(7($){$.m=7(c,d,e,f,g){4(8 d!=\'E\'&&8 d!=\'r\'){g=f;f=e;e=d;d=\'\'}4(8 e!=\'F\'){g=f;f=e;e=x}4(8 f!=\'r\'&&!n(f)){g=f;f=[\'\',\'\']}o h={s:$.y.s,9:$.y.9};d=(8 d!=\'r\'?d||{}:{t:d,z:e,6:f,9:g});o j=(!d.6?[\'\',\'\']:(n(d.6)?d.6:[d.6,d.6]));$.A({s:x,9:(d.9||G)});o k=7(a,b){4(d.z){$.u(j[0]+a+\'.v\')}4(b.p>=2){$.u(j[1]+a+\'-\'+b.q(0,2)+\'.v\')}4(b.p>=5){$.u(j[1]+a+\'-\'+b.q(0,5)+\'.v\')}};o l=w(d.t||$.m.B);c=(n(c)?c:[c]);H(i=0;i3){a=a.q(0,3)+a.q(3).N()}D a}7 n(a){D(a&&a.O==P)}})(Q);',53,53,'||||if||path|function|typeof|timeout|||||||||||||localise|isArray|var|length|substring|string|async|language|getScript|js|normaliseLang|false|ajaxSettings|loadBase|ajaxSetup|defaultLanguage|navigator|return|object|boolean|500|for|localize|userLanguage|replace|_|toLowerCase|toUpperCase|constructor|Array|jQuery'.split('|'),0,{})) -------------------------------------------------------------------------------- /css/ui.multiselect.css: -------------------------------------------------------------------------------- 1 | /* Multiselect 2 | ----------------------------------*/ 3 | 4 | .ui-multiselect { border: solid 1px; font-size: 0.8em; } 5 | .ui-multiselect ul { -moz-user-select: none; } 6 | .ui-multiselect li { margin: 0; padding: 0; cursor: default; line-height: 20px; height: 20px; font-size: 11px; list-style: none; } 7 | .ui-multiselect li a { color: #999; text-decoration: none; padding: 0; display: block; float: left; cursor: pointer;} 8 | .ui-multiselect li.ui-draggable-dragging { padding-left: 10px; } 9 | 10 | .ui-multiselect div.selected { position: relative; padding: 0; margin: 0; border: 0; float:left; } 11 | .ui-multiselect ul.selected { position: relative; padding: 0; overflow: auto; overflow-x: hidden; background: #fff; margin: 0; list-style: none; border: 0; position: relative; width: 100%; } 12 | .ui-multiselect ul.selected li { } 13 | 14 | .ui-multiselect div.available { position: relative; padding: 0; margin: 0; border: 0; float:left; border-left: 1px solid; } 15 | .ui-multiselect ul.available { position: relative; padding: 0; overflow: auto; overflow-x: hidden; background: #fff; margin: 0; list-style: none; border: 0; width: 100%; } 16 | .ui-multiselect ul.available li { padding-left: 10px; } 17 | 18 | .ui-multiselect .ui-state-default { border: none; margin-bottom: 1px; position: relative; padding-left: 20px;} 19 | .ui-multiselect .ui-state-hover { border: none; } 20 | .ui-multiselect .ui-widget-header {border: none; font-size: 11px; margin-bottom: 1px;} 21 | 22 | .ui-multiselect .add-all { float: right; padding: 7px;} 23 | .ui-multiselect .remove-all { float: right; padding: 7px;} 24 | .ui-multiselect .search { float: left; padding: 4px;} 25 | .ui-multiselect .count { float: left; padding: 7px;} 26 | 27 | .ui-multiselect li span.ui-icon-arrowthick-2-n-s { position: absolute; left: 2px; } 28 | .ui-multiselect li a.action { position: absolute; right: 2px; top: 2px; } 29 | 30 | .ui-multiselect input.search { height: 14px; padding: 1px; opacity: 0.5; margin: 4px; width: 100px; } -------------------------------------------------------------------------------- /js/plugins/scrollTo/jquery.scrollTo-min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery.ScrollTo - Easy element scrolling using jQuery. 3 | * Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com 4 | * Dual licensed under MIT and GPL. 5 | * Date: 3/9/2009 6 | * @author Ariel Flesler 7 | * @version 1.4.1 8 | * 9 | * http://flesler.blogspot.com/2007/10/jqueryscrollto.html 10 | */ 11 | ;(function($){var m=$.scrollTo=function(b,h,f){$(window).scrollTo(b,h,f)};m.defaults={axis:'xy',duration:parseFloat($.fn.jquery)>=1.3?0:1};m.window=function(b){return $(window).scrollable()};$.fn.scrollable=function(){return this.map(function(){var b=this,h=!b.nodeName||$.inArray(b.nodeName.toLowerCase(),['iframe','#document','html','body'])!=-1;if(!h)return b;var f=(b.contentWindow||b).document||b.ownerDocument||b;return $.browser.safari||f.compatMode=='BackCompat'?f.body:f.documentElement})};$.fn.scrollTo=function(l,j,a){if(typeof j=='object'){a=j;j=0}if(typeof a=='function')a={onAfter:a};if(l=='max')l=9e9;a=$.extend({},m.defaults,a);j=j||a.speed||a.duration;a.queue=a.queue&&a.axis.length>1;if(a.queue)j/=2;a.offset=n(a.offset);a.over=n(a.over);return this.scrollable().each(function(){var k=this,o=$(k),d=l,p,g={},q=o.is('html,body');switch(typeof d){case'number':case'string':if(/^([+-]=)?\d+(\.\d+)?(px)?$/.test(d)){d=n(d);break}d=$(d,this);case'object':if(d.is||d.style)p=(d=$(d)).offset()}$.each(a.axis.split(''),function(b,h){var f=h=='x'?'Left':'Top',i=f.toLowerCase(),c='scroll'+f,r=k[c],s=h=='x'?'Width':'Height';if(p){g[c]=p[i]+(q?0:r-o.offset()[i]);if(a.margin){g[c]-=parseInt(d.css('margin'+f))||0;g[c]-=parseInt(d.css('border'+f+'Width'))||0}g[c]+=a.offset[i]||0;if(a.over[i])g[c]+=d[s.toLowerCase()]()*a.over[i]}else g[c]=d[i];if(/^\d+$/.test(g[c]))g[c]=g[c]<=0?0:Math.min(g[c],u(s));if(!b&&a.queue){if(r!=g[c])t(a.onAfterFirst);delete g[c]}});t(a.onAfter);function t(b){o.animate(g,j,a.easing,b&&function(){b.call(this,l,a)})};function u(b){var h='scroll'+b;if(!q)return k[h];var f='client'+b,i=k.ownerDocument.documentElement,c=k.ownerDocument.body;return Math.max(i[h],c[h])-Math.min(i[f],c[f])}}).end()};function n(b){return typeof b=='object'?b:{top:b,left:b}}})(jQuery); -------------------------------------------------------------------------------- /js/plugins/scrollTo/README.txt: -------------------------------------------------------------------------------- 1 | jQuery.ScrollTo 1.4 2 | 3 | * Apart from the target and duration, the plugin can receive a hash of settings. Documentation and examples are included in the source file. 4 | 5 | * If you are interested in animated "same-page-scrolling" using anchors(...), check http://jquery.com/plugins/project/LocalScroll 6 | 7 | * The target can be specified as: 8 | * A Number/String specifying a position using px or just the number. 9 | * A string selector that will be relative, to the element that is going to be scrolled, and must match at least one child. 10 | * A DOM element, logically child of the element to scroll. 11 | * A hash { top:x, left:y }, x and y can be any kind of number/string like described above. 12 | 13 | * The plugin supports relative animations 14 | 15 | * 'em' and '%' are not supported as part of the target, because they won't work with jQuery.fn.animate. 16 | 17 | * The plugin might fail to scroll an element, to an inner node that is nested in more scrollable elements. This seems like an odd situation anyway. 18 | 19 | * Both axes ( x, y -> left, top ) can be scrolled, you can send 'x', 'y', 'xy' or 'yx' as 'axis' inside the settings. 20 | 21 | * If 2 axis are scrolled, there's an option to queue the animations, so that the second will start once the first ended ('xy' and 'yx' will have different effects) 22 | 23 | * The option 'margin' can be setted to true, then the margin of the target element, will be taken into account and will be deducted. 24 | 25 | * 'margin' will only be valid, if the target is a selector, a DOM element, or a jQuery Object. 26 | 27 | * The option 'offset' allows to scroll less or more than the actual target by a defined amount of pixels. Can be a number(both axes) or { top:x, left:y }. 28 | 29 | * The option 'over' lets you add or deduct a fraction of the element's height and width from the final position. so over:0.5 will scroll to the middle of the object. can be specified with {top:x, left:y} 30 | 31 | * Don't forget the callback event is now called 'onAfter', and if queuing is activated, then 'onAfterFirst' can be used. 32 | 33 | * If the first axis to be scrolled, is already positioned, that animation will be skipped, to avoid a delay in the animation. 34 | 35 | * The call to the plugin can be made in 2 different ways: $().scrollTo( target, duration, settings ) or $().scrollTo( target, settings ). Where one of the settings is 'duration'. 36 | 37 | * If you find any bug, or you have any advice, don't hesitate to open a ticket/request at http://jquery.com/plugins/project/ScrollTo . -------------------------------------------------------------------------------- /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 | /* multiselect styles */ 44 | .multiselect { 45 | width: 460px; 46 | height: 200px; 47 | } 48 | 49 | #switcher { 50 | margin-top: 20px; 51 | } 52 | 53 | form {margin: 0; padding: 0;} 54 | -------------------------------------------------------------------------------- /js/plugins/scrollTo/changes.txt: -------------------------------------------------------------------------------- 1 | 1.4.1 2 | [Feature] 3 | - The target can be 'max' to scroll to the end while keeping it elegant. 4 | [Enhancement] 5 | - Default duration is 0 for jquery +1.3. Means sync animation 6 | - The plugin works on all major browsers, on compat & quirks modes, including iframes. 7 | - In addition to window/document, if html or body are received, the plugin will choose the right one. 8 | [Fix] 9 | - The Regex accepts floating numbers, Thanks Ramin 10 | - Using jQuery.nodeName where neccessary so that this works on xml+xhtml 11 | - The max() internal function wasn't completely accurrate, now it is 98% (except for IE on quirks mode and it's not too noticeable). 12 | 13 | 1.4 14 | [Fix] 15 | - Fixed the problem when scrolling the window to absolute positioned elements on Safari. 16 | - Fixed the problem on Opera 9.5 when scrolling the window. That it always scrolls to 0. 17 | [Feature] 18 | - Added the settings object as 2nd argument to the onAfter callback. 19 | - The 3rd argument of scrollTo can be just a function and it's used as the onAfter. 20 | - Added full support for iframes (even max scroll calculation). 21 | - Instead of $.scrollTo, $(window).scrollTo() and $(document).scrollTo() can be used. 22 | - Added $().scrollable() that returns the real element to scroll, f.e: $(window).scrollable() == [body|html], works for iframes. 23 | [Enhancement] 24 | - Cleaned the code a bit, specially the comments 25 | 26 | 1.3.3 27 | [Change] 28 | - Changed the licensing from GPL to GPL+MIT. 29 | 30 | 1.3.2 31 | [Enhancement] 32 | - Small improvements to make the code shorter. 33 | [Change] 34 | - Removed the last argument received by onAfter as it was the same as the 'this' but jqueryfied. 35 | 36 | 1.3.1 37 | [Feature] 38 | - Exposed $.scrollTo.window() to get the element that needs to be animated, to scroll the window. 39 | - Added option 'over'. 40 | [Enhancement] 41 | - Made the code as short as possible. 42 | [Change] 43 | - Changed the arguments received by onAfter 44 | 45 | 1.3 46 | [Enhancement] 47 | - Added semicolon to the start, for safe file concatenation 48 | - Added a limit check, values below 0 or over the maximum are fixed. 49 | - Now it should work faster, only one of html or body go through all the processing, instead of both for all browsers. 50 | [Fix] 51 | - Fixed the behavior for Opera, which seemed to react to both changes on and . 52 | - The border is also reduced, when 'margin' is set to true. 53 | [Change] 54 | - The option speed has been renamed to duration. 55 | [Feature] 56 | - The duration can be specified with a number as 2nd argument, and the rest of the settings as the third ( like $().animate ) 57 | - Remade the demo 58 | 59 | 1.2.4 60 | [Enhancement] 61 | - The target can be in the form of { top:x, left:y } allowing different position for each axis. 62 | [Feature] 63 | - The option 'offset' has been added, to scroll behind or past the target. Can be a number(both axes) or { top:x, left:y }. 64 | 65 | 1.2.3 66 | [Feature] 67 | - Exposed the defaults. 68 | [Enhancement] 69 | - Made the callback functions receive more parameters. 70 | 71 | 1.2.2 72 | [Fix] 73 | - Fixed a bug, I didn't have to add the scrolled amount if it was body or html. 74 | 75 | 1.2 76 | [Change] 77 | - The option 'onafter' is now called 'onAfter'. 78 | [Feature] 79 | - Two axes can be scrolled together, this is set with the option 'axis'. 80 | - In case 2 axes are chosen, the scrolling can be queued: one scrolls, and then the other. 81 | - There's an intermediary event, 'onAfterFirst' called in case the axes are queued, after the first ends. 82 | - If the option 'margin' is set to true, the plugin will take in account, the margin of the target(no use if target is a value). -------------------------------------------------------------------------------- /js/plugins/localisation/jquery.localisation.js: -------------------------------------------------------------------------------- 1 | /* http://keith-wood.name/localisation.html 2 | Localisation assistance for jQuery v1.0.4. 3 | Written by Keith Wood (kbwood{at}iinet.com.au) June 2007. 4 | Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and 5 | MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. 6 | Please attribute the author if you use it. */ 7 | 8 | (function($) { // Hide scope, no $ conflict 9 | 10 | /* Load applicable localisation package(s) for one or more jQuery packages. 11 | Assumes that the localisations are named -.js 12 | and loads them in order from least to most specific. 13 | For example, $.localise('mypackage'); 14 | with the browser set to 'en-US' would attempt to load 15 | mypackage-en.js and mypackage-en-US.js. 16 | Also accepts an array of package names to process. 17 | Optionally specify whether or not to include the base file, 18 | the desired language, and/or the timeout period, e.g. 19 | $.localise(['mypackage1', 'yourpackage'], 20 | {loadBase: true; language: 'en-AU', timeout: 300}); 21 | @param packages (string or string[]) names of package(s) to load 22 | @param settings omit for the current browser language or 23 | (string) code for the language to load (aa[-AA]) or 24 | (object} options for the call with 25 | language (string) the code for the language 26 | loadBase (boolean) true to also load the base package or false (default) to not 27 | path (string or string[2]) the paths to the JavaScript, 28 | either as both or [base, localisations] 29 | timeout (number) the time period in milliseconds (default 500) 30 | @param loadBase (boolean, optional) true to also load the base package or false (default) to not - 31 | omit this if settings is an object 32 | @param path (string or string[2], optional) the paths to the JavaScript, 33 | either as both or [base, localisations] - 34 | omit this if settings is an object 35 | @param timeout (number, optional) the time period in milliseconds (default 500) - 36 | omit this if settings is an object */ 37 | $.localise = function(packages, settings, loadBase, path, timeout) { 38 | if (typeof settings != 'object' && typeof settings != 'string') { 39 | timeout = path; 40 | path = loadBase; 41 | loadBase = settings; 42 | settings = ''; 43 | } 44 | if (typeof loadBase != 'boolean') { 45 | timeout = path; 46 | path = loadBase; 47 | loadBase = false; 48 | } 49 | if (typeof path != 'string' && !isArray(path)) { 50 | timeout = path; 51 | path = ['', '']; 52 | } 53 | var saveSettings = {async: $.ajaxSettings.async, timeout: $.ajaxSettings.timeout}; 54 | settings = (typeof settings != 'string' ? settings || {} : 55 | {language: settings, loadBase: loadBase, path: path, timeout: timeout}); 56 | var paths = (!settings.path ? ['', ''] : 57 | (isArray(settings.path) ? settings.path : [settings.path, settings.path])); 58 | $.ajaxSetup({async: false, timeout: (settings.timeout || 500)}); 59 | var localiseOne = function(package, lang) { 60 | if (settings.loadBase) { 61 | $.getScript(paths[0] + package + '.js'); 62 | } 63 | if (lang.length >= 2) { 64 | $.getScript(paths[1] + package + '-' + lang.substring(0, 2) + '.js'); 65 | } 66 | if (lang.length >= 5) { 67 | $.getScript(paths[1] + package + '-' + lang.substring(0, 5) + '.js'); 68 | } 69 | }; 70 | var lang = normaliseLang(settings.language || $.localise.defaultLanguage); 71 | packages = (isArray(packages) ? packages : [packages]); 72 | for (i = 0; i < packages.length; i++) { 73 | localiseOne(packages[i], lang); 74 | } 75 | $.ajaxSetup(saveSettings); 76 | }; 77 | 78 | // Localise it! 79 | $.localize = $.localise; 80 | 81 | /* Retrieve the default language set for the browser. */ 82 | $.localise.defaultLanguage = normaliseLang(navigator.language /* Mozilla */ || 83 | navigator.userLanguage /* IE */); 84 | 85 | /* Ensure language code is in the format aa-AA. */ 86 | function normaliseLang(lang) { 87 | lang = lang.replace(/_/, '-').toLowerCase(); 88 | if (lang.length > 3) { 89 | lang = lang.substring(0, 3) + lang.substring(3).toUpperCase(); 90 | } 91 | return lang; 92 | } 93 | 94 | /* Determine whether an object is an array. */ 95 | function isArray(a) { 96 | return (a && a.constructor == Array); 97 | } 98 | 99 | })(jQuery); 100 | -------------------------------------------------------------------------------- /js/plugins/scrollTo/jquery.scrollTo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery.ScrollTo 3 | * Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com 4 | * Dual licensed under MIT and GPL. 5 | * Date: 3/9/2009 6 | * 7 | * @projectDescription Easy element scrolling using jQuery. 8 | * http://flesler.blogspot.com/2007/10/jqueryscrollto.html 9 | * Works with jQuery +1.2.6. Tested on FF 2/3, IE 6/7, Opera 9.5/6, Safari 3, Chrome 1 on WinXP. 10 | * 11 | * @author Ariel Flesler 12 | * @version 1.4.1 13 | * 14 | * @id jQuery.scrollTo 15 | * @id jQuery.fn.scrollTo 16 | * @param {String, Number, DOMElement, jQuery, Object} target Where to scroll the matched elements. 17 | * The different options for target are: 18 | * - A number position (will be applied to all axes). 19 | * - A string position ('44', '100px', '+=90', etc ) will be applied to all axes 20 | * - A jQuery/DOM element ( logically, child of the element to scroll ) 21 | * - A string selector, that will be relative to the element to scroll ( 'li:eq(2)', etc ) 22 | * - A hash { top:x, left:y }, x and y can be any kind of number/string like above. 23 | * @param {Number} duration The OVERALL length of the animation, this argument can be the settings object instead. 24 | * @param {Object,Function} settings Optional set of settings or the onAfter callback. 25 | * @option {String} axis Which axis must be scrolled, use 'x', 'y', 'xy' or 'yx'. 26 | * @option {Number} duration The OVERALL length of the animation. 27 | * @option {String} easing The easing method for the animation. 28 | * @option {Boolean} margin If true, the margin of the target element will be deducted from the final position. 29 | * @option {Object, Number} offset Add/deduct from the end position. One number for both axes or { top:x, left:y }. 30 | * @option {Object, Number} over Add/deduct the height/width multiplied by 'over', can be { top:x, left:y } when using both axes. 31 | * @option {Boolean} queue If true, and both axis are given, the 2nd axis will only be animated after the first one ends. 32 | * @option {Function} onAfter Function to be called after the scrolling ends. 33 | * @option {Function} onAfterFirst If queuing is activated, this function will be called after the first scrolling ends. 34 | * @return {jQuery} Returns the same jQuery object, for chaining. 35 | * 36 | * @desc Scroll to a fixed position 37 | * @example $('div').scrollTo( 340 ); 38 | * 39 | * @desc Scroll relatively to the actual position 40 | * @example $('div').scrollTo( '+=340px', { axis:'y' } ); 41 | * 42 | * @dec Scroll using a selector (relative to the scrolled element) 43 | * @example $('div').scrollTo( 'p.paragraph:eq(2)', 500, { easing:'swing', queue:true, axis:'xy' } ); 44 | * 45 | * @ Scroll to a DOM element (same for jQuery object) 46 | * @example var second_child = document.getElementById('container').firstChild.nextSibling; 47 | * $('#container').scrollTo( second_child, { duration:500, axis:'x', onAfter:function(){ 48 | * alert('scrolled!!'); 49 | * }}); 50 | * 51 | * @desc Scroll on both axes, to different values 52 | * @example $('div').scrollTo( { top: 300, left:'+=200' }, { axis:'xy', offset:-20 } ); 53 | */ 54 | ;(function( $ ){ 55 | 56 | var $scrollTo = $.scrollTo = function( target, duration, settings ){ 57 | $(window).scrollTo( target, duration, settings ); 58 | }; 59 | 60 | $scrollTo.defaults = { 61 | axis:'xy', 62 | duration: parseFloat($.fn.jquery) >= 1.3 ? 0 : 1 63 | }; 64 | 65 | // Returns the element that needs to be animated to scroll the window. 66 | // Kept for backwards compatibility (specially for localScroll & serialScroll) 67 | $scrollTo.window = function( scope ){ 68 | return $(window).scrollable(); 69 | }; 70 | 71 | // Hack, hack, hack... stay away! 72 | // Returns the real elements to scroll (supports window/iframes, documents and regular nodes) 73 | $.fn.scrollable = function(){ 74 | return this.map(function(){ 75 | var elem = this, 76 | isWin = !elem.nodeName || $.inArray( elem.nodeName.toLowerCase(), ['iframe','#document','html','body'] ) != -1; 77 | 78 | if( !isWin ) 79 | return elem; 80 | 81 | var doc = (elem.contentWindow || elem).document || elem.ownerDocument || elem; 82 | 83 | return $.browser.safari || doc.compatMode == 'BackCompat' ? 84 | doc.body : 85 | doc.documentElement; 86 | }); 87 | }; 88 | 89 | $.fn.scrollTo = function( target, duration, settings ){ 90 | if( typeof duration == 'object' ){ 91 | settings = duration; 92 | duration = 0; 93 | } 94 | if( typeof settings == 'function' ) 95 | settings = { onAfter:settings }; 96 | 97 | if( target == 'max' ) 98 | target = 9e9; 99 | 100 | settings = $.extend( {}, $scrollTo.defaults, settings ); 101 | // Speed is still recognized for backwards compatibility 102 | duration = duration || settings.speed || settings.duration; 103 | // Make sure the settings are given right 104 | settings.queue = settings.queue && settings.axis.length > 1; 105 | 106 | if( settings.queue ) 107 | // Let's keep the overall duration 108 | duration /= 2; 109 | settings.offset = both( settings.offset ); 110 | settings.over = both( settings.over ); 111 | 112 | return this.scrollable().each(function(){ 113 | var elem = this, 114 | $elem = $(elem), 115 | targ = target, toff, attr = {}, 116 | win = $elem.is('html,body'); 117 | 118 | switch( typeof targ ){ 119 | // A number will pass the regex 120 | case 'number': 121 | case 'string': 122 | if( /^([+-]=)?\d+(\.\d+)?(px)?$/.test(targ) ){ 123 | targ = both( targ ); 124 | // We are done 125 | break; 126 | } 127 | // Relative selector, no break! 128 | targ = $(targ,this); 129 | case 'object': 130 | // DOMElement / jQuery 131 | if( targ.is || targ.style ) 132 | // Get the real position of the target 133 | toff = (targ = $(targ)).offset(); 134 | } 135 | $.each( settings.axis.split(''), function( i, axis ){ 136 | var Pos = axis == 'x' ? 'Left' : 'Top', 137 | pos = Pos.toLowerCase(), 138 | key = 'scroll' + Pos, 139 | old = elem[key], 140 | Dim = axis == 'x' ? 'Width' : 'Height'; 141 | 142 | if( toff ){// jQuery / DOMElement 143 | attr[key] = toff[pos] + ( win ? 0 : old - $elem.offset()[pos] ); 144 | 145 | // If it's a dom element, reduce the margin 146 | if( settings.margin ){ 147 | attr[key] -= parseInt(targ.css('margin'+Pos)) || 0; 148 | attr[key] -= parseInt(targ.css('border'+Pos+'Width')) || 0; 149 | } 150 | 151 | attr[key] += settings.offset[pos] || 0; 152 | 153 | if( settings.over[pos] ) 154 | // Scroll to a fraction of its width/height 155 | attr[key] += targ[Dim.toLowerCase()]() * settings.over[pos]; 156 | }else 157 | attr[key] = targ[pos]; 158 | 159 | // Number or 'number' 160 | if( /^\d+$/.test(attr[key]) ) 161 | // Check the limits 162 | attr[key] = attr[key] <= 0 ? 0 : Math.min( attr[key], max(Dim) ); 163 | 164 | // Queueing axes 165 | if( !i && settings.queue ){ 166 | // Don't waste time animating, if there's no need. 167 | if( old != attr[key] ) 168 | // Intermediate animation 169 | animate( settings.onAfterFirst ); 170 | // Don't animate this axis again in the next iteration. 171 | delete attr[key]; 172 | } 173 | }); 174 | 175 | animate( settings.onAfter ); 176 | 177 | function animate( callback ){ 178 | $elem.animate( attr, duration, settings.easing, callback && function(){ 179 | callback.call(this, target, settings); 180 | }); 181 | }; 182 | 183 | // Max scrolling position, works on quirks mode 184 | // It only fails (not too badly) on IE, quirks mode. 185 | function max( Dim ){ 186 | var scroll = 'scroll'+Dim; 187 | 188 | if( !win ) 189 | return elem[scroll]; 190 | 191 | var size = 'client' + Dim, 192 | html = elem.ownerDocument.documentElement, 193 | body = elem.ownerDocument.body; 194 | 195 | return Math.max( html[scroll], body[scroll] ) 196 | - Math.min( html[size] , body[size] ); 197 | 198 | }; 199 | 200 | }).end(); 201 | }; 202 | 203 | function both( val ){ 204 | return typeof val == 'object' ? val : { top:val, left:val }; 205 | }; 206 | 207 | })( jQuery ); -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | jQuery UI Multiselect 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 21 | 22 | 23 | Fork me on GitHub 24 | 25 |
26 | 39 | 40 |
41 |

42 | It depends on jQuery 1.5 and jQuery UI 1.8. 43 | The widget is styleable using Themeroller. 44 | It works in an unobtrusive fashion, by just turning html multiple select inputs into a sexier equivalent. There's no extra markup needed. 45 |

46 | 47 |
    48 |
  • For installation instructions please have a look at the corresponding blogpost
  • 49 |
  • Source code is available at Github
  • 50 |
  • In case you are looking for the original version, it has been moved here
  • 51 |

52 | 53 |
54 | 159 |
160 | 161 |
162 | 163 | 166 |
167 | 168 |

Features

169 |
    170 |
  • Search within available options, if there are a lots of them
  • 171 |
  • Displaying counts of selected and available items
  • 172 |
  • Select All / Deselect All Buttons
  • 173 |
  • Dragging items from the available list to the selected list directly
  • 174 |
175 | 176 |

Contributors

177 | 181 |

182 |

Misc

183 |

184 | There are no limitations. Do whatever you want with this plugin. 185 | If you did some nice modifications, just let me know (via Github). I'd be happy to include them. 186 |

187 |

Other active projects

188 | 194 |
195 | 196 | 201 |
202 | 203 | 204 | -------------------------------------------------------------------------------- /js/ui.multiselect.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery UI Multiselect 3 | * 4 | * Authors: 5 | * Michael Aufreiter (quasipartikel.at) 6 | * Yanick Rochon (yanick.rochon[at]gmail[dot]com) 7 | * 8 | * Dual licensed under the MIT (MIT-LICENSE.txt) 9 | * and GPL (GPL-LICENSE.txt) licenses. 10 | * 11 | * http://www.quasipartikel.at/multiselect/ 12 | * 13 | * 14 | * Depends: 15 | * ui.core.js 16 | * ui.sortable.js 17 | * 18 | * Optional: 19 | * localization (http://plugins.jquery.com/project/localisation) 20 | * scrollTo (http://plugins.jquery.com/project/ScrollTo) 21 | * 22 | * Todo: 23 | * Make batch actions faster 24 | * Implement dynamic insertion through remote calls 25 | */ 26 | 27 | 28 | (function($) { 29 | 30 | $.widget("ui.multiselect", { 31 | options: { 32 | sortable: true, 33 | searchable: true, 34 | doubleClickable: true, 35 | animated: 'fast', 36 | show: 'slideDown', 37 | hide: 'slideUp', 38 | dividerLocation: 0.6, 39 | availableFirst: false, 40 | nodeComparator: function(node1,node2) { 41 | var text1 = node1.text(), 42 | text2 = node2.text(); 43 | return text1 == text2 ? 0 : (text1 < text2 ? -1 : 1); 44 | } 45 | }, 46 | _create: function() { 47 | this.element.hide(); 48 | this.id = this.element.attr("id"); 49 | this.container = $('
').insertAfter(this.element); 50 | this.count = 0; // number of currently selected options 51 | this.selectedContainer = $('
').appendTo(this.container); 52 | this.availableContainer = $('
')[this.options.availableFirst?'prependTo': 'appendTo'](this.container); 53 | this.selectedActions = $('
0 '+$.ui.multiselect.locale.itemsCount+''+$.ui.multiselect.locale.removeAll+'
').appendTo(this.selectedContainer); 54 | this.availableActions = $('').appendTo(this.availableContainer); 55 | this.selectedList = $('
').bind('selectstart', function(){return false;}).appendTo(this.selectedContainer); 56 | this.availableList = $('
').bind('selectstart', function(){return false;}).appendTo(this.availableContainer); 57 | 58 | var that = this; 59 | 60 | // set dimensions 61 | this.container.width(this.element.width()+1); 62 | this.selectedContainer.width(Math.floor(this.element.width()*this.options.dividerLocation)); 63 | this.availableContainer.width(Math.floor(this.element.width()*(1-this.options.dividerLocation))); 64 | 65 | // fix list height to match