Mercurial > hg > digilib-old
annotate webapp/src/main/webapp/jquery/jquery.range.js @ 1061:4f5c5c578aa4
rgb slider: color indicator functional, reset works only partially
author | hertzhaft |
---|---|
date | Sat, 31 Mar 2012 22:34:50 +0200 |
parents | 4f17420392a9 |
children |
rev | line source |
---|---|
1030 | 1 /* |
2 * jQuery.range - A tiny, easily styleable range selector | |
3 * Tom Moor, http://tommoor.com | |
4 * Copyright (c) 2011 Tom Moor | |
5 * MIT Licensed | |
6 * @version 1.0 | |
7 */ | |
8 | |
1061
4f5c5c578aa4
rgb slider: color indicator functional, reset works only partially
hertzhaft
parents:
1047
diff
changeset
|
9 /* |
4f5c5c578aa4
rgb slider: color indicator functional, reset works only partially
hertzhaft
parents:
1047
diff
changeset
|
10 * minor bug fixes (c) 2012 Martin Raspe (hertzhaft@biblhertz.it) |
4f5c5c578aa4
rgb slider: color indicator functional, reset works only partially
hertzhaft
parents:
1047
diff
changeset
|
11 */ |
4f5c5c578aa4
rgb slider: color indicator functional, reset works only partially
hertzhaft
parents:
1047
diff
changeset
|
12 |
1030 | 13 (function($){ |
14 | |
15 var TinyRange = function(){ | |
16 // locals | |
17 var options; | |
18 var $input; | |
19 var $rail; | |
20 var $handle; | |
21 var $handle2; | |
22 var $selection; | |
23 var $dragging; | |
24 var $original; | |
25 var jump; | |
26 var size; | |
27 var defaults = { | |
28 orientation: 'horizontal', // todo | |
29 range: false, | |
30 values: false, | |
31 snap: false, | |
32 change: null, | |
33 blur: null | |
34 }; | |
35 | |
36 var jumpHandle = function(ev) { | |
37 ev.pageX = ev.pageX - $input.offset().left; | |
38 | |
39 // get closest handle | |
40 var x1 = $handle.position().left; | |
41 var dist = ev.pageX - x1; | |
42 | |
43 if($handle2){ | |
44 var x2 = $handle2.position().left; | |
45 var dist2 = ev.pageX - x2; | |
46 } | |
47 | |
48 // move towards click | |
49 if(!$handle2 || Math.abs(dist) < Math.abs(dist2) ){ | |
50 if(dist > 0) moveHandle($handle, valueToPx(jump)+x1); | |
51 if(dist < 0) moveHandle($handle, -valueToPx(jump)+x1); | |
52 } else { | |
53 if(dist2 > 0) moveHandle($handle2, valueToPx(jump)+x2); | |
54 if(dist2 < 0) moveHandle($handle2, -valueToPx(jump)+x2); | |
55 } | |
56 } | |
57 | |
58 var moveHandle = function($h, p, update){ | |
59 | |
60 var boundR = $input.width()-size; | |
61 var boundL = 0; | |
62 | |
63 if(options.range){ | |
64 if($h[0] === $handle[0]){ | |
65 boundR = $handle2.position().left; | |
66 } else { | |
67 boundL = $handle.position().left; | |
68 } | |
69 } | |
70 | |
71 if(p >= boundR){ | |
72 p = boundR; | |
73 } else if(p <= boundL){ | |
74 p = boundL; | |
75 } | |
76 | |
1043 | 77 // leads to erratic behaviour with "step" attribute |
78 // if(options.snap && p !== boundR){ | |
79 // var snapPx = valueToPx(options.snap); | |
80 // p = Math.round(p/snapPx) * snapPx; | |
81 // } | |
1030 | 82 |
83 $h.css({'left': p, 'position': 'absolute'}); | |
84 if(options.range) updateSelection(); | |
85 if(update !== false) updateValues(); | |
86 } | |
87 | |
88 var dragStart = function(ev){ | |
89 ev.stopPropagation(); | |
90 ev.preventDefault(); | |
91 | |
92 $dragging = $(this); | |
93 }; | |
94 | |
95 var drag = function(ev){ | |
96 | |
97 if($dragging){ | |
98 ev.preventDefault(); | |
99 var pos = ev.pageX - $input.offset().left; | |
100 | |
101 moveHandle($dragging, pos); | |
102 } | |
103 }; | |
104 | |
105 var updateSelection = function(){ | |
106 | |
107 var p = $handle.position().left; | |
108 var w = $handle2.position().left-p; | |
109 $selection.css({ | |
110 'left': p, | |
111 'width': w, | |
112 'position': 'absolute' | |
113 }); | |
114 }; | |
115 | |
116 var dragEnd = function(ev){ | |
117 if($dragging){ | |
118 $dragging = null; | |
119 if (options.blur == null) { | |
120 // send original blur event | |
121 $original.blur(); | |
122 } else { | |
123 options.blur(options.values); | |
124 } | |
125 } | |
126 }; | |
127 | |
128 var updateValues = function(){ | |
129 | |
130 var prev; | |
131 if(options.range){ | |
132 | |
133 prev = options.values.slice(); // clone | |
1047
4f17420392a9
factor out calibration/scalemode to new dialogs plugin
hertzhaft
parents:
1046
diff
changeset
|
134 options.values[0] = bound(pxToValue($handle.position().left)); |
4f17420392a9
factor out calibration/scalemode to new dialogs plugin
hertzhaft
parents:
1046
diff
changeset
|
135 options.values[1] = bound(pxToValue($handle2.position().left)); |
1030 | 136 |
137 // set value on original element | |
138 $original.val(options.values[0] +','+options.values[1]); | |
139 } else { | |
140 | |
141 prev = options.values; | |
1047
4f17420392a9
factor out calibration/scalemode to new dialogs plugin
hertzhaft
parents:
1046
diff
changeset
|
142 options.values = bound(pxToValue($handle.position().left)); |
1030 | 143 |
144 // set value on original element | |
145 $original.val(options.values); | |
146 } | |
147 | |
148 if(options.values !== prev) { | |
149 if (options.change == null) { | |
150 // trigger original change event | |
151 $original.change(); | |
152 } else { | |
153 options.change(options.values); | |
154 } | |
155 } | |
156 }; | |
157 | |
158 var updateHandles = function(){ | |
159 | |
1040 | 160 if (options.values != null) { |
1030 | 161 if (options.range){ |
162 moveHandle($handle2, valueToPx(options.values[1]), false); | |
163 moveHandle($handle, valueToPx(options.values[0]), false); | |
164 } else { | |
165 moveHandle($handle, valueToPx(options.values), false); | |
166 } | |
167 } | |
168 | |
169 updateValues(); | |
170 }; | |
171 | |
1046 | 172 var pxToValue = function (px) { |
173 var w = $input.width() - size; | |
174 var valspan = options.max - options.min; | |
175 var v = px * valspan / w + options.min; | |
176 if (options.snap) { | |
1047
4f17420392a9
factor out calibration/scalemode to new dialogs plugin
hertzhaft
parents:
1046
diff
changeset
|
177 var tmp = v < 0 |
4f17420392a9
factor out calibration/scalemode to new dialogs plugin
hertzhaft
parents:
1046
diff
changeset
|
178 ? Math.floor(v / options.snap) * options.snap |
4f17420392a9
factor out calibration/scalemode to new dialogs plugin
hertzhaft
parents:
1046
diff
changeset
|
179 : Math.round(v / options.snap) * options.snap; |
1046 | 180 // hack to cut off floating point imprecision |
181 var result = parseFloat(tmp.toFixed(4)); | |
182 return result; | |
1043 | 183 } |
1030 | 184 return Math.round(v); |
185 }; | |
1046 | 186 |
187 var valueToPx = function (val) { | |
188 var w = $input.width() - size; | |
1040 | 189 var valspan = options.max - options.min; |
190 var valpos = val - options.min; | |
191 var v = valpos * w / valspan; | |
1030 | 192 return v; |
193 }; | |
1046 | 194 |
1030 | 195 var bound = function(input){ |
196 return Math.max(Math.min(input, options.max), options.min); | |
197 }; | |
1046 | 198 |
1030 | 199 var methods = { |
1046 | 200 init : function (o) { |
1030 | 201 // element already replaced |
202 if($(this).data('TinyRange')) return this; | |
203 // options | |
204 defaults.min = parseFloat($(this).attr('min')); | |
205 defaults.max = parseFloat($(this).attr('max')); | |
206 defaults.snap = parseFloat($(this).attr('step')); | |
207 | |
208 // options passed into plugin override input attributes | |
209 options = $.extend(defaults, o); | |
1046 | 210 |
1030 | 211 if(options.values){ |
212 // | |
213 } else if(options.range){ | |
214 options.values = [0, options.max]; | |
215 } else { | |
216 options.values = parseFloat($(this).attr('value')); | |
217 } | |
218 // how far do handles jump on click, default to step value | |
219 jump = options.snap ? options.snap : options.max/10; | |
220 // create dom elements | |
221 $input = $('<div/>', {'class': 'range-input'}).mousedown(jumpHandle); | |
222 $rail = $('<div/>', {'class': 'range-rail'}).appendTo($input); | |
223 if(options.range) $selection = $('<div/>', {'class': 'range-selection'}).appendTo($input); | |
224 $handle = $('<a/>', {'class': 'range-handle'}).appendTo($input).mousedown(dragStart); | |
225 if(options.range) $handle2 = $handle.clone(true).appendTo($input); | |
226 // replace dom element | |
227 $(this).after($input); | |
228 $(this).hide(); | |
229 $original = $(this); | |
230 // attach events | |
231 $(document).bind('mouseup', dragEnd); | |
232 $(document).bind('mousemove', drag); | |
233 // position handles | |
234 size = $handle.width(); | |
235 updateHandles(); | |
236 return this; | |
237 }, | |
1046 | 238 |
1030 | 239 set: function(input){ |
240 | |
241 if(typeof input === 'string'){ | |
242 options.values = bound(input); | |
243 } else if(typeof input === 'object' && input.length === 2){ | |
244 options.values[0] = bound(input[0]); | |
245 options.values[1] = bound(input[1]); | |
246 } | |
247 updateHandles(); | |
248 }, | |
1046 | 249 |
1030 | 250 destroy : function(){ |
251 $input.remove(); | |
252 $(this).show().data('TinyRange', false); | |
253 $(document).unbind('mouseup', dragEnd); | |
254 $(document).unbind('mousemove', drag); | |
255 return this; | |
256 } | |
257 }; | |
258 | |
259 return methods; | |
260 }; | |
261 | |
262 $.fn.range = function(method) { | |
263 | |
264 // so that arguments are accessible within each closure | |
265 var args = arguments; | |
266 | |
267 return this.each(function(){ | |
268 var state = $(this).data('TinyRange'); | |
269 | |
270 // Method calling logic | |
271 if (state && state[method] ) { | |
272 state[ method ].apply( this, Array.prototype.slice.call( args, 1 )); | |
273 } else if ( typeof method === 'object' || ! method ) { | |
274 | |
275 // create new tinyrange | |
276 var tr = (new TinyRange(this)); | |
277 tr.init.apply( this, args ); | |
278 | |
279 // save state in jquery data | |
280 $(this).data('TinyRange', tr); | |
281 | |
282 } else { | |
283 $.error( 'Method ' + method + ' does not exist on jQuery.range' ); | |
284 } | |
285 }); | |
286 }; | |
287 })(jQuery); |