multiselectjs_rails 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,20 @@
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.
@@ -0,0 +1,5 @@
1
+ # multiselectjs_rails #
2
+
3
+ This is a rails ready gem to provide the multiselect library from "crdeutsch/multiselect":https://github.com/crdeutsch/multiselect
4
+
5
+ install this in your Gem Assets group and include.
@@ -0,0 +1,8 @@
1
+ require "multiselectjs_rails/version"
2
+
3
+ module Multiselectjs
4
+ module Rails
5
+ class Engine < ::Rails::Engine
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ module MultiselectjsRails
2
+ VERSION = "0.3.1"
3
+ end
@@ -0,0 +1,11 @@
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
+ });
@@ -0,0 +1,11 @@
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
+ });
@@ -0,0 +1,11 @@
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
+ });
@@ -0,0 +1,11 @@
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
+ });
@@ -0,0 +1,13 @@
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
+ });
@@ -0,0 +1,7 @@
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;i<c.length;i++){k(c[i],l)}$.ajaxSetup(h)};$.localize=$.localise;$.localise.defaultLanguage=normaliseLang(navigator.language||navigator.userLanguage);function normaliseLang(a){a=a.replace(/_/,'-').toLowerCase();if(a.length>3){a=a.substring(0,3)+a.substring(3).toUpperCase()}return a}function isArray(a){return(a&&a.constructor==Array)}})(jQuery);
@@ -0,0 +1,7 @@
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(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?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;i<c.p;i++){k(c[i],l)}$.A(h)};$.I=$.m;$.m.B=w(C.t||C.J);7 w(a){a=a.K(/L/,\'-\').M();4(a.p>3){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,{}))
@@ -0,0 +1,99 @@
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 <base>-<lang>.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);
@@ -0,0 +1,37 @@
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(<a href="#some_id">...), 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 .
@@ -0,0 +1,82 @@
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 <html> and <body>.
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).
@@ -0,0 +1,11 @@
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);
@@ -0,0 +1,207 @@
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 );
@@ -0,0 +1,480 @@
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
+ dragToAdd: true,
34
+ searchable: true,
35
+ doubleClickable: true,
36
+ animated: 'fast',
37
+ show: 'slideDown',
38
+ hide: 'slideUp',
39
+ dividerLocation: 0.6,
40
+ selectedContainerOnLeft: true,
41
+ width: null,
42
+ height: null,
43
+ nodeComparator: function(node1,node2) {
44
+ var text1 = node1.text(),
45
+ text2 = node2.text();
46
+ return text1 == text2 ? 0 : (text1 < text2 ? -1 : 1);
47
+ },
48
+ includeRemoveAll: true,
49
+ includeAddAll: true,
50
+ pressEnterKeyToAddAll: false
51
+ },
52
+ _create: function() {
53
+ this.element.hide();
54
+ this.id = this.element.attr("id");
55
+ this.container = $('<div class="ui-multiselect ui-helper-clearfix ui-widget"></div>').insertAfter(this.element);
56
+ this.count = 0; // number of currently selected options
57
+ this.selectedContainer = $('<div class="selected"></div>');
58
+ if (this.options.selectedContainerOnLeft) {
59
+ this.selectedContainer.appendTo(this.container);
60
+ this.availableContainer = $('<div class="available"></div>').appendTo(this.container);
61
+ this.availableContainer.addClass('right-column');
62
+ }
63
+ else
64
+ {
65
+ this.availableContainer = $('<div class="available"></div>').appendTo(this.container);
66
+ this.selectedContainer.appendTo(this.container);
67
+ this.selectedContainer.addClass('right-column');
68
+ }
69
+ this.selectedActions = $('<div class="actions ui-widget-header ui-helper-clearfix"><span class="count">0 '+$.ui.multiselect.locale.itemsCount+'</span>'+(this.options.includeRemoveAll?'<a href="#" class="remove-all">'+$.ui.multiselect.locale.removeAll+'</a>':'<span class="remove-all">&nbsp;</span>')+'</div>').appendTo(this.selectedContainer);
70
+ this.availableActions = $('<div class="actions ui-widget-header ui-helper-clearfix"><input type="text" class="search empty ui-widget-content ui-corner-all"/>'+(this.options.includeAddAll?'<a href="#" class="add-all">'+$.ui.multiselect.locale.addAll+'</a>':'<span class="add-all">&nbsp;</span>')+'</div>').appendTo(this.availableContainer);
71
+ this.selectedList = $('<ul class="selected connected-list"><li class="ui-helper-hidden-accessible"></li></ul>').bind('selectstart', function(){return false;}).appendTo(this.selectedContainer);
72
+ this.availableList = $('<ul class="available connected-list"><li class="ui-helper-hidden-accessible"></li></ul>').bind('selectstart', function(){return false;}).appendTo(this.availableContainer);
73
+
74
+ var that = this;
75
+
76
+ var width = this.options.width;
77
+ if (!width) {
78
+ width = this.element.width();
79
+ }
80
+ var height = this.options.height;
81
+ if (!height) {
82
+ height = this.element.height();
83
+ }
84
+
85
+ // set dimensions
86
+ this.container.width(width-2);
87
+ if (this.options.selectedContainerOnLeft) {
88
+ this.selectedContainer.width(Math.floor(width*this.options.dividerLocation)-1);
89
+ this.availableContainer.width(Math.floor(width*(1-this.options.dividerLocation))-2);
90
+ }
91
+ else
92
+ {
93
+ this.selectedContainer.width(Math.floor(width*this.options.dividerLocation)-2);
94
+ this.availableContainer.width(Math.floor(width*(1-this.options.dividerLocation))-1);
95
+ }
96
+
97
+ // fix list height to match <option> depending on their individual header's heights
98
+ this.selectedList.height(Math.max(height-this.selectedActions.height(),1));
99
+ this.availableList.height(Math.max(height-this.availableActions.height(),1));
100
+
101
+ if ( !this.options.animated ) {
102
+ this.options.show = 'show';
103
+ this.options.hide = 'hide';
104
+ }
105
+
106
+ // init lists
107
+ this._populateLists(this.element.find('option'));
108
+
109
+ // make selection sortable
110
+ if (this.options.sortable) {
111
+ this.selectedList.sortable({
112
+ placeholder: 'ui-state-highlight',
113
+ axis: 'y',
114
+ update: function(event, ui) {
115
+ // apply the new sort order to the original selectbox
116
+ that.selectedList.find('li').each(function() {
117
+ if ($(this).data('optionLink'))
118
+ $(this).data('optionLink').remove().appendTo(that.element);
119
+ });
120
+ },
121
+ beforeStop: function (event, ui) {
122
+ // This lets us recognize which item was just added to
123
+ // the list in receive, per the workaround for not being
124
+ // able to reference the new element.
125
+ ui.item.addClass('dropped');
126
+ },
127
+ receive: function(event, ui) {
128
+ ui.item.data('optionLink').attr('selected', true);
129
+ // increment count
130
+ that.count += 1;
131
+ that._updateCount();
132
+ // workaround, because there's no way to reference
133
+ // the new element, see http://dev.jqueryui.com/ticket/4303
134
+ that.selectedList.children('.dropped').each(function() {
135
+ $(this).removeClass('dropped');
136
+ $(this).data('optionLink', ui.item.data('optionLink'));
137
+ $(this).data('idx', ui.item.data('idx'));
138
+ that._applyItemState($(this), true);
139
+ });
140
+
141
+ // workaround according to http://dev.jqueryui.com/ticket/4088
142
+ setTimeout(function() { ui.item.remove(); }, 1);
143
+ },
144
+ stop: function (event, ui) { that.element.change(); }
145
+ });
146
+ }
147
+
148
+ // set up livesearch
149
+ if (this.options.searchable) {
150
+ this._registerSearchEvents(this.availableContainer.find('input.search'));
151
+ } else {
152
+ $('.search').hide();
153
+ }
154
+
155
+ // batch actions
156
+ this.container.find(".remove-all").click(function() {
157
+ that._populateLists(that.element.find('option').removeAttr('selected'));
158
+ that.element.trigger('change');
159
+ return false;
160
+ });
161
+
162
+ this.container.find(".add-all").click(function() {
163
+ var options = that.element.find('option').not(":selected");
164
+ if (that.availableList.children('li:hidden').length > 1) {
165
+ that.availableList.children('li').each(function(i) {
166
+ if ($(this).is(":visible")) $(options[i-1]).attr('selected', 'selected');
167
+ });
168
+ } else {
169
+ options.attr('selected', 'selected');
170
+ }
171
+ that._populateLists(that.element.find('option'));
172
+ that.element.trigger('change');
173
+ if (that.options.pressEnterKeyToAddAll) {
174
+ //clear input after add all
175
+ $('input.search').val("");
176
+ }
177
+
178
+ return false;
179
+ });
180
+ },
181
+ destroy: function() {
182
+ this.element.show();
183
+ this.container.remove();
184
+
185
+ $.Widget.prototype.destroy.apply(this, arguments);
186
+ },
187
+ addOption: function(option) {
188
+ // Append the option
189
+ option = $(option);
190
+ var select = this.element;
191
+ select.append(option);
192
+
193
+ var item = this._getOptionNode(option).appendTo(option.attr('selected') ? this.selectedList : this.availableList).show();
194
+
195
+ if (option.attr('selected')) {
196
+ this.count += 1;
197
+ }
198
+ this._applyItemState(item, option.attr('selected'));
199
+ item.data('idx', this.count);
200
+
201
+ // update count
202
+ this._updateCount();
203
+ this._filter.apply(this.availableContainer.find('input.search'), [this.availableList]);
204
+ },
205
+ // Redisplay the lists of selected/available options.
206
+ // Call this after you've selected/unselected some options programmatically.
207
+ // GRIPE This is O(n) where n is the length of the list - seems like
208
+ // there must be a smarter way of doing this, but I have not been able
209
+ // to come up with one. I see no way to detect programmatic setting of
210
+ // the option's selected property, and without that, it seems like we
211
+ // can't have a general-case listener that does its thing every time an
212
+ // option is selected.
213
+ refresh: function() {
214
+ // Redisplay our lists.
215
+ this._populateLists(this.element.find('option'));
216
+ },
217
+ _populateLists: function(options) {
218
+ this.selectedList.children('.ui-element').remove();
219
+ this.availableList.children('.ui-element').remove();
220
+ this.count = 0;
221
+
222
+ var that = this;
223
+ var groups = $(this.element).find("optgroup").map(function(i) {
224
+ return that._getOptionGroup($(this));
225
+ });
226
+ groups.appendTo(this.selectedList.add(this.availableList));
227
+
228
+ var items = $(options.map(function(i) {
229
+ var item = that._getOptionNode(this).appendTo(that._getOptionList(this)).show();
230
+
231
+ if (this.selected) that.count += 1;
232
+ that._applyItemState(item, this.selected);
233
+ item.data('idx', i);
234
+ return item[0];
235
+ }));
236
+
237
+ // update count
238
+ this._updateCount();
239
+ that._filter.apply(this.availableContainer.find('input.search'), [that.availableList]);
240
+ },
241
+ _getOptionList: function(option) {
242
+ var selected = option.selected;
243
+ option = $(option);
244
+ var $list = selected ? this.selectedList : this.availableList;
245
+ var $group = option.closest("optgroup");
246
+ if ($group.length === 0) {
247
+ return $list;
248
+ } else {
249
+ var $groupList = $list.find("ul[title='" + $group.attr("label") + "']");
250
+ if ($groupList.length === 0) {
251
+ $groupList = $("<ul class='ui-state-default ui-element available' title='" + $group.attr("label") + "'>" + $group.attr("label") + "</ul>").appendTo($list);
252
+ }
253
+ $groupList.show();
254
+ return $groupList;
255
+ }
256
+ },
257
+ _getOptionGroup : function(optgroup) {
258
+ var groupNode = $("<ul class='ui-state-default ui-element available' title='" + optgroup.attr("label") + "'>" + optgroup.attr("label") + "</ul>").hide();
259
+ return groupNode[0];
260
+ },
261
+ _updateCount: function() {
262
+ this.selectedContainer.find('span.count').text(this.count+" "+$.ui.multiselect.locale.itemsCount);
263
+ },
264
+ _getOptionNode: function(option) {
265
+ option = $(option);
266
+ var node = $('<li class="ui-state-default ui-element" title="'+option.text()+'"><span class="ui-icon"/>'+option.text()+'<a href="#" class="action"><span class="ui-corner-all ui-icon"/></a></li>').hide();
267
+ node.data('optionLink', option);
268
+ return node;
269
+ },
270
+ // clones an item with associated data
271
+ // didn't find a smarter away around this
272
+ _cloneWithData: function(clonee) {
273
+ var clone = clonee.clone(false,false);
274
+ clone.data('optionLink', clonee.data('optionLink'));
275
+ clone.data('idx', clonee.data('idx'));
276
+ return clone;
277
+ },
278
+ _setSelected: function(item, selected) {
279
+ var temp = item.data('optionLink').attr('selected', selected);
280
+ var parent = temp.parent();
281
+ temp.detach().appendTo(parent);
282
+ this.element.trigger('change');
283
+
284
+ if (selected) {
285
+ var selectedItem = this._cloneWithData(item);
286
+ item[this.options.hide](this.options.animated, function() {
287
+ if (item.siblings().length === 0) {
288
+ item.closest("ul[title]").hide();
289
+ }
290
+ $(this).remove();
291
+ });
292
+ // get group to add it to...
293
+ var $list = this._getOptionList(selectedItem.data("optionLink")[0]);
294
+ selectedItem.appendTo($list).hide()[this.options.show](this.options.animated);
295
+
296
+ this._applyItemState(selectedItem, true);
297
+ return selectedItem;
298
+ } else {
299
+
300
+ // look for successor based on initial option index
301
+ var items = this.availableList.find('li'), comparator = this.options.nodeComparator;
302
+ var succ = null, i = item.data('idx'), direction = comparator(item, $(items[i]));
303
+
304
+ // TODO: test needed for dynamic list populating
305
+ if ( direction ) {
306
+ while (i>=0 && i<items.length) {
307
+ direction > 0 ? i++ : i--;
308
+ if ( direction != comparator(item, $(items[i])) ) {
309
+ // going up, go back one item down, otherwise leave as is
310
+ succ = items[direction > 0 ? i : i+1];
311
+ var group1 = item.closest("ul[title]"),
312
+ group2 = $(succ).closest("ul[title]");
313
+ if (group1.length !== 0 && group2.length !== 0) {
314
+ if (group1.attr("title") !== group2.attr("title")) {
315
+ succ = null;
316
+ }
317
+ }
318
+ break;
319
+ }
320
+ }
321
+ } else {
322
+ succ = items[i];
323
+ }
324
+
325
+ var availableItem = this._cloneWithData(item);
326
+ var $list = this._getOptionList(availableItem.data("optionLink")[0]);
327
+ succ ? availableItem.insertBefore($(succ)) : availableItem.appendTo($list);
328
+ item[this.options.hide](this.options.animated, function() {
329
+ if (item.siblings().length === 0) {
330
+ item.closest("ul[title]").hide();
331
+ }
332
+ $(this).remove();
333
+ });
334
+ availableItem.hide()[this.options.show](this.options.animated);
335
+
336
+ this._applyItemState(availableItem, false);
337
+ return availableItem;
338
+ }
339
+ },
340
+ _applyItemState: function(item, selected) {
341
+ if (selected) {
342
+ if (this.options.sortable)
343
+ item.children('span').addClass('ui-icon-arrowthick-2-n-s').removeClass('ui-helper-hidden').addClass('ui-icon');
344
+ else
345
+ item.children('span').removeClass('ui-icon-arrowthick-2-n-s').addClass('ui-helper-hidden').removeClass('ui-icon');
346
+ item.find('a.action span').addClass('ui-icon-minus').removeClass('ui-icon-plus');
347
+ this._registerRemoveEvents(item.find('a.action'));
348
+
349
+ } else {
350
+ item.children('span').removeClass('ui-icon-arrowthick-2-n-s').addClass('ui-helper-hidden').removeClass('ui-icon');
351
+ item.find('a.action span').addClass('ui-icon-plus').removeClass('ui-icon-minus');
352
+ this._registerAddEvents(item.find('a.action'));
353
+ }
354
+
355
+ this._registerDoubleClickEvents(item);
356
+ this._registerHoverEvents(item);
357
+ },
358
+ // taken from John Resig's liveUpdate script
359
+ _filter: function(list) {
360
+ var input = $(this);
361
+ var rows = list.find('li'),
362
+ cache = rows.map(function(){
363
+
364
+ return $(this).text().toLowerCase();
365
+ });
366
+
367
+ var term = $.trim(input.val().toLowerCase()), scores = [];
368
+
369
+ if (!term) {
370
+ rows.show();
371
+ } else {
372
+ rows.hide();
373
+
374
+ cache.each(function(i) {
375
+ if (this.indexOf(term)>-1) { scores.push(i); }
376
+ });
377
+
378
+ $.each(scores, function() {
379
+ $(rows[this]).show();
380
+ });
381
+ }
382
+ },
383
+ _registerDoubleClickEvents: function(elements) {
384
+ if (!this.options.doubleClickable) return;
385
+ elements.dblclick(function() {
386
+ elements.find('a.action').click();
387
+ });
388
+ },
389
+ _registerHoverEvents: function(elements) {
390
+ elements.removeClass('ui-state-hover');
391
+ elements.mouseover(function() {
392
+ $(this).addClass('ui-state-hover');
393
+ });
394
+ elements.mouseout(function() {
395
+ $(this).removeClass('ui-state-hover');
396
+ });
397
+ },
398
+ _registerAddEvents: function(elements) {
399
+ var that = this;
400
+ elements.click(function() {
401
+ var item = that._setSelected($(this).parent(), true);
402
+ that.count += 1;
403
+ that._updateCount();
404
+
405
+ // Prevent extra clicks from triggering bogus add events, if a user
406
+ // tries clicking during the removal process.
407
+ $(this).unbind('click');
408
+
409
+ return false;
410
+ });
411
+
412
+ // make draggable
413
+ if (this.options.sortable && this.options.dragToAdd) {
414
+ elements.each(function() {
415
+ $(this).parent().draggable({
416
+ connectToSortable: that.selectedList,
417
+ helper: function() {
418
+ var selectedItem = that._cloneWithData($(this)).width($(this).width() - 50);
419
+ selectedItem.width($(this).width());
420
+ return selectedItem;
421
+ },
422
+ appendTo: that.container,
423
+ containment: that.container,
424
+ revert: 'invalid'
425
+ });
426
+ });
427
+ }
428
+ },
429
+ _registerRemoveEvents: function(elements) {
430
+ var that = this;
431
+ elements.click(function() {
432
+ that._setSelected($(this).parent(), false);
433
+ that.count -= 1;
434
+ that._updateCount();
435
+
436
+ // Prevent extra clicks from triggering bogus remove events, if a
437
+ // user tries clicking during the removal process.
438
+ $(this).unbind('click');
439
+
440
+ return false;
441
+ });
442
+ },
443
+ _registerSearchEvents: function(input) {
444
+ var that = this;
445
+
446
+ input.focus(function() {
447
+ $(this).addClass('ui-state-active');
448
+ })
449
+ .blur(function() {
450
+ $(this).removeClass('ui-state-active');
451
+ })
452
+ .keypress(function(e) {
453
+ if (e.keyCode == 13) {
454
+ if (that.options.pressEnterKeyToAddAll) {
455
+ //on Enter, if a filter is present add all, then clear the input
456
+ var str = $('input.search').val();
457
+ if (str !== undefined && str !== null && str !== "") {
458
+ $('a.add-all').click();
459
+ $('input.search').val("");
460
+ }
461
+ }
462
+ return false;
463
+ }
464
+ })
465
+ .keyup(function() {
466
+ that._filter.apply(this, [that.availableList]);
467
+ });
468
+ }
469
+ });
470
+
471
+ $.extend($.ui.multiselect, {
472
+ locale: {
473
+ addAll:'Add all',
474
+ removeAll:'Remove all',
475
+ itemsCount:'items selected'
476
+ }
477
+ });
478
+
479
+
480
+ })(jQuery);
@@ -0,0 +1,31 @@
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; padding-right: 18px; overflow: hidden; word-wrap: break-word; }
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
+
13
+ .ui-multiselect div.available { position: relative; padding: 0; margin: 0; border: 0; float:left; }
14
+ .ui-multiselect ul.available { position: relative; padding: 0; overflow: auto; overflow-x: hidden; background: #fff; margin: 0; list-style: none; border: 0; width: 100%; }
15
+ .ui-multiselect ul.available li { padding-left: 10px; }
16
+
17
+ .ui-multiselect div.right-column { border-left: 1px solid; }
18
+
19
+ .ui-multiselect .ui-state-default { border: none; margin-bottom: 1px; position: relative; padding-left: 20px;}
20
+ .ui-multiselect .ui-state-hover { border: none; }
21
+ .ui-multiselect .ui-widget-header {border: none; font-size: 11px; margin-bottom: 1px;}
22
+
23
+ .ui-multiselect .add-all { float: right; padding: 7px;}
24
+ .ui-multiselect .remove-all { float: right; padding: 7px;}
25
+ .ui-multiselect .search { float: left; padding: 4px;}
26
+ .ui-multiselect .count { float: left; padding: 7px;}
27
+
28
+ .ui-multiselect li span.ui-icon-arrowthick-2-n-s { position: absolute; left: 2px; }
29
+ .ui-multiselect li a.action { position: absolute; right: 2px; top: 2px; }
30
+
31
+ .ui-multiselect input.search { height: 14px; padding: 1px; opacity: 0.5; margin: 4px; width: 100px; }
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: multiselectjs_rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Scott M Parrish
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: railties
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '3.1'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '3.1'
46
+ description: ! 'A Rails 3.1 Engine to include javascritp and css files from https://github.com/crdeutsch/multiselect '
47
+ email:
48
+ - anithri@gmail.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - lib/multiselectjs_rails/version.rb
54
+ - lib/multiselectjs_rails.rb
55
+ - vendor/assets/stylesheets/ui.multiselect.css
56
+ - vendor/assets/javascripts/ui.multiselect.js
57
+ - vendor/assets/javascripts/locale/ui-multiselect-fr.js
58
+ - vendor/assets/javascripts/locale/ui-multiselect-de.js
59
+ - vendor/assets/javascripts/locale/ui-multiselect-en.js
60
+ - vendor/assets/javascripts/locale/ui-multiselect-es.js
61
+ - vendor/assets/javascripts/locale/ui-multiselect-it.js
62
+ - vendor/assets/javascripts/plugins/scrollTo/jquery.scrollTo-min.js
63
+ - vendor/assets/javascripts/plugins/scrollTo/README.txt
64
+ - vendor/assets/javascripts/plugins/scrollTo/jquery.scrollTo.js
65
+ - vendor/assets/javascripts/plugins/scrollTo/changes.txt
66
+ - vendor/assets/javascripts/plugins/localisation/jquery.localisation.js
67
+ - vendor/assets/javascripts/plugins/localisation/jquery.localisation-pack.js
68
+ - vendor/assets/javascripts/plugins/localisation/jquery.localisation-min.js
69
+ - MIT-LICENSE.txt
70
+ - README.md
71
+ homepage: https://github.com/anithri/multiselectjs_rails
72
+ licenses: []
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ segments:
84
+ - 0
85
+ hash: 368088046168383247
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ segments:
93
+ - 0
94
+ hash: 368088046168383247
95
+ requirements: []
96
+ rubyforge_project: multiselectjs_rails
97
+ rubygems_version: 1.8.21
98
+ signing_key:
99
+ specification_version: 3
100
+ summary: A Rails Engine for vendor/assets of multiselect javascript library"
101
+ test_files: []