##// END OF EJS Templates
Added a class for RadioButtons container...
Jonathan Frederic -
Show More
@@ -1,382 +1,381 b''
1 1 //----------------------------------------------------------------------------
2 2 // Copyright (C) 2013 The IPython Development Team
3 3 //
4 4 // Distributed under the terms of the BSD License. The full license is in
5 5 // the file COPYING, distributed as part of this software.
6 6 //----------------------------------------------------------------------------
7 7
8 8 //============================================================================
9 9 // SelectionWidget
10 10 //============================================================================
11 11
12 12 /**
13 13 * @module IPython
14 14 * @namespace IPython
15 15 **/
16 16
17 17 define(["notebook/js/widgets/widget"], function(WidgetManager){
18 18
19 19 var DropdownView = IPython.DOMWidgetView.extend({
20 20 render : function(){
21 21 // Called when view is rendered.
22 22 this.$el
23 23 .addClass('widget-hbox-single');
24 24 this.$label = $('<div />')
25 25 .appendTo(this.$el)
26 26 .addClass('widget-hlabel')
27 27 .hide();
28 28 this.$buttongroup = $('<div />')
29 29 .addClass('widget_item')
30 30 .addClass('btn-group')
31 31 .appendTo(this.$el);
32 32 this.$el_to_style = this.$buttongroup; // Set default element to style
33 33 this.$droplabel = $('<button />')
34 34 .addClass('btn')
35 35 .addClass('widget-combo-btn')
36 36 .html("&nbsp;")
37 37 .appendTo(this.$buttongroup);
38 38 this.$dropbutton = $('<button />')
39 39 .addClass('btn')
40 40 .addClass('dropdown-toggle')
41 41 .addClass('widget-combo-carrot-btn')
42 42 .attr('data-toggle', 'dropdown')
43 43 .append($('<span />').addClass("caret"))
44 44 .appendTo(this.$buttongroup);
45 45 this.$droplist = $('<ul />')
46 46 .addClass('dropdown-menu')
47 47 .appendTo(this.$buttongroup);
48 48
49 49 // Set defaults.
50 50 this.update();
51 51 },
52 52
53 53 update : function(options){
54 54 // Update the contents of this view
55 55 //
56 56 // Called when the model is changed. The model may have been
57 57 // changed by another view or by a state update from the back-end.
58 58
59 59 if (options === undefined || options.updated_view != this) {
60 60 var selected_item_text = this.model.get('value_name');
61 61 if (selected_item_text.trim().length === 0) {
62 62 this.$droplabel.html("&nbsp;");
63 63 } else {
64 64 this.$droplabel.text(selected_item_text);
65 65 }
66 66
67 67 var items = this.model.get('value_names');
68 68 var $replace_droplist = $('<ul />')
69 69 .addClass('dropdown-menu');
70 70 var that = this;
71 71 _.each(items, function(item, i) {
72 72 var item_button = $('<a href="#"/>')
73 73 .text(item)
74 74 .on('click', $.proxy(that.handle_click, that));
75 75 $replace_droplist.append($('<li />').append(item_button));
76 76 });
77 77
78 78 this.$droplist.replaceWith($replace_droplist);
79 79 this.$droplist.remove();
80 80 this.$droplist = $replace_droplist;
81 81
82 82 if (this.model.get('disabled')) {
83 83 this.$buttongroup.attr('disabled','disabled');
84 84 this.$droplabel.attr('disabled','disabled');
85 85 this.$dropbutton.attr('disabled','disabled');
86 86 this.$droplist.attr('disabled','disabled');
87 87 } else {
88 88 this.$buttongroup.removeAttr('disabled');
89 89 this.$droplabel.removeAttr('disabled');
90 90 this.$dropbutton.removeAttr('disabled');
91 91 this.$droplist.removeAttr('disabled');
92 92 }
93 93
94 94 var description = this.model.get('description');
95 95 if (description.length === 0) {
96 96 this.$label.hide();
97 97 } else {
98 98 this.$label.text(description);
99 99 this.$label.show();
100 100 }
101 101 }
102 102 return DropdownView.__super__.update.apply(this);
103 103 },
104 104
105 105 handle_click: function (e) {
106 106 // Handle when a value is clicked.
107 107
108 108 // Calling model.set will trigger all of the other views of the
109 109 // model to update.
110 110 this.model.set('value_name', $(e.target).text(), {updated_view: this});
111 111 this.touch();
112 112 },
113 113
114 114 });
115 115 WidgetManager.register_widget_view('DropdownView', DropdownView);
116 116
117 117
118 118 var RadioButtonsView = IPython.DOMWidgetView.extend({
119 119 render : function(){
120 120 // Called when view is rendered.
121 121 this.$el
122 122 .addClass('widget-hbox');
123 123 this.$label = $('<div />')
124 124 .appendTo(this.$el)
125 125 .addClass('widget-hlabel')
126 126 .hide();
127 127 this.$container = $('<div />')
128 128 .appendTo(this.$el)
129 .addClass('widget-container')
130 .addClass('vbox');
129 .addClass('widget-radio-box');
131 130 this.$el_to_style = this.$container; // Set default element to style
132 131 this.update();
133 132 },
134 133
135 134 update : function(options){
136 135 // Update the contents of this view
137 136 //
138 137 // Called when the model is changed. The model may have been
139 138 // changed by another view or by a state update from the back-end.
140 139 if (options === undefined || options.updated_view != this) {
141 140 // Add missing items to the DOM.
142 141 var items = this.model.get('value_names');
143 142 var disabled = this.model.get('disabled');
144 143 var that = this;
145 144 _.each(items, function(item, index) {
146 145 var item_query = ' :input[value="' + item + '"]';
147 146 if (that.$el.find(item_query).length === 0) {
148 147 var $label = $('<label />')
149 148 .addClass('radio')
150 149 .text(item)
151 150 .appendTo(that.$container);
152 151
153 152 $('<input />')
154 153 .attr('type', 'radio')
155 154 .addClass(that.model)
156 155 .val(item)
157 156 .prependTo($label)
158 157 .on('click', $.proxy(that.handle_click, that));
159 158 }
160 159
161 160 var $item_element = that.$container.find(item_query);
162 161 if (that.model.get('value_name') == item) {
163 162 $item_element.prop('checked', true);
164 163 } else {
165 164 $item_element.prop('checked', false);
166 165 }
167 166 $item_element.prop('disabled', disabled);
168 167 });
169 168
170 169 // Remove items that no longer exist.
171 170 this.$container.find('input').each(function(i, obj) {
172 171 var value = $(obj).val();
173 172 var found = false;
174 173 _.each(items, function(item, index) {
175 174 if (item == value) {
176 175 found = true;
177 176 return false;
178 177 }
179 178 });
180 179
181 180 if (!found) {
182 181 $(obj).parent().remove();
183 182 }
184 183 });
185 184
186 185 var description = this.model.get('description');
187 186 if (description.length === 0) {
188 187 this.$label.hide();
189 188 } else {
190 189 this.$label.text(description);
191 190 this.$label.show();
192 191 }
193 192 }
194 193 return RadioButtonsView.__super__.update.apply(this);
195 194 },
196 195
197 196 handle_click: function (e) {
198 197 // Handle when a value is clicked.
199 198
200 199 // Calling model.set will trigger all of the other views of the
201 200 // model to update.
202 201 this.model.set('value_name', $(e.target).val(), {updated_view: this});
203 202 this.touch();
204 203 },
205 204 });
206 205 WidgetManager.register_widget_view('RadioButtonsView', RadioButtonsView);
207 206
208 207
209 208 var ToggleButtonsView = IPython.DOMWidgetView.extend({
210 209 render : function(){
211 210 // Called when view is rendered.
212 211 this.$el
213 212 .addClass('widget-hbox-single');
214 213 this.$label = $('<div />')
215 214 .appendTo(this.$el)
216 215 .addClass('widget-hlabel')
217 216 .hide();
218 217 this.$buttongroup = $('<div />')
219 218 .addClass('btn-group')
220 219 .attr('data-toggle', 'buttons-radio')
221 220 .appendTo(this.$el);
222 221 this.$el_to_style = this.$buttongroup; // Set default element to style
223 222 this.update();
224 223 },
225 224
226 225 update : function(options){
227 226 // Update the contents of this view
228 227 //
229 228 // Called when the model is changed. The model may have been
230 229 // changed by another view or by a state update from the back-end.
231 230 if (options === undefined || options.updated_view != this) {
232 231 // Add missing items to the DOM.
233 232 var items = this.model.get('value_names');
234 233 var disabled = this.model.get('disabled');
235 234 var that = this;
236 235 var item_html;
237 236 _.each(items, function(item, index) {
238 237 if (item.trim().length == 0) {
239 238 item_html = "&nbsp;";
240 239 } else {
241 240 item_html = IPython.utils.escape_html(item);
242 241 }
243 242 var item_query = '[data-value="' + item + '"]';
244 243 var $item_element = that.$buttongroup.find(item_query);
245 244 if (!$item_element.length) {
246 245 $item_element = $('<button/>')
247 246 .attr('type', 'button')
248 247 .addClass('btn')
249 248 .html(item_html)
250 249 .appendTo(that.$buttongroup)
251 250 .attr('data-value', item)
252 251 .on('click', $.proxy(that.handle_click, that));
253 252 }
254 253 if (that.model.get('value_name') == item) {
255 254 $item_element.addClass('active');
256 255 } else {
257 256 $item_element.removeClass('active');
258 257 }
259 258 $item_element.prop('disabled', disabled);
260 259 });
261 260
262 261 // Remove items that no longer exist.
263 262 this.$buttongroup.find('button').each(function(i, obj) {
264 263 var value = $(obj).data('value');
265 264 var found = false;
266 265 _.each(items, function(item, index) {
267 266 if (item == value) {
268 267 found = true;
269 268 return false;
270 269 }
271 270 });
272 271
273 272 if (!found) {
274 273 $(obj).remove();
275 274 }
276 275 });
277 276
278 277 var description = this.model.get('description');
279 278 if (description.length === 0) {
280 279 this.$label.hide();
281 280 } else {
282 281 this.$label.text(description);
283 282 this.$label.show();
284 283 }
285 284 }
286 285 return ToggleButtonsView.__super__.update.apply(this);
287 286 },
288 287
289 288 handle_click: function (e) {
290 289 // Handle when a value is clicked.
291 290
292 291 // Calling model.set will trigger all of the other views of the
293 292 // model to update.
294 293 this.model.set('value_name', $(e.target).data('value'), {updated_view: this});
295 294 this.touch();
296 295 },
297 296 });
298 297 WidgetManager.register_widget_view('ToggleButtonsView', ToggleButtonsView);
299 298
300 299
301 300 var SelectView = IPython.DOMWidgetView.extend({
302 301 render : function(){
303 302 // Called when view is rendered.
304 303 this.$el
305 304 .addClass('widget-hbox');
306 305 this.$label = $('<div />')
307 306 .appendTo(this.$el)
308 307 .addClass('widget-hlabel')
309 308 .hide();
310 309 this.$listbox = $('<select />')
311 310 .addClass('widget-listbox')
312 311 .attr('size', 6)
313 312 .appendTo(this.$el);
314 313 this.$el_to_style = this.$listbox; // Set default element to style
315 314 this.update();
316 315 },
317 316
318 317 update : function(options){
319 318 // Update the contents of this view
320 319 //
321 320 // Called when the model is changed. The model may have been
322 321 // changed by another view or by a state update from the back-end.
323 322 if (options === undefined || options.updated_view != this) {
324 323 // Add missing items to the DOM.
325 324 var items = this.model.get('value_names');
326 325 var that = this;
327 326 _.each(items, function(item, index) {
328 327 var item_query = ' :contains("' + item + '")';
329 328 if (that.$listbox.find(item_query).length === 0) {
330 329 $('<option />')
331 330 .text(item)
332 331 .attr('value_name', item)
333 332 .appendTo(that.$listbox)
334 333 .on('click', $.proxy(that.handle_click, that));
335 334 }
336 335 });
337 336
338 337 // Select the correct element
339 338 this.$listbox.val(this.model.get('value_name'));
340 339
341 340 // Disable listbox if needed
342 341 var disabled = this.model.get('disabled');
343 342 this.$listbox.prop('disabled', disabled);
344 343
345 344 // Remove items that no longer exist.
346 345 this.$listbox.find('option').each(function(i, obj) {
347 346 var value = $(obj).text();
348 347 var found = false;
349 348 _.each(items, function(item, index) {
350 349 if (item == value) {
351 350 found = true;
352 351 return false;
353 352 }
354 353 });
355 354
356 355 if (!found) {
357 356 $(obj).remove();
358 357 }
359 358 });
360 359
361 360 var description = this.model.get('description');
362 361 if (description.length === 0) {
363 362 this.$label.hide();
364 363 } else {
365 364 this.$label.text(description);
366 365 this.$label.show();
367 366 }
368 367 }
369 368 return SelectView.__super__.update.apply(this);
370 369 },
371 370
372 371 handle_click: function (e) {
373 372 // Handle when a value is clicked.
374 373
375 374 // Calling model.set will trigger all of the other views of the
376 375 // model to update.
377 376 this.model.set('value_name', $(e.target).text(), {updated_view: this});
378 377 this.touch();
379 378 },
380 379 });
381 380 WidgetManager.register_widget_view('SelectView', SelectView);
382 381 });
@@ -1,271 +1,280 b''
1 1 .widget-area {
2 2 /*
3 3 LESS file that styles IPython notebook widgets and the area they sit in.
4 4
5 5 The widget area typically looks something like this:
6 6 +------------------------------------------+
7 7 | widget-area |
8 8 | +--------+---------------------------+ |
9 9 | | prompt | widget-subarea | |
10 10 | | | +--------+ +--------+ | |
11 11 | | | | widget | | widget | | |
12 12 | | | +--------+ +--------+ | |
13 13 | +--------+---------------------------+ |
14 14 +------------------------------------------+
15 15 */
16 16
17 17 page-break-inside : avoid;
18 18 .hbox();
19 19
20 20 .widget-subarea {
21 21 padding : 0.44em 0.4em 0.4em 1px;
22 22 margin-left : 6px;
23 23
24 24 .border-box-sizing();
25 25 .vbox();
26 26 .box-flex2();
27 27 .align-start();
28 28 }
29 29 }
30 30
31 31 /* THE CLASSES BELOW CAN APPEAR ANYWHERE IN THE DOM (POSSIBLEY OUTSIDE OF
32 32 THE WIDGET AREA). */
33 33
34 34 .widget-hlabel {
35 35 /* Horizontal Label */
36 36 min-width : 10ex;
37 37 padding-right : 8px;
38 38 padding-top : 3px;
39 39 text-align : right;
40 40 vertical-align : text-top;
41 41 }
42 42
43 43 .widget-vlabel {
44 44 /* Vertical Label */
45 45 padding-bottom : 5px;
46 46 text-align : center;
47 47 vertical-align : text-bottom;
48 48 }
49 49
50 50 .widget-hreadout {
51 51 padding-left : 8px;
52 52 padding-top : 3px;
53 53 text-align : left;
54 54 vertical-align : text-top;
55 55 }
56 56
57 57 .widget-vreadout {
58 58 /* Vertical Label */
59 59 padding-top : 5px;
60 60 text-align : center;
61 61 vertical-align : text-top;
62 62 }
63 63
64 64 .slide-track {
65 65 /* Slider Track */
66 66 border : 1px solid #CCCCCC;
67 67 background : #FFFFFF;
68 68
69 69 .corner-all(); /* Round the corners of the slide track */
70 70 }
71 71
72 72 .widget-hslider {
73 73 /* Horizontal jQuery Slider
74 74
75 75 Both the horizontal and vertical versions of the slider are characterized
76 76 by a styled div that contains an invisible jQuery slide div which
77 77 contains a visible slider handle div. This is requred so we can control
78 78 how the slider is drawn and 'fix' the issue where the slide handle
79 79 doesn't stop at the end of the slide.
80 80
81 81 Both horizontal and vertical sliders have this div nesting:
82 82 +------------------------------------------+
83 83 | widget-(h/v)slider |
84 84 | +--------+---------------------------+ |
85 85 | | ui-slider | |
86 86 | | +------------------+ | |
87 87 | | | ui-slider-handle | | |
88 88 | | +------------------+ | |
89 89 | +--------+---------------------------+ |
90 90 +------------------------------------------+
91 91 */
92 92
93 93 /* Fix the padding of the slide track so the ui-slider is sized
94 94 correctly. */
95 95 padding-left : 8px;
96 96 padding-right : 5px;
97 97 overflow : visible;
98 98
99 99 /* Default size of the slider */
100 100 width : 348px;
101 101 height : 5px;
102 102 max-height : 5px;
103 103 margin-top : 11px;
104 104 margin-bottom: 10px;
105 105
106 106 /* Style the slider track */
107 107 .slide-track();
108 108
109 109 /* Make the div a flex box (makes FF behave correctly). */
110 110 .hbox();
111 111
112 112 .ui-slider {
113 113 /* Inner, invisible slide div */
114 114 border : 0px !important;
115 115 background : none !important;
116 116
117 117 .hbox();
118 118 .box-flex1();
119 119
120 120 .ui-slider-handle {
121 121 width : 14px !important;
122 122 height : 28px !important;
123 123 margin-top : -8px !important;
124 124 }
125 125 }
126 126 }
127 127
128 128 .widget-vslider {
129 129 /* Vertical jQuery Slider */
130 130
131 131 /* Fix the padding of the slide track so the ui-slider is sized
132 132 correctly. */
133 133 padding-bottom : 8px;
134 134 overflow : visible;
135 135
136 136 /* Default size of the slider */
137 137 width : 5px;
138 138 max-width : 5px;
139 139 height : 250px;
140 140 margin-left : 12px;
141 141
142 142 /* Style the slider track */
143 143 .slide-track();
144 144
145 145 /* Make the div a flex box (makes FF behave correctly). */
146 146 .vbox();
147 147
148 148 .ui-slider {
149 149 /* Inner, invisible slide div */
150 150 border : 0px !important;
151 151 background : none !important;
152 152 margin-left : -4px;
153 153 margin-top : 5px;
154 154
155 155 .vbox();
156 156 .box-flex1();
157 157
158 158 .ui-slider-handle {
159 159 width : 28px !important;
160 160 height : 14px !important;
161 161 margin-left : -9px;
162 162 }
163 163 }
164 164 }
165 165
166 166 .widget-text {
167 167 /* String Textbox - used for TextBoxView and TextAreaView */
168 168 width : 350px;
169 169 margin : 0px !important;
170 170 }
171 171
172 172 .widget-listbox {
173 173 /* Listbox */
174 174 width : 364px;
175 175 margin-bottom : 0px;
176 176 }
177 177
178 178 .widget-numeric-text {
179 179 /* Single Line Textbox - used for IntTextView and FloatTextView */
180 180 width : 150px;
181 margin : 0px !important;
181 182 }
182 183
183 184 .widget-progress {
184 185 /* Progress Bar */
185 186 width : 363px;
186 187
187 188 .bar {
188 189 /* Disable progress bar animation */
189 190 -webkit-transition : none;
190 191 -moz-transition : none;
191 192 -ms-transition : none;
192 193 -o-transition : none;
193 194 transition : none;
194 195 }
195 196 }
196 197
197 198 .widget-combo-btn {
198 199 /* ComboBox Main Button */
199 200 min-width : 138px; /* + 26px drop arrow btn = 164px */
200 201 }
201 202
202 203 .widget-box {
203 204 /* The following section sets the style for the invisible div that
204 205 hold widgets and their accompanying labels.
205 206
206 207 Looks like this:
207 208 +-----------------------------+
208 209 | widget-box (or similar) |
209 210 | +-------+---------------+ |
210 211 | | Label | Actual Widget | |
211 212 | +-------+---------------+ |
212 213 +-----------------------------+
213 214 */
214 215 margin : 5px;
215 216
216 217 .start();
217 218 .widget-container();
218 219 }
219 220
220 221 .widget-hbox {
221 222 /* Horizontal widgets */
222 223 .widget-box();
223 224 .hbox();
224 225 }
225 226
226 227 .widget-hbox-single {
227 228 /* Single line horizontal widgets */
228 229 .widget-hbox();
229 230 height : 30px;
230 231 }
231 232
232 233 .widget-vbox {
233 234 /* Vertical widgets */
234 235 .widget-box();
235 236 .vbox();
236 237 }
237 238
238 239 .widget-vbox-single {
239 240 /* For vertical slides */
240 241 .widget-vbox();
241 242 width : 30px;
242 243 }
243 244
244 245 .widget-modal {
245 246 /* ContainerWidget - ModalView */
246 247 overflow : hidden;
247 248 position : absolute !important;
248 249 top : 0px;
249 250 left : 0px;
250 251 margin-left : 0px !important;
251 252 }
252 253
253 254 .widget-modal-body {
254 255 /* ContainerWidget - ModalView Body */
255 256 max-height: none !important;
256 257 }
257 258
258 259 .widget-container {
259 260 /* ContainerWidget */
260 261 .border-box-sizing();
261 262 .align-start();
262 263 }
263 264
265 .widget-radio-box {
266 /* Contains RadioButtonsWidget */
267 .vbox();
268 .border-box-sizing();
269
270 padding-top: 4px;
271 }
272
264 273 .docked-widget-modal {
265 274 /* Horizontal Label */
266 275 overflow: hidden;
267 276 position: relative !important;
268 277 top: 0px !important;
269 278 left: 0px !important;
270 279 margin-left: 0px !important;
271 280 } No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now