##// END OF EJS Templates
Merge pull request #6106 from chronitis/interact-slider-textedit...
Matthias Bussonnier -
r18267:d4de7b72 merge
parent child Browse files
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: function(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: function(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