multiselectjs_rails 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []