jquery-tools 0.0.2
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/.gitignore +1 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +31 -0
- data/Rakefile +2 -0
- data/jquery-tools.gemspec +17 -0
- data/lib/jquery-tools.rb +8 -0
- data/lib/jquery-tools/version.rb +5 -0
- data/vendor/assets/images/next.gif +0 -0
- data/vendor/assets/images/prev.gif +0 -0
- data/vendor/assets/javascripts/dateinput/dateinput.js +783 -0
- data/vendor/assets/javascripts/overlay/overlay.apple.js +155 -0
- data/vendor/assets/javascripts/overlay/overlay.js +293 -0
- data/vendor/assets/javascripts/rangeinput/rangeinput.js +471 -0
- data/vendor/assets/javascripts/scrollable/scrollable.autoscroll.js +96 -0
- data/vendor/assets/javascripts/scrollable/scrollable.js +368 -0
- data/vendor/assets/javascripts/scrollable/scrollable.navigator.js +134 -0
- data/vendor/assets/javascripts/tabs/tabs.js +319 -0
- data/vendor/assets/javascripts/tabs/tabs.slideshow.js +191 -0
- data/vendor/assets/javascripts/toolbox/toolbox.expose.js +224 -0
- data/vendor/assets/javascripts/toolbox/toolbox.flashembed.js +301 -0
- data/vendor/assets/javascripts/toolbox/toolbox.history.js +108 -0
- data/vendor/assets/javascripts/toolbox/toolbox.mousewheel.js +65 -0
- data/vendor/assets/javascripts/tooltip/tooltip.dynamic.js +154 -0
- data/vendor/assets/javascripts/tooltip/tooltip.js +358 -0
- data/vendor/assets/javascripts/tooltip/tooltip.slide.js +78 -0
- data/vendor/assets/javascripts/validator/validator.js +598 -0
- data/vendor/assets/stylesheets/jquery-tools/dateinput.css +139 -0
- metadata +74 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* jQuery Tools @VERSION / Overlay Apple effect.
|
|
4
|
+
*
|
|
5
|
+
* NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
|
|
6
|
+
*
|
|
7
|
+
* http://flowplayer.org/tools/overlay/apple.html
|
|
8
|
+
*
|
|
9
|
+
* Since: July 2009
|
|
10
|
+
* Date: @DATE
|
|
11
|
+
*/
|
|
12
|
+
(function($) {
|
|
13
|
+
|
|
14
|
+
// version number
|
|
15
|
+
var t = $.tools.overlay,
|
|
16
|
+
w = $(window);
|
|
17
|
+
|
|
18
|
+
// extend global configuragion with effect specific defaults
|
|
19
|
+
$.extend(t.conf, {
|
|
20
|
+
start: {
|
|
21
|
+
top: null,
|
|
22
|
+
left: null
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
fadeInSpeed: 'fast',
|
|
26
|
+
zIndex: 9999
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// utility function
|
|
30
|
+
function getPosition(el) {
|
|
31
|
+
var p = el.offset();
|
|
32
|
+
return {
|
|
33
|
+
top: p.top + el.height() / 2,
|
|
34
|
+
left: p.left + el.width() / 2
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
//{{{ load
|
|
39
|
+
|
|
40
|
+
var loadEffect = function(pos, onLoad) {
|
|
41
|
+
|
|
42
|
+
var overlay = this.getOverlay(),
|
|
43
|
+
conf = this.getConf(),
|
|
44
|
+
trigger = this.getTrigger(),
|
|
45
|
+
self = this,
|
|
46
|
+
oWidth = overlay.outerWidth({margin:true}),
|
|
47
|
+
img = overlay.data("img"),
|
|
48
|
+
position = conf.fixed ? 'fixed' : 'absolute';
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
// growing image is required.
|
|
52
|
+
if (!img) {
|
|
53
|
+
var bg = overlay.css("backgroundImage");
|
|
54
|
+
|
|
55
|
+
if (!bg) {
|
|
56
|
+
throw "background-image CSS property not set for overlay";
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// url("bg.jpg") --> bg.jpg
|
|
60
|
+
bg = bg.slice(bg.indexOf("(") + 1, bg.indexOf(")")).replace(/\"/g, "");
|
|
61
|
+
overlay.css("backgroundImage", "none");
|
|
62
|
+
|
|
63
|
+
img = $('<img src="' + bg + '"/>');
|
|
64
|
+
img.css({border:0, display:'none'}).width(oWidth);
|
|
65
|
+
$('body').append(img);
|
|
66
|
+
overlay.data("img", img);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// initial top & left
|
|
70
|
+
var itop = conf.start.top || Math.round(w.height() / 2),
|
|
71
|
+
ileft = conf.start.left || Math.round(w.width() / 2);
|
|
72
|
+
|
|
73
|
+
if (trigger) {
|
|
74
|
+
var p = getPosition(trigger);
|
|
75
|
+
itop = p.top;
|
|
76
|
+
ileft = p.left;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// put overlay into final position
|
|
80
|
+
if (conf.fixed) {
|
|
81
|
+
itop -= w.scrollTop();
|
|
82
|
+
ileft -= w.scrollLeft();
|
|
83
|
+
} else {
|
|
84
|
+
pos.top += w.scrollTop();
|
|
85
|
+
pos.left += w.scrollLeft();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// initialize background image and make it visible
|
|
89
|
+
img.css({
|
|
90
|
+
position: 'absolute',
|
|
91
|
+
top: itop,
|
|
92
|
+
left: ileft,
|
|
93
|
+
width: 0,
|
|
94
|
+
zIndex: conf.zIndex
|
|
95
|
+
}).show();
|
|
96
|
+
|
|
97
|
+
pos.position = position;
|
|
98
|
+
overlay.css(pos);
|
|
99
|
+
|
|
100
|
+
// begin growing
|
|
101
|
+
img.animate({
|
|
102
|
+
top: overlay.css("top"),
|
|
103
|
+
left: overlay.css("left"),
|
|
104
|
+
width: oWidth}, conf.speed, function() {
|
|
105
|
+
|
|
106
|
+
// set close button and content over the image
|
|
107
|
+
overlay.css("zIndex", conf.zIndex + 1).fadeIn(conf.fadeInSpeed, function() {
|
|
108
|
+
|
|
109
|
+
if (self.isOpened() && !$(this).index(overlay)) {
|
|
110
|
+
onLoad.call();
|
|
111
|
+
} else {
|
|
112
|
+
overlay.hide();
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
}).css("position", position);
|
|
117
|
+
|
|
118
|
+
};
|
|
119
|
+
//}}}
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
var closeEffect = function(onClose) {
|
|
123
|
+
|
|
124
|
+
// variables
|
|
125
|
+
var overlay = this.getOverlay().hide(),
|
|
126
|
+
conf = this.getConf(),
|
|
127
|
+
trigger = this.getTrigger(),
|
|
128
|
+
img = overlay.data("img"),
|
|
129
|
+
|
|
130
|
+
css = {
|
|
131
|
+
top: conf.start.top,
|
|
132
|
+
left: conf.start.left,
|
|
133
|
+
width: 0
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// trigger position
|
|
137
|
+
if (trigger) { $.extend(css, getPosition(trigger)); }
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
// change from fixed to absolute position
|
|
141
|
+
if (conf.fixed) {
|
|
142
|
+
img.css({position: 'absolute'})
|
|
143
|
+
.animate({ top: "+=" + w.scrollTop(), left: "+=" + w.scrollLeft()}, 0);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// shrink image
|
|
147
|
+
img.animate(css, conf.closeSpeed, onClose);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
// add overlay effect
|
|
152
|
+
t.addEffect("apple", loadEffect, closeEffect);
|
|
153
|
+
|
|
154
|
+
})(jQuery);
|
|
155
|
+
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* jQuery Tools @VERSION Overlay - Overlay base. Extend it.
|
|
4
|
+
*
|
|
5
|
+
* NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
|
|
6
|
+
*
|
|
7
|
+
* http://flowplayer.org/tools/overlay/
|
|
8
|
+
*
|
|
9
|
+
* Since: March 2008
|
|
10
|
+
* Date: @DATE
|
|
11
|
+
*/
|
|
12
|
+
(function($) {
|
|
13
|
+
|
|
14
|
+
// static constructs
|
|
15
|
+
$.tools = $.tools || {version: '@VERSION'};
|
|
16
|
+
|
|
17
|
+
$.tools.overlay = {
|
|
18
|
+
|
|
19
|
+
addEffect: function(name, loadFn, closeFn) {
|
|
20
|
+
effects[name] = [loadFn, closeFn];
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
conf: {
|
|
24
|
+
close: null,
|
|
25
|
+
closeOnClick: true,
|
|
26
|
+
closeOnEsc: true,
|
|
27
|
+
closeSpeed: 'fast',
|
|
28
|
+
effect: 'default',
|
|
29
|
+
|
|
30
|
+
// since 1.2. fixed positioning not supported by IE6
|
|
31
|
+
fixed: !$.browser.msie || $.browser.version > 6,
|
|
32
|
+
|
|
33
|
+
left: 'center',
|
|
34
|
+
load: false, // 1.2
|
|
35
|
+
mask: null,
|
|
36
|
+
oneInstance: true,
|
|
37
|
+
speed: 'normal',
|
|
38
|
+
target: null, // target element to be overlayed. by default taken from [rel]
|
|
39
|
+
top: '10%'
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
var instances = [], effects = {};
|
|
45
|
+
|
|
46
|
+
// the default effect. nice and easy!
|
|
47
|
+
$.tools.overlay.addEffect('default',
|
|
48
|
+
|
|
49
|
+
/*
|
|
50
|
+
onLoad/onClose functions must be called otherwise none of the
|
|
51
|
+
user supplied callback methods won't be called
|
|
52
|
+
*/
|
|
53
|
+
function(pos, onLoad) {
|
|
54
|
+
|
|
55
|
+
var conf = this.getConf(),
|
|
56
|
+
w = $(window);
|
|
57
|
+
|
|
58
|
+
if (!conf.fixed) {
|
|
59
|
+
pos.top += w.scrollTop();
|
|
60
|
+
pos.left += w.scrollLeft();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
pos.position = conf.fixed ? 'fixed' : 'absolute';
|
|
64
|
+
this.getOverlay().css(pos).fadeIn(conf.speed, onLoad);
|
|
65
|
+
|
|
66
|
+
}, function(onClose) {
|
|
67
|
+
this.getOverlay().fadeOut(this.getConf().closeSpeed, onClose);
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
function Overlay(trigger, conf) {
|
|
73
|
+
|
|
74
|
+
// private variables
|
|
75
|
+
var self = this,
|
|
76
|
+
fire = trigger.add(self),
|
|
77
|
+
w = $(window),
|
|
78
|
+
closers,
|
|
79
|
+
overlay,
|
|
80
|
+
opened,
|
|
81
|
+
maskConf = $.tools.expose && (conf.mask || conf.expose),
|
|
82
|
+
uid = Math.random().toString().slice(10);
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
// mask configuration
|
|
86
|
+
if (maskConf) {
|
|
87
|
+
if (typeof maskConf == 'string') { maskConf = {color: maskConf}; }
|
|
88
|
+
maskConf.closeOnClick = maskConf.closeOnEsc = false;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// get overlay and trigger
|
|
92
|
+
var jq = conf.target || trigger.attr("rel");
|
|
93
|
+
overlay = jq ? $(jq) : null || trigger;
|
|
94
|
+
|
|
95
|
+
// overlay not found. cannot continue
|
|
96
|
+
if (!overlay.length) { throw "Could not find Overlay: " + jq; }
|
|
97
|
+
|
|
98
|
+
// trigger's click event
|
|
99
|
+
if (trigger && trigger.index(overlay) == -1) {
|
|
100
|
+
trigger.click(function(e) {
|
|
101
|
+
self.load(e);
|
|
102
|
+
return e.preventDefault();
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// API methods
|
|
107
|
+
$.extend(self, {
|
|
108
|
+
|
|
109
|
+
load: function(e) {
|
|
110
|
+
|
|
111
|
+
// can be opened only once
|
|
112
|
+
if (self.isOpened()) { return self; }
|
|
113
|
+
|
|
114
|
+
// find the effect
|
|
115
|
+
var eff = effects[conf.effect];
|
|
116
|
+
if (!eff) { throw "Overlay: cannot find effect : \"" + conf.effect + "\""; }
|
|
117
|
+
|
|
118
|
+
// close other instances?
|
|
119
|
+
if (conf.oneInstance) {
|
|
120
|
+
$.each(instances, function() {
|
|
121
|
+
this.close(e);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// onBeforeLoad
|
|
126
|
+
e = e || $.Event();
|
|
127
|
+
e.type = "onBeforeLoad";
|
|
128
|
+
fire.trigger(e);
|
|
129
|
+
if (e.isDefaultPrevented()) { return self; }
|
|
130
|
+
|
|
131
|
+
// opened
|
|
132
|
+
opened = true;
|
|
133
|
+
|
|
134
|
+
// possible mask effect
|
|
135
|
+
if (maskConf) { $(overlay).expose(maskConf); }
|
|
136
|
+
|
|
137
|
+
// position & dimensions
|
|
138
|
+
var top = conf.top,
|
|
139
|
+
left = conf.left,
|
|
140
|
+
oWidth = overlay.outerWidth({margin:true}),
|
|
141
|
+
oHeight = overlay.outerHeight({margin:true});
|
|
142
|
+
|
|
143
|
+
if (typeof top == 'string') {
|
|
144
|
+
top = top == 'center' ? Math.max((w.height() - oHeight) / 2, 0) :
|
|
145
|
+
parseInt(top, 10) / 100 * w.height();
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (left == 'center') { left = Math.max((w.width() - oWidth) / 2, 0); }
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
// load effect
|
|
152
|
+
eff[0].call(self, {top: top, left: left}, function() {
|
|
153
|
+
if (opened) {
|
|
154
|
+
e.type = "onLoad";
|
|
155
|
+
fire.trigger(e);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// mask.click closes overlay
|
|
160
|
+
if (maskConf && conf.closeOnClick) {
|
|
161
|
+
$.mask.getMask().one("click", self.close);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// when window is clicked outside overlay, we close
|
|
165
|
+
if (conf.closeOnClick) {
|
|
166
|
+
$(document).bind("click." + uid, function(e) {
|
|
167
|
+
if (!$(e.target).parents(overlay).length) {
|
|
168
|
+
self.close(e);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// keyboard::escape
|
|
174
|
+
if (conf.closeOnEsc) {
|
|
175
|
+
|
|
176
|
+
// one callback is enough if multiple instances are loaded simultaneously
|
|
177
|
+
$(document).bind("keydown." + uid, function(e) {
|
|
178
|
+
if (e.keyCode == 27) {
|
|
179
|
+
self.close(e);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
return self;
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
close: function(e) {
|
|
189
|
+
|
|
190
|
+
if (!self.isOpened()) { return self; }
|
|
191
|
+
|
|
192
|
+
e = e || $.Event();
|
|
193
|
+
e.type = "onBeforeClose";
|
|
194
|
+
fire.trigger(e);
|
|
195
|
+
if (e.isDefaultPrevented()) { return; }
|
|
196
|
+
|
|
197
|
+
opened = false;
|
|
198
|
+
|
|
199
|
+
// close effect
|
|
200
|
+
effects[conf.effect][1].call(self, function() {
|
|
201
|
+
e.type = "onClose";
|
|
202
|
+
fire.trigger(e);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// unbind the keyboard / clicking actions
|
|
206
|
+
$(document).unbind("click." + uid).unbind("keydown." + uid);
|
|
207
|
+
|
|
208
|
+
if (maskConf) {
|
|
209
|
+
$.mask.close();
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return self;
|
|
213
|
+
},
|
|
214
|
+
|
|
215
|
+
getOverlay: function() {
|
|
216
|
+
return overlay;
|
|
217
|
+
},
|
|
218
|
+
|
|
219
|
+
getTrigger: function() {
|
|
220
|
+
return trigger;
|
|
221
|
+
},
|
|
222
|
+
|
|
223
|
+
getClosers: function() {
|
|
224
|
+
return closers;
|
|
225
|
+
},
|
|
226
|
+
|
|
227
|
+
isOpened: function() {
|
|
228
|
+
return opened;
|
|
229
|
+
},
|
|
230
|
+
|
|
231
|
+
// manipulate start, finish and speeds
|
|
232
|
+
getConf: function() {
|
|
233
|
+
return conf;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
// callbacks
|
|
239
|
+
$.each("onBeforeLoad,onStart,onLoad,onBeforeClose,onClose".split(","), function(i, name) {
|
|
240
|
+
|
|
241
|
+
// configuration
|
|
242
|
+
if ($.isFunction(conf[name])) {
|
|
243
|
+
$(self).bind(name, conf[name]);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// API
|
|
247
|
+
self[name] = function(fn) {
|
|
248
|
+
if (fn) { $(self).bind(name, fn); }
|
|
249
|
+
return self;
|
|
250
|
+
};
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
// close button
|
|
254
|
+
closers = overlay.find(conf.close || ".close");
|
|
255
|
+
|
|
256
|
+
if (!closers.length && !conf.close) {
|
|
257
|
+
closers = $('<a class="close"></a>');
|
|
258
|
+
overlay.prepend(closers);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
closers.click(function(e) {
|
|
262
|
+
self.close(e);
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
// autoload
|
|
266
|
+
if (conf.load) { self.load(); }
|
|
267
|
+
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// jQuery plugin initialization
|
|
271
|
+
$.fn.overlay = function(conf) {
|
|
272
|
+
|
|
273
|
+
// already constructed --> return API
|
|
274
|
+
var el = this.data("overlay");
|
|
275
|
+
if (el) { return el; }
|
|
276
|
+
|
|
277
|
+
if ($.isFunction(conf)) {
|
|
278
|
+
conf = {onBeforeLoad: conf};
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
conf = $.extend(true, {}, $.tools.overlay.conf, conf);
|
|
282
|
+
|
|
283
|
+
this.each(function() {
|
|
284
|
+
el = new Overlay($(this), conf);
|
|
285
|
+
instances.push(el);
|
|
286
|
+
$(this).data("overlay", el);
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
return conf.api ? el: this;
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
})(jQuery);
|
|
293
|
+
|
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* jQuery Tools @VERSION Rangeinput - HTML5 <input type="range" /> for humans
|
|
4
|
+
*
|
|
5
|
+
* NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
|
|
6
|
+
*
|
|
7
|
+
* http://flowplayer.org/tools/rangeinput/
|
|
8
|
+
*
|
|
9
|
+
* Since: Mar 2010
|
|
10
|
+
* Date: @DATE
|
|
11
|
+
*/
|
|
12
|
+
(function($) {
|
|
13
|
+
|
|
14
|
+
$.tools = $.tools || {version: '@VERSION'};
|
|
15
|
+
|
|
16
|
+
var tool;
|
|
17
|
+
|
|
18
|
+
tool = $.tools.rangeinput = {
|
|
19
|
+
|
|
20
|
+
conf: {
|
|
21
|
+
min: 0,
|
|
22
|
+
max: 100, // as defined in the standard
|
|
23
|
+
step: 'any', // granularity of the value. a non-zero float or int (or "any")
|
|
24
|
+
steps: 0,
|
|
25
|
+
value: 0,
|
|
26
|
+
precision: undefined,
|
|
27
|
+
vertical: 0,
|
|
28
|
+
keyboard: true,
|
|
29
|
+
progress: false,
|
|
30
|
+
speed: 100,
|
|
31
|
+
|
|
32
|
+
// set to null if not needed
|
|
33
|
+
css: {
|
|
34
|
+
input: 'range',
|
|
35
|
+
slider: 'slider',
|
|
36
|
+
progress: 'progress',
|
|
37
|
+
handle: 'handle'
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
//{{{ fn.drag
|
|
44
|
+
|
|
45
|
+
/*
|
|
46
|
+
FULL featured drag and drop. 0.7 kb minified, 0.3 gzipped. done.
|
|
47
|
+
Who told d'n'd is rocket science? Usage:
|
|
48
|
+
|
|
49
|
+
$(".myelement").drag({y: false}).bind("drag", function(event, x, y) {
|
|
50
|
+
// do your custom thing
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
Configuration:
|
|
54
|
+
x: true, // enable horizontal drag
|
|
55
|
+
y: true, // enable vertical drag
|
|
56
|
+
drag: true // true = perform drag, false = only fire events
|
|
57
|
+
|
|
58
|
+
Events: dragStart, drag, dragEnd.
|
|
59
|
+
*/
|
|
60
|
+
var doc, draggable;
|
|
61
|
+
|
|
62
|
+
$.fn.drag = function(conf) {
|
|
63
|
+
|
|
64
|
+
// disable IE specialities
|
|
65
|
+
document.ondragstart = function () { return false; };
|
|
66
|
+
|
|
67
|
+
conf = $.extend({x: true, y: true, drag: true}, conf);
|
|
68
|
+
|
|
69
|
+
doc = doc || $(document).bind("mousedown mouseup", function(e) {
|
|
70
|
+
|
|
71
|
+
var el = $(e.target);
|
|
72
|
+
|
|
73
|
+
// start
|
|
74
|
+
if (e.type == "mousedown" && el.data("drag")) {
|
|
75
|
+
|
|
76
|
+
var offset = el.position(),
|
|
77
|
+
x0 = e.pageX - offset.left,
|
|
78
|
+
y0 = e.pageY - offset.top,
|
|
79
|
+
start = true;
|
|
80
|
+
|
|
81
|
+
doc.bind("mousemove.drag", function(e) {
|
|
82
|
+
var x = e.pageX -x0,
|
|
83
|
+
y = e.pageY -y0,
|
|
84
|
+
props = {};
|
|
85
|
+
|
|
86
|
+
if (conf.x) { props.left = x; }
|
|
87
|
+
if (conf.y) { props.top = y; }
|
|
88
|
+
|
|
89
|
+
if (start) {
|
|
90
|
+
el.trigger("dragStart");
|
|
91
|
+
start = false;
|
|
92
|
+
}
|
|
93
|
+
if (conf.drag) { el.css(props); }
|
|
94
|
+
el.trigger("drag", [y, x]);
|
|
95
|
+
draggable = el;
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
e.preventDefault();
|
|
99
|
+
|
|
100
|
+
} else {
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
if (draggable) {
|
|
104
|
+
draggable.trigger("dragEnd");
|
|
105
|
+
}
|
|
106
|
+
} finally {
|
|
107
|
+
doc.unbind("mousemove.drag");
|
|
108
|
+
draggable = null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
return this.data("drag", true);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
//}}}
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
function round(value, precision) {
|
|
122
|
+
var n = Math.pow(10, precision);
|
|
123
|
+
return Math.round(value * n) / n;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// get hidden element's width or height even though it's hidden
|
|
127
|
+
function dim(el, key) {
|
|
128
|
+
var v = parseInt(el.css(key), 10);
|
|
129
|
+
if (v) { return v; }
|
|
130
|
+
var s = el[0].currentStyle;
|
|
131
|
+
return s && s.width && parseInt(s.width, 10);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function hasEvent(el) {
|
|
135
|
+
var e = el.data("events");
|
|
136
|
+
return e && e.onSlide;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function RangeInput(input, conf) {
|
|
140
|
+
|
|
141
|
+
// private variables
|
|
142
|
+
var self = this,
|
|
143
|
+
css = conf.css,
|
|
144
|
+
root = $("<div><div/><a href='#'/></div>").data("rangeinput", self),
|
|
145
|
+
vertical,
|
|
146
|
+
value, // current value
|
|
147
|
+
origo, // handle's start point
|
|
148
|
+
len, // length of the range
|
|
149
|
+
pos; // current position of the handle
|
|
150
|
+
|
|
151
|
+
// create range
|
|
152
|
+
input.before(root);
|
|
153
|
+
|
|
154
|
+
var handle = root.addClass(css.slider).find("a").addClass(css.handle),
|
|
155
|
+
progress = root.find("div").addClass(css.progress);
|
|
156
|
+
|
|
157
|
+
// get (HTML5) attributes into configuration
|
|
158
|
+
$.each("min,max,step,value".split(","), function(i, key) {
|
|
159
|
+
var val = input.attr(key);
|
|
160
|
+
if (parseFloat(val)) {
|
|
161
|
+
conf[key] = parseFloat(val, 10);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
var range = conf.max - conf.min,
|
|
166
|
+
step = conf.step == 'any' ? 0 : conf.step,
|
|
167
|
+
precision = conf.precision;
|
|
168
|
+
|
|
169
|
+
if (precision === undefined) {
|
|
170
|
+
try {
|
|
171
|
+
precision = step.toString().split(".")[1].length;
|
|
172
|
+
} catch (err) {
|
|
173
|
+
precision = 0;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Replace built-in range input (type attribute cannot be changed)
|
|
178
|
+
if (input.attr("type") == 'range') {
|
|
179
|
+
var def = input.clone().wrap("<div/>").parent().html(),
|
|
180
|
+
clone = $(def.replace(/type/i, "type=text data-orig-type"));
|
|
181
|
+
|
|
182
|
+
clone.val(conf.value);
|
|
183
|
+
input.replaceWith(clone);
|
|
184
|
+
input = clone;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
input.addClass(css.input);
|
|
188
|
+
|
|
189
|
+
var fire = $(self).add(input), fireOnSlide = true;
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
The flesh and bone of this tool. All sliding is routed trough this.
|
|
194
|
+
|
|
195
|
+
@param evt types include: click, keydown, blur and api (setValue call)
|
|
196
|
+
@param isSetValue when called trough setValue() call (keydown, blur, api)
|
|
197
|
+
|
|
198
|
+
vertical configuration gives additional complexity.
|
|
199
|
+
*/
|
|
200
|
+
function slide(evt, x, val, isSetValue) {
|
|
201
|
+
|
|
202
|
+
// calculate value based on slide position
|
|
203
|
+
if (val === undefined) {
|
|
204
|
+
val = x / len * range;
|
|
205
|
+
|
|
206
|
+
// x is calculated based on val. we need to strip off min during calculation
|
|
207
|
+
} else if (isSetValue) {
|
|
208
|
+
val -= conf.min;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// increment in steps
|
|
212
|
+
if (step) {
|
|
213
|
+
val = Math.round(val / step) * step;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// count x based on value or tweak x if stepping is done
|
|
217
|
+
if (x === undefined || step) {
|
|
218
|
+
x = val * len / range;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// crazy value?
|
|
222
|
+
if (isNaN(val)) { return self; }
|
|
223
|
+
|
|
224
|
+
// stay within range
|
|
225
|
+
x = Math.max(0, Math.min(x, len));
|
|
226
|
+
val = x / len * range;
|
|
227
|
+
|
|
228
|
+
if (isSetValue || !vertical) {
|
|
229
|
+
val += conf.min;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// in vertical ranges value rises upwards
|
|
233
|
+
if (vertical) {
|
|
234
|
+
if (isSetValue) {
|
|
235
|
+
x = len -x;
|
|
236
|
+
} else {
|
|
237
|
+
val = conf.max - val;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// precision
|
|
242
|
+
val = round(val, precision);
|
|
243
|
+
|
|
244
|
+
// onSlide
|
|
245
|
+
var isClick = evt.type == "click";
|
|
246
|
+
if (fireOnSlide && value !== undefined && !isClick) {
|
|
247
|
+
evt.type = "onSlide";
|
|
248
|
+
fire.trigger(evt, [val, x]);
|
|
249
|
+
if (evt.isDefaultPrevented()) { return self; }
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// speed & callback
|
|
253
|
+
var speed = isClick ? conf.speed : 0,
|
|
254
|
+
callback = isClick ? function() {
|
|
255
|
+
evt.type = "change";
|
|
256
|
+
fire.trigger(evt, [val]);
|
|
257
|
+
} : null;
|
|
258
|
+
|
|
259
|
+
if (vertical) {
|
|
260
|
+
handle.animate({top: x}, speed, callback);
|
|
261
|
+
if (conf.progress) {
|
|
262
|
+
progress.animate({height: len - x + handle.height() / 2}, speed);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
} else {
|
|
266
|
+
handle.animate({left: x}, speed, callback);
|
|
267
|
+
if (conf.progress) {
|
|
268
|
+
progress.animate({width: x + handle.width() / 2}, speed);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// store current value
|
|
273
|
+
value = val;
|
|
274
|
+
pos = x;
|
|
275
|
+
|
|
276
|
+
// se input field's value
|
|
277
|
+
input.val(val);
|
|
278
|
+
|
|
279
|
+
return self;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
$.extend(self, {
|
|
284
|
+
|
|
285
|
+
getValue: function() {
|
|
286
|
+
return value;
|
|
287
|
+
},
|
|
288
|
+
|
|
289
|
+
setValue: function(val, e) {
|
|
290
|
+
init();
|
|
291
|
+
return slide(e || $.Event("api"), undefined, val, true);
|
|
292
|
+
},
|
|
293
|
+
|
|
294
|
+
getConf: function() {
|
|
295
|
+
return conf;
|
|
296
|
+
},
|
|
297
|
+
|
|
298
|
+
getProgress: function() {
|
|
299
|
+
return progress;
|
|
300
|
+
},
|
|
301
|
+
|
|
302
|
+
getHandle: function() {
|
|
303
|
+
return handle;
|
|
304
|
+
},
|
|
305
|
+
|
|
306
|
+
getInput: function() {
|
|
307
|
+
return input;
|
|
308
|
+
},
|
|
309
|
+
|
|
310
|
+
step: function(am, e) {
|
|
311
|
+
e = e || $.Event();
|
|
312
|
+
var step = conf.step == 'any' ? 1 : conf.step;
|
|
313
|
+
self.setValue(value + step * (am || 1), e);
|
|
314
|
+
},
|
|
315
|
+
|
|
316
|
+
// HTML5 compatible name
|
|
317
|
+
stepUp: function(am) {
|
|
318
|
+
return self.step(am || 1);
|
|
319
|
+
},
|
|
320
|
+
|
|
321
|
+
// HTML5 compatible name
|
|
322
|
+
stepDown: function(am) {
|
|
323
|
+
return self.step(-am || -1);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
// callbacks
|
|
329
|
+
$.each("onSlide,change".split(","), function(i, name) {
|
|
330
|
+
|
|
331
|
+
// from configuration
|
|
332
|
+
if ($.isFunction(conf[name])) {
|
|
333
|
+
$(self).bind(name, conf[name]);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// API methods
|
|
337
|
+
self[name] = function(fn) {
|
|
338
|
+
if (fn) { $(self).bind(name, fn); }
|
|
339
|
+
return self;
|
|
340
|
+
};
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
// dragging
|
|
345
|
+
handle.drag({drag: false}).bind("dragStart", function() {
|
|
346
|
+
|
|
347
|
+
/* do some pre- calculations for seek() function. improves performance */
|
|
348
|
+
init();
|
|
349
|
+
|
|
350
|
+
// avoid redundant event triggering (= heavy stuff)
|
|
351
|
+
fireOnSlide = hasEvent($(self)) || hasEvent(input);
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
}).bind("drag", function(e, y, x) {
|
|
355
|
+
|
|
356
|
+
if (input.is(":disabled")) { return false; }
|
|
357
|
+
slide(e, vertical ? y : x);
|
|
358
|
+
|
|
359
|
+
}).bind("dragEnd", function(e) {
|
|
360
|
+
if (!e.isDefaultPrevented()) {
|
|
361
|
+
e.type = "change";
|
|
362
|
+
fire.trigger(e, [value]);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
}).click(function(e) {
|
|
366
|
+
return e.preventDefault();
|
|
367
|
+
});
|
|
368
|
+
|
|
369
|
+
// clicking
|
|
370
|
+
root.click(function(e) {
|
|
371
|
+
if (input.is(":disabled") || e.target == handle[0]) {
|
|
372
|
+
return e.preventDefault();
|
|
373
|
+
}
|
|
374
|
+
init();
|
|
375
|
+
var fix = vertical ? handle.height() / 2 : handle.width() / 2;
|
|
376
|
+
slide(e, vertical ? len-origo-fix + e.pageY : e.pageX -origo -fix);
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
if (conf.keyboard) {
|
|
380
|
+
|
|
381
|
+
input.keydown(function(e) {
|
|
382
|
+
|
|
383
|
+
if (input.attr("readonly")) { return; }
|
|
384
|
+
|
|
385
|
+
var key = e.keyCode,
|
|
386
|
+
up = $([75, 76, 38, 33, 39]).index(key) != -1,
|
|
387
|
+
down = $([74, 72, 40, 34, 37]).index(key) != -1;
|
|
388
|
+
|
|
389
|
+
if ((up || down) && !(e.shiftKey || e.altKey || e.ctrlKey)) {
|
|
390
|
+
|
|
391
|
+
// UP: k=75, l=76, up=38, pageup=33, right=39
|
|
392
|
+
if (up) {
|
|
393
|
+
self.step(key == 33 ? 10 : 1, e);
|
|
394
|
+
|
|
395
|
+
// DOWN: j=74, h=72, down=40, pagedown=34, left=37
|
|
396
|
+
} else if (down) {
|
|
397
|
+
self.step(key == 34 ? -10 : -1, e);
|
|
398
|
+
}
|
|
399
|
+
return e.preventDefault();
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
input.blur(function(e) {
|
|
406
|
+
var val = $(this).val();
|
|
407
|
+
if (val !== value) {
|
|
408
|
+
self.setValue(val, e);
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
// HTML5 DOM methods
|
|
414
|
+
$.extend(input[0], { stepUp: self.stepUp, stepDown: self.stepDown});
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
// calculate all dimension related stuff
|
|
418
|
+
function init() {
|
|
419
|
+
vertical = conf.vertical || dim(root, "height") > dim(root, "width");
|
|
420
|
+
|
|
421
|
+
if (vertical) {
|
|
422
|
+
len = dim(root, "height") - dim(handle, "height");
|
|
423
|
+
origo = root.offset().top + len;
|
|
424
|
+
|
|
425
|
+
} else {
|
|
426
|
+
len = dim(root, "width") - dim(handle, "width");
|
|
427
|
+
origo = root.offset().left;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
function begin() {
|
|
432
|
+
init();
|
|
433
|
+
self.setValue(conf.value !== undefined ? conf.value : conf.min);
|
|
434
|
+
}
|
|
435
|
+
begin();
|
|
436
|
+
|
|
437
|
+
// some browsers cannot get dimensions upon initialization
|
|
438
|
+
if (!len) {
|
|
439
|
+
$(window).load(begin);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
$.expr[':'].range = function(el) {
|
|
444
|
+
var type = el.getAttribute("type");
|
|
445
|
+
return type && type == 'range' || !!$(el).filter("input").data("rangeinput");
|
|
446
|
+
};
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
// jQuery plugin implementation
|
|
450
|
+
$.fn.rangeinput = function(conf) {
|
|
451
|
+
|
|
452
|
+
// already installed
|
|
453
|
+
if (this.data("rangeinput")) { return this; }
|
|
454
|
+
|
|
455
|
+
// extend configuration with globals
|
|
456
|
+
conf = $.extend(true, {}, tool.conf, conf);
|
|
457
|
+
|
|
458
|
+
var els;
|
|
459
|
+
|
|
460
|
+
this.each(function() {
|
|
461
|
+
var el = new RangeInput($(this), $.extend(true, {}, conf));
|
|
462
|
+
var input = el.getInput().data("rangeinput", el);
|
|
463
|
+
els = els ? els.add(input) : input;
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
return els ? els : this;
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
}) (jQuery);
|
|
471
|
+
|