##// END OF EJS Templates
Merge pull request #6943 from jdfreder/numtextfix...
Min RK -
r18925:68e57a5e merge
parent child Browse files
Show More
@@ -1,455 +1,457 b''
1 // Copyright (c) IPython Development Team.
1 // Copyright (c) IPython Development Team.
2 // Distributed under the terms of the Modified BSD License.
2 // Distributed under the terms of the Modified BSD License.
3
3
4 define([
4 define([
5 "widgets/js/widget",
5 "widgets/js/widget",
6 "jqueryui",
6 "jqueryui",
7 "base/js/keyboard",
7 "base/js/keyboard",
8 "bootstrap"
8 "bootstrap"
9 ], function(widget, $, keyboard){
9 ], function(widget, $, keyboard){
10
10
11 var IntSliderView = widget.DOMWidgetView.extend({
11 var IntSliderView = widget.DOMWidgetView.extend({
12 render : function(){
12 render : function(){
13 // Called when view is rendered.
13 // Called when view is rendered.
14 this.$el
14 this.$el
15 .addClass('widget-hbox widget-slider');
15 .addClass('widget-hbox widget-slider');
16 this.$label = $('<div />')
16 this.$label = $('<div />')
17 .appendTo(this.$el)
17 .appendTo(this.$el)
18 .addClass('widget-label')
18 .addClass('widget-label')
19 .hide();
19 .hide();
20
20
21 this.$slider = $('<div />')
21 this.$slider = $('<div />')
22 .slider({})
22 .slider({})
23 .addClass('slider');
23 .addClass('slider');
24 // Put the slider in a container
24 // Put the slider in a container
25 this.$slider_container = $('<div />')
25 this.$slider_container = $('<div />')
26 .addClass('widget-hslider')
26 .addClass('widget-hslider')
27 .append(this.$slider);
27 .append(this.$slider);
28 this.$el.append(this.$slider_container);
28 this.$el.append(this.$slider_container);
29
29
30 this.$readout = $('<div/>')
30 this.$readout = $('<div/>')
31 .appendTo(this.$el)
31 .appendTo(this.$el)
32 .addClass('widget-readout')
32 .addClass('widget-readout')
33 .attr('contentEditable', true)
33 .attr('contentEditable', true)
34 .hide();
34 .hide();
35
35
36 this.model.on('change:slider_color', function(sender, value) {
36 this.model.on('change:slider_color', function(sender, value) {
37 this.$slider.find('a').css('background', value);
37 this.$slider.find('a').css('background', value);
38 }, this);
38 }, this);
39 this.$slider.find('a').css('background', this.model.get('slider_color'));
39 this.$slider.find('a').css('background', this.model.get('slider_color'));
40
40
41 // Set defaults.
41 // Set defaults.
42 this.update();
42 this.update();
43 },
43 },
44
44
45 update_attr: function(name, value) {
45 update_attr: function(name, value) {
46 // Set a css attr of the widget view.
46 // Set a css attr of the widget view.
47 if (name == 'color') {
47 if (name == 'color') {
48 this.$readout.css(name, value);
48 this.$readout.css(name, value);
49 } else if (name.substring(0, 4) == 'font') {
49 } else if (name.substring(0, 4) == 'font') {
50 this.$readout.css(name, value);
50 this.$readout.css(name, value);
51 } else if (name.substring(0, 6) == 'border') {
51 } else if (name.substring(0, 6) == 'border') {
52 this.$slider.find('a').css(name, value);
52 this.$slider.find('a').css(name, value);
53 this.$slider_container.css(name, value);
53 this.$slider_container.css(name, value);
54 } else if (name == 'width' || name == 'height' || name == 'background') {
54 } else if (name == 'width' || name == 'height' || name == 'background') {
55 this.$slider_container.css(name, value);
55 this.$slider_container.css(name, value);
56 } else {
56 } else {
57 this.$slider.css(name, value);
57 this.$slider.css(name, value);
58 }
58 }
59 },
59 },
60
60
61 update : function(options){
61 update : function(options){
62 // Update the contents of this view
62 // Update the contents of this view
63 //
63 //
64 // Called when the model is changed. The model may have been
64 // Called when the model is changed. The model may have been
65 // changed by another view or by a state update from the back-end.
65 // changed by another view or by a state update from the back-end.
66 if (options === undefined || options.updated_view != this) {
66 if (options === undefined || options.updated_view != this) {
67 // JQuery slider option keys. These keys happen to have a
67 // JQuery slider option keys. These keys happen to have a
68 // one-to-one mapping with the corrosponding keys of the model.
68 // one-to-one mapping with the corrosponding keys of the model.
69 var jquery_slider_keys = ['step', 'disabled'];
69 var jquery_slider_keys = ['step', 'disabled'];
70 var that = this;
70 var that = this;
71 that.$slider.slider({});
71 that.$slider.slider({});
72 _.each(jquery_slider_keys, function(key, i) {
72 _.each(jquery_slider_keys, function(key, i) {
73 var model_value = that.model.get(key);
73 var model_value = that.model.get(key);
74 if (model_value !== undefined) {
74 if (model_value !== undefined) {
75 that.$slider.slider("option", key, model_value);
75 that.$slider.slider("option", key, model_value);
76 }
76 }
77 });
77 });
78
78
79 var max = this.model.get('max');
79 var max = this.model.get('max');
80 var min = this.model.get('min');
80 var min = this.model.get('min');
81 if (min <= max) {
81 if (min <= max) {
82 if (max !== undefined) this.$slider.slider('option', 'max', max);
82 if (max !== undefined) this.$slider.slider('option', 'max', max);
83 if (min !== undefined) this.$slider.slider('option', 'min', min);
83 if (min !== undefined) this.$slider.slider('option', 'min', min);
84 }
84 }
85
85
86 var range_value = this.model.get("_range");
86 var range_value = this.model.get("_range");
87 if (range_value !== undefined) {
87 if (range_value !== undefined) {
88 this.$slider.slider("option", "range", range_value);
88 this.$slider.slider("option", "range", range_value);
89 }
89 }
90
90
91 // WORKAROUND FOR JQUERY SLIDER BUG.
91 // WORKAROUND FOR JQUERY SLIDER BUG.
92 // The horizontal position of the slider handle
92 // The horizontal position of the slider handle
93 // depends on the value of the slider at the time
93 // depends on the value of the slider at the time
94 // of orientation change. Before applying the new
94 // of orientation change. Before applying the new
95 // workaround, we set the value to the minimum to
95 // workaround, we set the value to the minimum to
96 // make sure that the horizontal placement of the
96 // make sure that the horizontal placement of the
97 // handle in the vertical slider is always
97 // handle in the vertical slider is always
98 // consistent.
98 // consistent.
99 var orientation = this.model.get('orientation');
99 var orientation = this.model.get('orientation');
100 var min = this.model.get('min');
100 var min = this.model.get('min');
101 var max = this.model.get('max');
101 var max = this.model.get('max');
102 if (this.model.get('_range')) {
102 if (this.model.get('_range')) {
103 this.$slider.slider('option', 'values', [min, min]);
103 this.$slider.slider('option', 'values', [min, min]);
104 } else {
104 } else {
105 this.$slider.slider('option', 'value', min);
105 this.$slider.slider('option', 'value', min);
106 }
106 }
107 this.$slider.slider('option', 'orientation', orientation);
107 this.$slider.slider('option', 'orientation', orientation);
108 var value = this.model.get('value');
108 var value = this.model.get('value');
109 if (this.model.get('_range')) {
109 if (this.model.get('_range')) {
110 // values for the range case are validated python-side in
110 // values for the range case are validated python-side in
111 // _Bounded{Int,Float}RangeWidget._validate
111 // _Bounded{Int,Float}RangeWidget._validate
112 this.$slider.slider('option', 'values', value);
112 this.$slider.slider('option', 'values', value);
113 this.$readout.text(value.join("-"));
113 this.$readout.text(value.join("-"));
114 } else {
114 } else {
115 if(value > max) {
115 if(value > max) {
116 value = max;
116 value = max;
117 }
117 }
118 else if(value < min){
118 else if(value < min){
119 value = min;
119 value = min;
120 }
120 }
121 this.$slider.slider('option', 'value', value);
121 this.$slider.slider('option', 'value', value);
122 this.$readout.text(value);
122 this.$readout.text(value);
123 }
123 }
124
124
125 if(this.model.get('value')!=value) {
125 if(this.model.get('value')!=value) {
126 this.model.set('value', value, {updated_view: this});
126 this.model.set('value', value, {updated_view: this});
127 this.touch();
127 this.touch();
128 }
128 }
129
129
130 // Use the right CSS classes for vertical & horizontal sliders
130 // Use the right CSS classes for vertical & horizontal sliders
131 if (orientation=='vertical') {
131 if (orientation=='vertical') {
132 this.$slider_container
132 this.$slider_container
133 .removeClass('widget-hslider')
133 .removeClass('widget-hslider')
134 .addClass('widget-vslider');
134 .addClass('widget-vslider');
135 this.$el
135 this.$el
136 .removeClass('widget-hbox')
136 .removeClass('widget-hbox')
137 .addClass('widget-vbox');
137 .addClass('widget-vbox');
138
138
139 } else {
139 } else {
140 this.$slider_container
140 this.$slider_container
141 .removeClass('widget-vslider')
141 .removeClass('widget-vslider')
142 .addClass('widget-hslider');
142 .addClass('widget-hslider');
143 this.$el
143 this.$el
144 .removeClass('widget-vbox')
144 .removeClass('widget-vbox')
145 .addClass('widget-hbox');
145 .addClass('widget-hbox');
146 }
146 }
147
147
148 var description = this.model.get('description');
148 var description = this.model.get('description');
149 if (description.length === 0) {
149 if (description.length === 0) {
150 this.$label.hide();
150 this.$label.hide();
151 } else {
151 } else {
152 this.$label.text(description);
152 this.$label.text(description);
153 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
153 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
154 this.$label.show();
154 this.$label.show();
155 }
155 }
156
156
157 var readout = this.model.get('readout');
157 var readout = this.model.get('readout');
158 if (readout) {
158 if (readout) {
159 this.$readout.show();
159 this.$readout.show();
160 } else {
160 } else {
161 this.$readout.hide();
161 this.$readout.hide();
162 }
162 }
163 }
163 }
164 return IntSliderView.__super__.update.apply(this);
164 return IntSliderView.__super__.update.apply(this);
165 },
165 },
166
166
167 events: {
167 events: {
168 // Dictionary of events and their handlers.
168 // Dictionary of events and their handlers.
169 "slide" : "handleSliderChange",
169 "slide" : "handleSliderChange",
170 "blur [contentEditable=true]": "handleTextChange",
170 "blur [contentEditable=true]": "handleTextChange",
171 "keydown [contentEditable=true]": "handleKeyDown"
171 "keydown [contentEditable=true]": "handleKeyDown"
172 },
172 },
173
173
174 handleKeyDown: function(e) {
174 handleKeyDown: function(e) {
175 if (e.keyCode == keyboard.keycodes.enter) {
175 if (e.keyCode == keyboard.keycodes.enter) {
176 e.preventDefault();
176 e.preventDefault();
177 this.handleTextChange();
177 this.handleTextChange();
178 }
178 }
179 },
179 },
180
180
181 handleTextChange: function() {
181 handleTextChange: function() {
182 // this handles the entry of text into the contentEditable label
182 // this handles the entry of text into the contentEditable label
183 // first, the value is checked if it contains a parseable number
183 // first, the value is checked if it contains a parseable number
184 // (or pair of numbers, for the _range case)
184 // (or pair of numbers, for the _range case)
185 // then it is clamped within the min-max range of the slider
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
186 // finally, the model is updated if the value is to be changed
187 //
187 //
188 // if any of these conditions are not met, the text is reset
188 // if any of these conditions are not met, the text is reset
189 //
189 //
190 // the step size is not enforced
190 // the step size is not enforced
191
191
192 var text = this.$readout.text();
192 var text = this.$readout.text();
193 var vmin = this.model.get('min');
193 var vmin = this.model.get('min');
194 var vmax = this.model.get('max');
194 var vmax = this.model.get('max');
195 if (this.model.get("_range")) {
195 if (this.model.get("_range")) {
196 // range case
196 // range case
197 // ranges can be expressed either "val-val" or "val:val" (+spaces)
197 // ranges can be expressed either "val-val" or "val:val" (+spaces)
198 var match = this._range_regex.exec(text);
198 var match = this._range_regex.exec(text);
199 if (match) {
199 if (match) {
200 var values = [this._parse_value(match[1]),
200 var values = [this._parse_value(match[1]),
201 this._parse_value(match[2])];
201 this._parse_value(match[2])];
202 // reject input where NaN or lower > upper
202 // reject input where NaN or lower > upper
203 if (isNaN(values[0]) ||
203 if (isNaN(values[0]) ||
204 isNaN(values[1]) ||
204 isNaN(values[1]) ||
205 (values[0] > values[1])) {
205 (values[0] > values[1])) {
206 this.$readout.text(this.model.get('value').join('-'));
206 this.$readout.text(this.model.get('value').join('-'));
207 } else {
207 } else {
208 // clamp to range
208 // clamp to range
209 values = [Math.max(Math.min(values[0], vmax), vmin),
209 values = [Math.max(Math.min(values[0], vmax), vmin),
210 Math.max(Math.min(values[1], vmax), vmin)];
210 Math.max(Math.min(values[1], vmax), vmin)];
211
211
212 if ((values[0] != this.model.get('value')[0]) ||
212 if ((values[0] != this.model.get('value')[0]) ||
213 (values[1] != this.model.get('value')[1])) {
213 (values[1] != this.model.get('value')[1])) {
214 this.$readout.text(values.join('-'));
214 this.$readout.text(values.join('-'));
215 this.model.set('value', values, {updated_view: this});
215 this.model.set('value', values, {updated_view: this});
216 this.touch();
216 this.touch();
217 } else {
217 } else {
218 this.$readout.text(this.model.get('value').join('-'));
218 this.$readout.text(this.model.get('value').join('-'));
219 }
219 }
220 }
220 }
221 } else {
221 } else {
222 this.$readout.text(this.model.get('value').join('-'));
222 this.$readout.text(this.model.get('value').join('-'));
223 }
223 }
224 } else {
224 } else {
225 // single value case
225 // single value case
226 var value = this._parse_value(text);
226 var value = this._parse_value(text);
227 if (isNaN(value)) {
227 if (isNaN(value)) {
228 this.$readout.text(this.model.get('value'));
228 this.$readout.text(this.model.get('value'));
229 } else {
229 } else {
230 value = Math.max(Math.min(value, vmax), vmin);
230 value = Math.max(Math.min(value, vmax), vmin);
231
231
232 if (value != this.model.get('value')) {
232 if (value != this.model.get('value')) {
233 this.$readout.text(value);
233 this.$readout.text(value);
234 this.model.set('value', value, {updated_view: this});
234 this.model.set('value', value, {updated_view: this});
235 this.touch();
235 this.touch();
236 } else {
236 } else {
237 this.$readout.text(this.model.get('value'));
237 this.$readout.text(this.model.get('value'));
238 }
238 }
239 }
239 }
240 }
240 }
241 },
241 },
242
242
243 _parse_value: parseInt,
243 _parse_value: parseInt,
244
244
245 _range_regex: /^\s*([+-]?\d+)\s*[-:]\s*([+-]?\d+)/,
245 _range_regex: /^\s*([+-]?\d+)\s*[-:]\s*([+-]?\d+)/,
246
246
247 handleSliderChange: function(e, ui) {
247 handleSliderChange: function(e, ui) {
248 // Called when the slider value is changed.
248 // Called when the slider value is changed.
249
249
250 // Calling model.set will trigger all of the other views of the
250 // Calling model.set will trigger all of the other views of the
251 // model to update.
251 // model to update.
252 if (this.model.get("_range")) {
252 if (this.model.get("_range")) {
253 var actual_value = ui.values.map(this._validate_slide_value);
253 var actual_value = ui.values.map(this._validate_slide_value);
254 this.$readout.text(actual_value.join("-"));
254 this.$readout.text(actual_value.join("-"));
255 } else {
255 } else {
256 var actual_value = this._validate_slide_value(ui.value);
256 var actual_value = this._validate_slide_value(ui.value);
257 this.$readout.text(actual_value);
257 this.$readout.text(actual_value);
258 }
258 }
259 this.model.set('value', actual_value, {updated_view: this});
259 this.model.set('value', actual_value, {updated_view: this});
260 this.touch();
260 this.touch();
261 },
261 },
262
262
263 _validate_slide_value: function(x) {
263 _validate_slide_value: function(x) {
264 // Validate the value of the slider before sending it to the back-end
264 // Validate the value of the slider before sending it to the back-end
265 // and applying it to the other views on the page.
265 // and applying it to the other views on the page.
266
266
267 // Double bit-wise not truncates the decimel (int cast).
267 // Double bit-wise not truncates the decimel (int cast).
268 return ~~x;
268 return ~~x;
269 },
269 },
270 });
270 });
271
271
272
272
273 var IntTextView = widget.DOMWidgetView.extend({
273 var IntTextView = widget.DOMWidgetView.extend({
274 render : function(){
274 render : function(){
275 // Called when view is rendered.
275 // Called when view is rendered.
276 this.$el
276 this.$el
277 .addClass('widget-hbox widget-text');
277 .addClass('widget-hbox widget-text');
278 this.$label = $('<div />')
278 this.$label = $('<div />')
279 .appendTo(this.$el)
279 .appendTo(this.$el)
280 .addClass('widget-label')
280 .addClass('widget-label')
281 .hide();
281 .hide();
282 this.$textbox = $('<input type="text" />')
282 this.$textbox = $('<input type="text" />')
283 .addClass('form-control')
283 .addClass('form-control')
284 .addClass('widget-numeric-text')
284 .addClass('widget-numeric-text')
285 .appendTo(this.$el);
285 .appendTo(this.$el);
286 this.update(); // Set defaults.
286 this.update(); // Set defaults.
287 },
287 },
288
288
289 update : function(options){
289 update : function(options){
290 // Update the contents of this view
290 // Update the contents of this view
291 //
291 //
292 // Called when the model is changed. The model may have been
292 // Called when the model is changed. The model may have been
293 // changed by another view or by a state update from the back-end.
293 // changed by another view or by a state update from the back-end.
294 if (options === undefined || options.updated_view != this) {
294 if (options === undefined || options.updated_view != this) {
295 var value = this.model.get('value');
295 var value = this.model.get('value');
296 if (this._parse_value(this.$textbox.val()) != value) {
296 if (this._parse_value(this.$textbox.val()) != value) {
297 this.$textbox.val(value);
297 this.$textbox.val(value);
298 }
298 }
299
299
300 if (this.model.get('disabled')) {
300 if (this.model.get('disabled')) {
301 this.$textbox.attr('disabled','disabled');
301 this.$textbox.attr('disabled','disabled');
302 } else {
302 } else {
303 this.$textbox.removeAttr('disabled');
303 this.$textbox.removeAttr('disabled');
304 }
304 }
305
305
306 var description = this.model.get('description');
306 var description = this.model.get('description');
307 if (description.length === 0) {
307 if (description.length === 0) {
308 this.$label.hide();
308 this.$label.hide();
309 } else {
309 } else {
310 this.$label.text(description);
310 this.$label.text(description);
311 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
311 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
312 this.$label.show();
312 this.$label.show();
313 }
313 }
314 }
314 }
315 return IntTextView.__super__.update.apply(this);
315 return IntTextView.__super__.update.apply(this);
316 },
316 },
317
317
318 update_attr: function(name, value) {
318 update_attr: function(name, value) {
319 // Set a css attr of the widget view.
319 // Set a css attr of the widget view.
320 this.$textbox.css(name, value);
320 this.$textbox.css(name, value);
321 },
321 },
322
322
323 events: {
323 events: {
324 // Dictionary of events and their handlers.
324 // Dictionary of events and their handlers.
325 "keyup input" : "handleChanging",
325 "keyup input" : "handleChanging",
326 "paste input" : "handleChanging",
326 "paste input" : "handleChanging",
327 "cut input" : "handleChanging",
327 "cut input" : "handleChanging",
328
328
329 // Fires only when control is validated or looses focus.
329 // Fires only when control is validated or looses focus.
330 "change input" : "handleChanged"
330 "change input" : "handleChanged"
331 },
331 },
332
332
333 handleChanging: function(e) {
333 handleChanging: function(e) {
334 // Handles and validates user input.
334 // Handles and validates user input.
335
335
336 // Try to parse value as a int.
336 // Try to parse value as a int.
337 var numericalValue = 0;
337 var numericalValue = 0;
338 if (e.target.value !== '') {
338 var trimmed = e.target.value.trim();
339 var trimmed = e.target.value.trim();
339 if (trimmed === '') {
340 return;
341 } else {
340 if (!(['-', '-.', '.', '+.', '+'].indexOf(trimmed) >= 0)) {
342 if (!(['-', '-.', '.', '+.', '+'].indexOf(trimmed) >= 0)) {
341 numericalValue = this._parse_value(e.target.value);
343 numericalValue = this._parse_value(e.target.value);
342 }
344 }
343 }
345 }
344
346
345 // If parse failed, reset value to value stored in model.
347 // If parse failed, reset value to value stored in model.
346 if (isNaN(numericalValue)) {
348 if (isNaN(numericalValue)) {
347 e.target.value = this.model.get('value');
349 e.target.value = this.model.get('value');
348 } else if (!isNaN(numericalValue)) {
350 } else if (!isNaN(numericalValue)) {
349 if (this.model.get('max') !== undefined) {
351 if (this.model.get('max') !== undefined) {
350 numericalValue = Math.min(this.model.get('max'), numericalValue);
352 numericalValue = Math.min(this.model.get('max'), numericalValue);
351 }
353 }
352 if (this.model.get('min') !== undefined) {
354 if (this.model.get('min') !== undefined) {
353 numericalValue = Math.max(this.model.get('min'), numericalValue);
355 numericalValue = Math.max(this.model.get('min'), numericalValue);
354 }
356 }
355
357
356 // Apply the value if it has changed.
358 // Apply the value if it has changed.
357 if (numericalValue != this.model.get('value')) {
359 if (numericalValue != this.model.get('value')) {
358
360
359 // Calling model.set will trigger all of the other views of the
361 // Calling model.set will trigger all of the other views of the
360 // model to update.
362 // model to update.
361 this.model.set('value', numericalValue, {updated_view: this});
363 this.model.set('value', numericalValue, {updated_view: this});
362 this.touch();
364 this.touch();
363 }
365 }
364 }
366 }
365 },
367 },
366
368
367 handleChanged: function(e) {
369 handleChanged: function(e) {
368 // Applies validated input.
370 // Applies validated input.
369 if (this.model.get('value') != e.target.value) {
371 if (e.target.value.trim() === '' || e.target.value !== this.model.get('value')) {
370 e.target.value = this.model.get('value');
372 e.target.value = this.model.get('value');
371 }
373 }
372 },
374 },
373
375
374 _parse_value: parseInt
376 _parse_value: parseInt
375 });
377 });
376
378
377
379
378 var ProgressView = widget.DOMWidgetView.extend({
380 var ProgressView = widget.DOMWidgetView.extend({
379 render : function(){
381 render : function(){
380 // Called when view is rendered.
382 // Called when view is rendered.
381 this.$el
383 this.$el
382 .addClass('widget-hbox widget-progress');
384 .addClass('widget-hbox widget-progress');
383 this.$label = $('<div />')
385 this.$label = $('<div />')
384 .appendTo(this.$el)
386 .appendTo(this.$el)
385 .addClass('widget-label')
387 .addClass('widget-label')
386 .hide();
388 .hide();
387 this.$progress = $('<div />')
389 this.$progress = $('<div />')
388 .addClass('progress')
390 .addClass('progress')
389 .addClass('widget-progress')
391 .addClass('widget-progress')
390 .appendTo(this.$el);
392 .appendTo(this.$el);
391 this.$bar = $('<div />')
393 this.$bar = $('<div />')
392 .addClass('progress-bar')
394 .addClass('progress-bar')
393 .css('width', '50%')
395 .css('width', '50%')
394 .appendTo(this.$progress);
396 .appendTo(this.$progress);
395 this.update(); // Set defaults.
397 this.update(); // Set defaults.
396
398
397 this.model.on('change:bar_style', function(model, value) {
399 this.model.on('change:bar_style', function(model, value) {
398 this.update_bar_style();
400 this.update_bar_style();
399 }, this);
401 }, this);
400 this.update_bar_style('');
402 this.update_bar_style('');
401 },
403 },
402
404
403 update : function(){
405 update : function(){
404 // Update the contents of this view
406 // Update the contents of this view
405 //
407 //
406 // Called when the model is changed. The model may have been
408 // Called when the model is changed. The model may have been
407 // changed by another view or by a state update from the back-end.
409 // changed by another view or by a state update from the back-end.
408 var value = this.model.get('value');
410 var value = this.model.get('value');
409 var max = this.model.get('max');
411 var max = this.model.get('max');
410 var min = this.model.get('min');
412 var min = this.model.get('min');
411 var percent = 100.0 * (value - min) / (max - min);
413 var percent = 100.0 * (value - min) / (max - min);
412 this.$bar.css('width', percent + '%');
414 this.$bar.css('width', percent + '%');
413
415
414 var description = this.model.get('description');
416 var description = this.model.get('description');
415 if (description.length === 0) {
417 if (description.length === 0) {
416 this.$label.hide();
418 this.$label.hide();
417 } else {
419 } else {
418 this.$label.text(description);
420 this.$label.text(description);
419 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
421 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
420 this.$label.show();
422 this.$label.show();
421 }
423 }
422 return ProgressView.__super__.update.apply(this);
424 return ProgressView.__super__.update.apply(this);
423 },
425 },
424
426
425 update_bar_style: function(previous_trait_value) {
427 update_bar_style: function(previous_trait_value) {
426 var class_map = {
428 var class_map = {
427 success: ['progress-bar-success'],
429 success: ['progress-bar-success'],
428 info: ['progress-bar-info'],
430 info: ['progress-bar-info'],
429 warning: ['progress-bar-warning'],
431 warning: ['progress-bar-warning'],
430 danger: ['progress-bar-danger']
432 danger: ['progress-bar-danger']
431 };
433 };
432 this.update_mapped_classes(class_map, 'bar_style', previous_trait_value, this.$bar);
434 this.update_mapped_classes(class_map, 'bar_style', previous_trait_value, this.$bar);
433 },
435 },
434
436
435 update_attr: function(name, value) {
437 update_attr: function(name, value) {
436 // Set a css attr of the widget view.
438 // Set a css attr of the widget view.
437 if (name.substring(0, 6) == 'border' || name == 'width' ||
439 if (name.substring(0, 6) == 'border' || name == 'width' ||
438 name == 'height' || name == 'background' || name == 'margin' ||
440 name == 'height' || name == 'background' || name == 'margin' ||
439 name == 'padding') {
441 name == 'padding') {
440
442
441 this.$progress.css(name, value);
443 this.$progress.css(name, value);
442 } else if (name == 'color') {
444 } else if (name == 'color') {
443 this.$bar.css('background', value);
445 this.$bar.css('background', value);
444 } else {
446 } else {
445 this.$bar.css(name, value);
447 this.$bar.css(name, value);
446 }
448 }
447 },
449 },
448 });
450 });
449
451
450 return {
452 return {
451 'IntSliderView': IntSliderView,
453 'IntSliderView': IntSliderView,
452 'IntTextView': IntTextView,
454 'IntTextView': IntTextView,
453 'ProgressView': ProgressView,
455 'ProgressView': ProgressView,
454 };
456 };
455 });
457 });
General Comments 0
You need to be logged in to leave comments. Login now