##// END OF EJS Templates
adressed @jdfrederer's concern!
Tarun Gaba -
Show More
@@ -1,310 +1,315
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 "components/bootstrap/js/bootstrap.min",
7 "components/bootstrap/js/bootstrap.min",
8 ], function(widget, $){
8 ], function(widget, $){
9
9
10 var IntSliderView = widget.DOMWidgetView.extend({
10 var IntSliderView = widget.DOMWidgetView.extend({
11 render : function(){
11 render : function(){
12 // Called when view is rendered.
12 // Called when view is rendered.
13 this.$el
13 this.$el
14 .addClass('widget-hbox-single');
14 .addClass('widget-hbox-single');
15 this.$label = $('<div />')
15 this.$label = $('<div />')
16 .appendTo(this.$el)
16 .appendTo(this.$el)
17 .addClass('widget-hlabel')
17 .addClass('widget-hlabel')
18 .hide();
18 .hide();
19
19
20 this.$slider = $('<div />')
20 this.$slider = $('<div />')
21 .slider({})
21 .slider({})
22 .addClass('slider');
22 .addClass('slider');
23 // Put the slider in a container
23 // Put the slider in a container
24 this.$slider_container = $('<div />')
24 this.$slider_container = $('<div />')
25 .addClass('widget-hslider')
25 .addClass('widget-hslider')
26 .append(this.$slider);
26 .append(this.$slider);
27 this.$el_to_style = this.$slider_container; // Set default element to style
27 this.$el_to_style = this.$slider_container; // Set default element to style
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-hreadout')
32 .addClass('widget-hreadout')
33 .hide();
33 .hide();
34
34
35 // Set defaults.
35 // Set defaults.
36 this.update();
36 this.update();
37 },
37 },
38
38
39 update : function(options){
39 update : function(options){
40 // Update the contents of this view
40 // Update the contents of this view
41 //
41 //
42 // Called when the model is changed. The model may have been
42 // Called when the model is changed. The model may have been
43 // changed by another view or by a state update from the back-end.
43 // changed by another view or by a state update from the back-end.
44 if (options === undefined || options.updated_view != this) {
44 if (options === undefined || options.updated_view != this) {
45 // JQuery slider option keys. These keys happen to have a
45 // JQuery slider option keys. These keys happen to have a
46 // one-to-one mapping with the corrosponding keys of the model.
46 // one-to-one mapping with the corrosponding keys of the model.
47 var jquery_slider_keys = ['step', 'max', 'min', 'disabled'];
47 var jquery_slider_keys = ['step', 'max', 'min', 'disabled'];
48 var that = this;
48 var that = this;
49 that.$slider.slider({});
49 that.$slider.slider({});
50 _.each(jquery_slider_keys, function(key, i) {
50 _.each(jquery_slider_keys, function(key, i) {
51 var model_value = that.model.get(key);
51 var model_value = that.model.get(key);
52 if (model_value !== undefined) {
52 if (model_value !== undefined) {
53 that.$slider.slider("option", key, model_value);
53 that.$slider.slider("option", key, model_value);
54 }
54 }
55 });
55 });
56
56
57 // WORKAROUND FOR JQUERY SLIDER BUG.
57 // WORKAROUND FOR JQUERY SLIDER BUG.
58 // The horizontal position of the slider handle
58 // The horizontal position of the slider handle
59 // depends on the value of the slider at the time
59 // depends on the value of the slider at the time
60 // of orientation change. Before applying the new
60 // of orientation change. Before applying the new
61 // workaround, we set the value to the minimum to
61 // workaround, we set the value to the minimum to
62 // make sure that the horizontal placement of the
62 // make sure that the horizontal placement of the
63 // handle in the vertical slider is always
63 // handle in the vertical slider is always
64 // consistent.
64 // consistent.
65 var orientation = this.model.get('orientation');
65 var orientation = this.model.get('orientation');
66 var min = this.model.get('min');
66 var min = this.model.get('min');
67 var max = this.model.get('max');
67 var max = this.model.get('max');
68 this.$slider.slider('option', 'value', min);
68 this.$slider.slider('option', 'value', min);
69 this.$slider.slider('option', 'orientation', orientation);
69 this.$slider.slider('option', 'orientation', orientation);
70 value = this.model.get('value');
70 value = this.model.get('value');
71 if(value > max) {
71 if(value > max) {
72 value = max;
72 value = max;
73 }
73 }
74 else if(value < min){
74 else if(value < min){
75 value = min;
75 value = min;
76 }
76 }
77 this.model.set('value', value, {updated_view: this});
78 this.$slider.slider('option', 'value', value);
77 this.$slider.slider('option', 'value', value);
79 this.$readout.text(value);
78 this.$readout.text(value);
80 this.touch();
79
80 if(this.model.get('value')!=value) {
81 alert(this.model.get('value'));
82 this.model.set('value', value, {updated_view: this});
83 alert("touched");
84 this.touch();
85 }
81
86
82 // Use the right CSS classes for vertical & horizontal sliders
87 // Use the right CSS classes for vertical & horizontal sliders
83 if (orientation=='vertical') {
88 if (orientation=='vertical') {
84 this.$slider_container
89 this.$slider_container
85 .removeClass('widget-hslider')
90 .removeClass('widget-hslider')
86 .addClass('widget-vslider');
91 .addClass('widget-vslider');
87 this.$el
92 this.$el
88 .removeClass('widget-hbox-single')
93 .removeClass('widget-hbox-single')
89 .addClass('widget-vbox-single');
94 .addClass('widget-vbox-single');
90 this.$label
95 this.$label
91 .removeClass('widget-hlabel')
96 .removeClass('widget-hlabel')
92 .addClass('widget-vlabel');
97 .addClass('widget-vlabel');
93 this.$readout
98 this.$readout
94 .removeClass('widget-hreadout')
99 .removeClass('widget-hreadout')
95 .addClass('widget-vreadout');
100 .addClass('widget-vreadout');
96
101
97 } else {
102 } else {
98 this.$slider_container
103 this.$slider_container
99 .removeClass('widget-vslider')
104 .removeClass('widget-vslider')
100 .addClass('widget-hslider');
105 .addClass('widget-hslider');
101 this.$el
106 this.$el
102 .removeClass('widget-vbox-single')
107 .removeClass('widget-vbox-single')
103 .addClass('widget-hbox-single');
108 .addClass('widget-hbox-single');
104 this.$label
109 this.$label
105 .removeClass('widget-vlabel')
110 .removeClass('widget-vlabel')
106 .addClass('widget-hlabel');
111 .addClass('widget-hlabel');
107 this.$readout
112 this.$readout
108 .removeClass('widget-vreadout')
113 .removeClass('widget-vreadout')
109 .addClass('widget-hreadout');
114 .addClass('widget-hreadout');
110 }
115 }
111
116
112 var description = this.model.get('description');
117 var description = this.model.get('description');
113 if (description.length === 0) {
118 if (description.length === 0) {
114 this.$label.hide();
119 this.$label.hide();
115 } else {
120 } else {
116 this.$label.text(description);
121 this.$label.text(description);
117 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
122 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
118 this.$label.show();
123 this.$label.show();
119 }
124 }
120
125
121 var readout = this.model.get('readout');
126 var readout = this.model.get('readout');
122 if (readout) {
127 if (readout) {
123 this.$readout.show();
128 this.$readout.show();
124 } else {
129 } else {
125 this.$readout.hide();
130 this.$readout.hide();
126 }
131 }
127 }
132 }
128 return IntSliderView.__super__.update.apply(this);
133 return IntSliderView.__super__.update.apply(this);
129 },
134 },
130
135
131 events: {
136 events: {
132 // Dictionary of events and their handlers.
137 // Dictionary of events and their handlers.
133 "slide" : "handleSliderChange"
138 "slide" : "handleSliderChange"
134 },
139 },
135
140
136 handleSliderChange: function(e, ui) {
141 handleSliderChange: function(e, ui) {
137 // Called when the slider value is changed.
142 // Called when the slider value is changed.
138
143
139 // Calling model.set will trigger all of the other views of the
144 // Calling model.set will trigger all of the other views of the
140 // model to update.
145 // model to update.
141 var actual_value = this._validate_slide_value(ui.value);
146 var actual_value = this._validate_slide_value(ui.value);
142 this.model.set('value', actual_value, {updated_view: this});
147 this.model.set('value', actual_value, {updated_view: this});
143 this.$readout.text(actual_value);
148 this.$readout.text(actual_value);
144 this.touch();
149 this.touch();
145 },
150 },
146
151
147 _validate_slide_value: function(x) {
152 _validate_slide_value: function(x) {
148 // Validate the value of the slider before sending it to the back-end
153 // Validate the value of the slider before sending it to the back-end
149 // and applying it to the other views on the page.
154 // and applying it to the other views on the page.
150
155
151 // Double bit-wise not truncates the decimel (int cast).
156 // Double bit-wise not truncates the decimel (int cast).
152 return ~~x;
157 return ~~x;
153 },
158 },
154 });
159 });
155
160
156
161
157 var IntTextView = widget.DOMWidgetView.extend({
162 var IntTextView = widget.DOMWidgetView.extend({
158 render : function(){
163 render : function(){
159 // Called when view is rendered.
164 // Called when view is rendered.
160 this.$el
165 this.$el
161 .addClass('widget-hbox-single');
166 .addClass('widget-hbox-single');
162 this.$label = $('<div />')
167 this.$label = $('<div />')
163 .appendTo(this.$el)
168 .appendTo(this.$el)
164 .addClass('widget-hlabel')
169 .addClass('widget-hlabel')
165 .hide();
170 .hide();
166 this.$textbox = $('<input type="text" />')
171 this.$textbox = $('<input type="text" />')
167 .addClass('form-control')
172 .addClass('form-control')
168 .addClass('widget-numeric-text')
173 .addClass('widget-numeric-text')
169 .appendTo(this.$el);
174 .appendTo(this.$el);
170 this.$el_to_style = this.$textbox; // Set default element to style
175 this.$el_to_style = this.$textbox; // Set default element to style
171 this.update(); // Set defaults.
176 this.update(); // Set defaults.
172 },
177 },
173
178
174 update : function(options){
179 update : function(options){
175 // Update the contents of this view
180 // Update the contents of this view
176 //
181 //
177 // Called when the model is changed. The model may have been
182 // Called when the model is changed. The model may have been
178 // changed by another view or by a state update from the back-end.
183 // changed by another view or by a state update from the back-end.
179 if (options === undefined || options.updated_view != this) {
184 if (options === undefined || options.updated_view != this) {
180 var value = this.model.get('value');
185 var value = this.model.get('value');
181 if (this._parse_value(this.$textbox.val()) != value) {
186 if (this._parse_value(this.$textbox.val()) != value) {
182 this.$textbox.val(value);
187 this.$textbox.val(value);
183 }
188 }
184
189
185 if (this.model.get('disabled')) {
190 if (this.model.get('disabled')) {
186 this.$textbox.attr('disabled','disabled');
191 this.$textbox.attr('disabled','disabled');
187 } else {
192 } else {
188 this.$textbox.removeAttr('disabled');
193 this.$textbox.removeAttr('disabled');
189 }
194 }
190
195
191 var description = this.model.get('description');
196 var description = this.model.get('description');
192 if (description.length === 0) {
197 if (description.length === 0) {
193 this.$label.hide();
198 this.$label.hide();
194 } else {
199 } else {
195 this.$label.text(description);
200 this.$label.text(description);
196 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
201 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
197 this.$label.show();
202 this.$label.show();
198 }
203 }
199 }
204 }
200 return IntTextView.__super__.update.apply(this);
205 return IntTextView.__super__.update.apply(this);
201 },
206 },
202
207
203 events: {
208 events: {
204 // Dictionary of events and their handlers.
209 // Dictionary of events and their handlers.
205 "keyup input" : "handleChanging",
210 "keyup input" : "handleChanging",
206 "paste input" : "handleChanging",
211 "paste input" : "handleChanging",
207 "cut input" : "handleChanging",
212 "cut input" : "handleChanging",
208
213
209 // Fires only when control is validated or looses focus.
214 // Fires only when control is validated or looses focus.
210 "change input" : "handleChanged"
215 "change input" : "handleChanged"
211 },
216 },
212
217
213 handleChanging: function(e) {
218 handleChanging: function(e) {
214 // Handles and validates user input.
219 // Handles and validates user input.
215
220
216 // Try to parse value as a int.
221 // Try to parse value as a int.
217 var numericalValue = 0;
222 var numericalValue = 0;
218 if (e.target.value !== '') {
223 if (e.target.value !== '') {
219 var trimmed = e.target.value.trim();
224 var trimmed = e.target.value.trim();
220 if (!(['-', '-.', '.', '+.', '+'].indexOf(trimmed) >= 0)) {
225 if (!(['-', '-.', '.', '+.', '+'].indexOf(trimmed) >= 0)) {
221 numericalValue = this._parse_value(e.target.value);
226 numericalValue = this._parse_value(e.target.value);
222 }
227 }
223 }
228 }
224
229
225 // If parse failed, reset value to value stored in model.
230 // If parse failed, reset value to value stored in model.
226 if (isNaN(numericalValue)) {
231 if (isNaN(numericalValue)) {
227 e.target.value = this.model.get('value');
232 e.target.value = this.model.get('value');
228 } else if (!isNaN(numericalValue)) {
233 } else if (!isNaN(numericalValue)) {
229 if (this.model.get('max') !== undefined) {
234 if (this.model.get('max') !== undefined) {
230 numericalValue = Math.min(this.model.get('max'), numericalValue);
235 numericalValue = Math.min(this.model.get('max'), numericalValue);
231 }
236 }
232 if (this.model.get('min') !== undefined) {
237 if (this.model.get('min') !== undefined) {
233 numericalValue = Math.max(this.model.get('min'), numericalValue);
238 numericalValue = Math.max(this.model.get('min'), numericalValue);
234 }
239 }
235
240
236 // Apply the value if it has changed.
241 // Apply the value if it has changed.
237 if (numericalValue != this.model.get('value')) {
242 if (numericalValue != this.model.get('value')) {
238
243
239 // Calling model.set will trigger all of the other views of the
244 // Calling model.set will trigger all of the other views of the
240 // model to update.
245 // model to update.
241 this.model.set('value', numericalValue, {updated_view: this});
246 this.model.set('value', numericalValue, {updated_view: this});
242 this.touch();
247 this.touch();
243 }
248 }
244 }
249 }
245 },
250 },
246
251
247 handleChanged: function(e) {
252 handleChanged: function(e) {
248 // Applies validated input.
253 // Applies validated input.
249 if (this.model.get('value') != e.target.value) {
254 if (this.model.get('value') != e.target.value) {
250 e.target.value = this.model.get('value');
255 e.target.value = this.model.get('value');
251 }
256 }
252 },
257 },
253
258
254 _parse_value: function(value) {
259 _parse_value: function(value) {
255 // Parse the value stored in a string.
260 // Parse the value stored in a string.
256 return parseInt(value);
261 return parseInt(value);
257 },
262 },
258 });
263 });
259
264
260
265
261 var ProgressView = widget.DOMWidgetView.extend({
266 var ProgressView = widget.DOMWidgetView.extend({
262 render : function(){
267 render : function(){
263 // Called when view is rendered.
268 // Called when view is rendered.
264 this.$el
269 this.$el
265 .addClass('widget-hbox-single');
270 .addClass('widget-hbox-single');
266 this.$label = $('<div />')
271 this.$label = $('<div />')
267 .appendTo(this.$el)
272 .appendTo(this.$el)
268 .addClass('widget-hlabel')
273 .addClass('widget-hlabel')
269 .hide();
274 .hide();
270 this.$progress = $('<div />')
275 this.$progress = $('<div />')
271 .addClass('progress')
276 .addClass('progress')
272 .addClass('widget-progress')
277 .addClass('widget-progress')
273 .appendTo(this.$el);
278 .appendTo(this.$el);
274 this.$el_to_style = this.$progress; // Set default element to style
279 this.$el_to_style = this.$progress; // Set default element to style
275 this.$bar = $('<div />')
280 this.$bar = $('<div />')
276 .addClass('progress-bar')
281 .addClass('progress-bar')
277 .css('width', '50%')
282 .css('width', '50%')
278 .appendTo(this.$progress);
283 .appendTo(this.$progress);
279 this.update(); // Set defaults.
284 this.update(); // Set defaults.
280 },
285 },
281
286
282 update : function(){
287 update : function(){
283 // Update the contents of this view
288 // Update the contents of this view
284 //
289 //
285 // Called when the model is changed. The model may have been
290 // Called when the model is changed. The model may have been
286 // changed by another view or by a state update from the back-end.
291 // changed by another view or by a state update from the back-end.
287 var value = this.model.get('value');
292 var value = this.model.get('value');
288 var max = this.model.get('max');
293 var max = this.model.get('max');
289 var min = this.model.get('min');
294 var min = this.model.get('min');
290 var percent = 100.0 * (value - min) / (max - min);
295 var percent = 100.0 * (value - min) / (max - min);
291 this.$bar.css('width', percent + '%');
296 this.$bar.css('width', percent + '%');
292
297
293 var description = this.model.get('description');
298 var description = this.model.get('description');
294 if (description.length === 0) {
299 if (description.length === 0) {
295 this.$label.hide();
300 this.$label.hide();
296 } else {
301 } else {
297 this.$label.text(description);
302 this.$label.text(description);
298 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
303 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
299 this.$label.show();
304 this.$label.show();
300 }
305 }
301 return ProgressView.__super__.update.apply(this);
306 return ProgressView.__super__.update.apply(this);
302 },
307 },
303 });
308 });
304
309
305 return {
310 return {
306 'IntSliderView': IntSliderView,
311 'IntSliderView': IntSliderView,
307 'IntTextView': IntTextView,
312 'IntTextView': IntTextView,
308 'ProgressView': ProgressView,
313 'ProgressView': ProgressView,
309 };
314 };
310 });
315 });
General Comments 0
You need to be logged in to leave comments. Login now