Show More
@@ -9,6 +9,11 define([ | |||||
9 | var IntTextView = int_widgets.IntTextView; |
|
9 | var IntTextView = int_widgets.IntTextView; | |
10 |
|
10 | |||
11 | var FloatSliderView = IntSliderView.extend({ |
|
11 | var FloatSliderView = IntSliderView.extend({ | |
|
12 | _parse_value: parseFloat, | |||
|
13 | ||||
|
14 | // matches: whitespace?, float, whitespace?, [-:], whitespace?, float | |||
|
15 | _range_regex: /^\s*([+-]?(?:\d*\.?\d+|\d+\.)(?:[eE][+-]?\d+)?)\s*[-:]\s*([+-]?(?:\d*\.?\d+|\d+\.)(?:[eE][+-]?\d+)?)/, | |||
|
16 | ||||
12 | _validate_slide_value: function(x) { |
|
17 | _validate_slide_value: function(x) { | |
13 | // Validate the value of the slider before sending it to the back-end |
|
18 | // Validate the value of the slider before sending it to the back-end | |
14 | // and applying it to the other views on the page. |
|
19 | // and applying it to the other views on the page. | |
@@ -17,10 +22,7 define([ | |||||
17 | }); |
|
22 | }); | |
18 |
|
23 | |||
19 | var FloatTextView = IntTextView.extend({ |
|
24 | var FloatTextView = IntTextView.extend({ | |
20 |
_parse_value: |
|
25 | _parse_value: parseFloat | |
21 | // Parse the value stored in a string. |
|
|||
22 | return parseFloat(value); |
|
|||
23 | }, |
|
|||
24 | }); |
|
26 | }); | |
25 |
|
27 | |||
26 | return { |
|
28 | return { |
@@ -4,8 +4,9 | |||||
4 | define([ |
|
4 | define([ | |
5 | "widgets/js/widget", |
|
5 | "widgets/js/widget", | |
6 | "jqueryui", |
|
6 | "jqueryui", | |
7 | "bootstrap", |
|
7 | "base/js/keyboard", | |
8 | ], function(widget, $){ |
|
8 | "bootstrap" | |
|
9 | ], function(widget, $, keyboard){ | |||
9 |
|
10 | |||
10 | var IntSliderView = widget.DOMWidgetView.extend({ |
|
11 | var IntSliderView = widget.DOMWidgetView.extend({ | |
11 | render : function(){ |
|
12 | render : function(){ | |
@@ -29,6 +30,7 define([ | |||||
29 | this.$readout = $('<div/>') |
|
30 | this.$readout = $('<div/>') | |
30 | .appendTo(this.$el) |
|
31 | .appendTo(this.$el) | |
31 | .addClass('widget-readout') |
|
32 | .addClass('widget-readout') | |
|
33 | .attr('contentEditable', true) | |||
32 | .hide(); |
|
34 | .hide(); | |
33 |
|
35 | |||
34 | this.model.on('change:slider_color', function(sender, value) { |
|
36 | this.model.on('change:slider_color', function(sender, value) { | |
@@ -164,9 +166,84 define([ | |||||
164 |
|
166 | |||
165 | events: { |
|
167 | events: { | |
166 | // Dictionary of events and their handlers. |
|
168 | // Dictionary of events and their handlers. | |
167 | "slide" : "handleSliderChange" |
|
169 | "slide" : "handleSliderChange", | |
|
170 | "blur [contentEditable=true]": "handleTextChange", | |||
|
171 | "keydown [contentEditable=true]": "handleKeyDown" | |||
168 | }, |
|
172 | }, | |
169 |
|
173 | |||
|
174 | handleKeyDown: function(e) { | |||
|
175 | if (e.keyCode == keyboard.keycodes.enter) { | |||
|
176 | e.preventDefault(); | |||
|
177 | this.handleTextChange(); | |||
|
178 | } | |||
|
179 | }, | |||
|
180 | ||||
|
181 | handleTextChange: function() { | |||
|
182 | // this handles the entry of text into the contentEditable label | |||
|
183 | // first, the value is checked if it contains a parseable number | |||
|
184 | // (or pair of numbers, for the _range case) | |||
|
185 | // then it is clamped within the min-max range of the slider | |||
|
186 | // finally, the model is updated if the value is to be changed | |||
|
187 | // | |||
|
188 | // if any of these conditions are not met, the text is reset | |||
|
189 | // | |||
|
190 | // the step size is not enforced | |||
|
191 | ||||
|
192 | var text = this.$readout.text(); | |||
|
193 | var vmin = this.model.get('min'); | |||
|
194 | var vmax = this.model.get('max'); | |||
|
195 | if (this.model.get("_range")) { | |||
|
196 | // range case | |||
|
197 | // ranges can be expressed either "val-val" or "val:val" (+spaces) | |||
|
198 | var match = this._range_regex.exec(text); | |||
|
199 | if (match) { | |||
|
200 | var values = [this._parse_value(match[1]), | |||
|
201 | this._parse_value(match[2])]; | |||
|
202 | // reject input where NaN or lower > upper | |||
|
203 | if (isNaN(values[0]) || | |||
|
204 | isNaN(values[1]) || | |||
|
205 | (values[0] > values[1])) { | |||
|
206 | this.$readout.text(this.model.get('value').join('-')); | |||
|
207 | } else { | |||
|
208 | // clamp to range | |||
|
209 | values = [Math.max(Math.min(values[0], vmax), vmin), | |||
|
210 | Math.max(Math.min(values[1], vmax), vmin)]; | |||
|
211 | ||||
|
212 | if ((values[0] != this.model.get('value')[0]) || | |||
|
213 | (values[1] != this.model.get('value')[1])) { | |||
|
214 | this.$readout.text(values.join('-')); | |||
|
215 | this.model.set('value', values, {updated_view: this}); | |||
|
216 | this.touch(); | |||
|
217 | } else { | |||
|
218 | this.$readout.text(this.model.get('value').join('-')); | |||
|
219 | } | |||
|
220 | } | |||
|
221 | } else { | |||
|
222 | this.$readout.text(this.model.get('value').join('-')); | |||
|
223 | } | |||
|
224 | } else { | |||
|
225 | // single value case | |||
|
226 | var value = this._parse_value(text); | |||
|
227 | if (isNaN(value)) { | |||
|
228 | this.$readout.text(this.model.get('value')); | |||
|
229 | } else { | |||
|
230 | value = Math.max(Math.min(value, vmax), vmin); | |||
|
231 | ||||
|
232 | if (value != this.model.get('value')) { | |||
|
233 | this.$readout.text(value); | |||
|
234 | this.model.set('value', value, {updated_view: this}); | |||
|
235 | this.touch(); | |||
|
236 | } else { | |||
|
237 | this.$readout.text(this.model.get('value')); | |||
|
238 | } | |||
|
239 | } | |||
|
240 | } | |||
|
241 | }, | |||
|
242 | ||||
|
243 | _parse_value: parseInt, | |||
|
244 | ||||
|
245 | _range_regex: /^\s*([+-]?\d+)\s*[-:]\s*([+-]?\d+)/, | |||
|
246 | ||||
170 | handleSliderChange: function(e, ui) { |
|
247 | handleSliderChange: function(e, ui) { | |
171 | // Called when the slider value is changed. |
|
248 | // Called when the slider value is changed. | |
172 |
|
249 | |||
@@ -294,10 +371,7 define([ | |||||
294 | } |
|
371 | } | |
295 | }, |
|
372 | }, | |
296 |
|
373 | |||
297 |
_parse_value: |
|
374 | _parse_value: parseInt | |
298 | // Parse the value stored in a string. |
|
|||
299 | return parseInt(value); |
|
|||
300 | }, |
|
|||
301 | }); |
|
375 | }); | |
302 |
|
376 | |||
303 |
|
377 |
General Comments 0
You need to be logged in to leave comments.
Login now