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