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.
- data/MIT-LICENSE.txt +20 -0
- data/README.md +5 -0
- data/lib/multiselectjs_rails.rb +8 -0
- data/lib/multiselectjs_rails/version.rb +3 -0
- data/vendor/assets/javascripts/locale/ui-multiselect-de.js +11 -0
- data/vendor/assets/javascripts/locale/ui-multiselect-en.js +11 -0
- data/vendor/assets/javascripts/locale/ui-multiselect-es.js +11 -0
- data/vendor/assets/javascripts/locale/ui-multiselect-fr.js +11 -0
- data/vendor/assets/javascripts/locale/ui-multiselect-it.js +13 -0
- data/vendor/assets/javascripts/plugins/localisation/jquery.localisation-min.js +7 -0
- data/vendor/assets/javascripts/plugins/localisation/jquery.localisation-pack.js +7 -0
- data/vendor/assets/javascripts/plugins/localisation/jquery.localisation.js +99 -0
- data/vendor/assets/javascripts/plugins/scrollTo/README.txt +37 -0
- data/vendor/assets/javascripts/plugins/scrollTo/changes.txt +82 -0
- data/vendor/assets/javascripts/plugins/scrollTo/jquery.scrollTo-min.js +11 -0
- data/vendor/assets/javascripts/plugins/scrollTo/jquery.scrollTo.js +207 -0
- data/vendor/assets/javascripts/ui.multiselect.js +480 -0
- data/vendor/assets/stylesheets/ui.multiselect.css +31 -0
- metadata +101 -0
data/MIT-LICENSE.txt
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -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"> </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"> </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: []
|