##// END OF EJS Templates
don't use contains in SelectWidget item_query...
MinRK -
Show More
@@ -1,472 +1,472 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 "base/js/utils",
6 "base/js/utils",
7 "jquery",
7 "jquery",
8 "bootstrap",
8 "bootstrap",
9 ], function(widget, utils, $){
9 ], function(widget, utils, $){
10
10
11 var DropdownView = widget.DOMWidgetView.extend({
11 var DropdownView = 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-dropdown');
15 .addClass('widget-hbox widget-dropdown');
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 this.$buttongroup = $('<div />')
20 this.$buttongroup = $('<div />')
21 .addClass('widget_item')
21 .addClass('widget_item')
22 .addClass('btn-group')
22 .addClass('btn-group')
23 .appendTo(this.$el);
23 .appendTo(this.$el);
24 this.$droplabel = $('<button />')
24 this.$droplabel = $('<button />')
25 .addClass('btn btn-default')
25 .addClass('btn btn-default')
26 .addClass('widget-combo-btn')
26 .addClass('widget-combo-btn')
27 .html("&nbsp;")
27 .html("&nbsp;")
28 .appendTo(this.$buttongroup);
28 .appendTo(this.$buttongroup);
29 this.$dropbutton = $('<button />')
29 this.$dropbutton = $('<button />')
30 .addClass('btn btn-default')
30 .addClass('btn btn-default')
31 .addClass('dropdown-toggle')
31 .addClass('dropdown-toggle')
32 .addClass('widget-combo-carrot-btn')
32 .addClass('widget-combo-carrot-btn')
33 .attr('data-toggle', 'dropdown')
33 .attr('data-toggle', 'dropdown')
34 .append($('<span />').addClass("caret"))
34 .append($('<span />').addClass("caret"))
35 .appendTo(this.$buttongroup);
35 .appendTo(this.$buttongroup);
36 this.$droplist = $('<ul />')
36 this.$droplist = $('<ul />')
37 .addClass('dropdown-menu')
37 .addClass('dropdown-menu')
38 .appendTo(this.$buttongroup);
38 .appendTo(this.$buttongroup);
39
39
40 this.model.on('change:button_style', function(model, value) {
40 this.model.on('change:button_style', function(model, value) {
41 this.update_button_style();
41 this.update_button_style();
42 }, this);
42 }, this);
43 this.update_button_style('');
43 this.update_button_style('');
44
44
45 // Set defaults.
45 // Set defaults.
46 this.update();
46 this.update();
47 },
47 },
48
48
49 update : function(options){
49 update : function(options){
50 // Update the contents of this view
50 // Update the contents of this view
51 //
51 //
52 // Called when the model is changed. The model may have been
52 // Called when the model is changed. The model may have been
53 // changed by another view or by a state update from the back-end.
53 // changed by another view or by a state update from the back-end.
54
54
55 if (options === undefined || options.updated_view != this) {
55 if (options === undefined || options.updated_view != this) {
56 var selected_item_text = this.model.get('value_name');
56 var selected_item_text = this.model.get('value_name');
57 if (selected_item_text.trim().length === 0) {
57 if (selected_item_text.trim().length === 0) {
58 this.$droplabel.html("&nbsp;");
58 this.$droplabel.html("&nbsp;");
59 } else {
59 } else {
60 this.$droplabel.text(selected_item_text);
60 this.$droplabel.text(selected_item_text);
61 }
61 }
62
62
63 var items = this.model.get('value_names');
63 var items = this.model.get('value_names');
64 var $replace_droplist = $('<ul />')
64 var $replace_droplist = $('<ul />')
65 .addClass('dropdown-menu');
65 .addClass('dropdown-menu');
66 // Copy the style
66 // Copy the style
67 $replace_droplist.attr('style', this.$droplist.attr('style'));
67 $replace_droplist.attr('style', this.$droplist.attr('style'));
68 var that = this;
68 var that = this;
69 _.each(items, function(item, i) {
69 _.each(items, function(item, i) {
70 var item_button = $('<a href="#"/>')
70 var item_button = $('<a href="#"/>')
71 .text(item)
71 .text(item)
72 .on('click', $.proxy(that.handle_click, that));
72 .on('click', $.proxy(that.handle_click, that));
73 $replace_droplist.append($('<li />').append(item_button));
73 $replace_droplist.append($('<li />').append(item_button));
74 });
74 });
75
75
76 this.$droplist.replaceWith($replace_droplist);
76 this.$droplist.replaceWith($replace_droplist);
77 this.$droplist.remove();
77 this.$droplist.remove();
78 this.$droplist = $replace_droplist;
78 this.$droplist = $replace_droplist;
79
79
80 if (this.model.get('disabled')) {
80 if (this.model.get('disabled')) {
81 this.$buttongroup.attr('disabled','disabled');
81 this.$buttongroup.attr('disabled','disabled');
82 this.$droplabel.attr('disabled','disabled');
82 this.$droplabel.attr('disabled','disabled');
83 this.$dropbutton.attr('disabled','disabled');
83 this.$dropbutton.attr('disabled','disabled');
84 this.$droplist.attr('disabled','disabled');
84 this.$droplist.attr('disabled','disabled');
85 } else {
85 } else {
86 this.$buttongroup.removeAttr('disabled');
86 this.$buttongroup.removeAttr('disabled');
87 this.$droplabel.removeAttr('disabled');
87 this.$droplabel.removeAttr('disabled');
88 this.$dropbutton.removeAttr('disabled');
88 this.$dropbutton.removeAttr('disabled');
89 this.$droplist.removeAttr('disabled');
89 this.$droplist.removeAttr('disabled');
90 }
90 }
91
91
92 var description = this.model.get('description');
92 var description = this.model.get('description');
93 if (description.length === 0) {
93 if (description.length === 0) {
94 this.$label.hide();
94 this.$label.hide();
95 } else {
95 } else {
96 this.$label.text(description);
96 this.$label.text(description);
97 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
97 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
98 this.$label.show();
98 this.$label.show();
99 }
99 }
100 }
100 }
101 return DropdownView.__super__.update.apply(this);
101 return DropdownView.__super__.update.apply(this);
102 },
102 },
103
103
104 update_button_style: function(previous_trait_value) {
104 update_button_style: function(previous_trait_value) {
105 var class_map = {
105 var class_map = {
106 primary: ['btn-primary'],
106 primary: ['btn-primary'],
107 success: ['btn-success'],
107 success: ['btn-success'],
108 info: ['btn-info'],
108 info: ['btn-info'],
109 warning: ['btn-warning'],
109 warning: ['btn-warning'],
110 danger: ['btn-danger']
110 danger: ['btn-danger']
111 };
111 };
112 this.update_mapped_classes(class_map, 'button_style', previous_trait_value, this.$droplabel);
112 this.update_mapped_classes(class_map, 'button_style', previous_trait_value, this.$droplabel);
113 this.update_mapped_classes(class_map, 'button_style', previous_trait_value, this.$dropbutton);
113 this.update_mapped_classes(class_map, 'button_style', previous_trait_value, this.$dropbutton);
114 },
114 },
115
115
116 update_attr: function(name, value) {
116 update_attr: function(name, value) {
117 // Set a css attr of the widget view.
117 // Set a css attr of the widget view.
118 if (name.substring(0, 6) == 'border' || name == 'background' || name == 'color') {
118 if (name.substring(0, 6) == 'border' || name == 'background' || name == 'color') {
119 this.$droplabel.css(name, value);
119 this.$droplabel.css(name, value);
120 this.$dropbutton.css(name, value);
120 this.$dropbutton.css(name, value);
121 this.$droplist.css(name, value);
121 this.$droplist.css(name, value);
122 } else if (name == 'width') {
122 } else if (name == 'width') {
123 this.$droplist.css(name, value);
123 this.$droplist.css(name, value);
124 this.$droplabel.css(name, value);
124 this.$droplabel.css(name, value);
125 } else if (name == 'padding') {
125 } else if (name == 'padding') {
126 this.$droplist.css(name, value);
126 this.$droplist.css(name, value);
127 this.$buttongroup.css(name, value);
127 this.$buttongroup.css(name, value);
128 } else if (name == 'margin') {
128 } else if (name == 'margin') {
129 this.$buttongroup.css(name, value);
129 this.$buttongroup.css(name, value);
130 } else if (name == 'height') {
130 } else if (name == 'height') {
131 this.$droplabel.css(name, value);
131 this.$droplabel.css(name, value);
132 this.$dropbutton.css(name, value);
132 this.$dropbutton.css(name, value);
133 } else {
133 } else {
134 this.$droplist.css(name, value);
134 this.$droplist.css(name, value);
135 this.$droplabel.css(name, value);
135 this.$droplabel.css(name, value);
136 }
136 }
137 },
137 },
138
138
139 handle_click: function (e) {
139 handle_click: function (e) {
140 // Handle when a value is clicked.
140 // Handle when a value is clicked.
141
141
142 // Calling model.set will trigger all of the other views of the
142 // Calling model.set will trigger all of the other views of the
143 // model to update.
143 // model to update.
144 this.model.set('value_name', $(e.target).text(), {updated_view: this});
144 this.model.set('value_name', $(e.target).text(), {updated_view: this});
145 this.touch();
145 this.touch();
146 },
146 },
147
147
148 });
148 });
149
149
150
150
151 var RadioButtonsView = widget.DOMWidgetView.extend({
151 var RadioButtonsView = widget.DOMWidgetView.extend({
152 render : function(){
152 render : function(){
153 // Called when view is rendered.
153 // Called when view is rendered.
154 this.$el
154 this.$el
155 .addClass('widget-hbox widget-radio');
155 .addClass('widget-hbox widget-radio');
156 this.$label = $('<div />')
156 this.$label = $('<div />')
157 .appendTo(this.$el)
157 .appendTo(this.$el)
158 .addClass('widget-label')
158 .addClass('widget-label')
159 .hide();
159 .hide();
160 this.$container = $('<div />')
160 this.$container = $('<div />')
161 .appendTo(this.$el)
161 .appendTo(this.$el)
162 .addClass('widget-radio-box');
162 .addClass('widget-radio-box');
163 this.update();
163 this.update();
164 },
164 },
165
165
166 update : function(options){
166 update : function(options){
167 // Update the contents of this view
167 // Update the contents of this view
168 //
168 //
169 // Called when the model is changed. The model may have been
169 // Called when the model is changed. The model may have been
170 // changed by another view or by a state update from the back-end.
170 // changed by another view or by a state update from the back-end.
171 if (options === undefined || options.updated_view != this) {
171 if (options === undefined || options.updated_view != this) {
172 // Add missing items to the DOM.
172 // Add missing items to the DOM.
173 var items = this.model.get('value_names');
173 var items = this.model.get('value_names');
174 var disabled = this.model.get('disabled');
174 var disabled = this.model.get('disabled');
175 var that = this;
175 var that = this;
176 _.each(items, function(item, index) {
176 _.each(items, function(item, index) {
177 var item_query = ' :input[value="' + item + '"]';
177 var item_query = ' :input[value="' + item + '"]';
178 if (that.$el.find(item_query).length === 0) {
178 if (that.$el.find(item_query).length === 0) {
179 var $label = $('<label />')
179 var $label = $('<label />')
180 .addClass('radio')
180 .addClass('radio')
181 .text(item)
181 .text(item)
182 .appendTo(that.$container);
182 .appendTo(that.$container);
183
183
184 $('<input />')
184 $('<input />')
185 .attr('type', 'radio')
185 .attr('type', 'radio')
186 .addClass(that.model)
186 .addClass(that.model)
187 .val(item)
187 .val(item)
188 .prependTo($label)
188 .prependTo($label)
189 .on('click', $.proxy(that.handle_click, that));
189 .on('click', $.proxy(that.handle_click, that));
190 }
190 }
191
191
192 var $item_element = that.$container.find(item_query);
192 var $item_element = that.$container.find(item_query);
193 if (that.model.get('value_name') == item) {
193 if (that.model.get('value_name') == item) {
194 $item_element.prop('checked', true);
194 $item_element.prop('checked', true);
195 } else {
195 } else {
196 $item_element.prop('checked', false);
196 $item_element.prop('checked', false);
197 }
197 }
198 $item_element.prop('disabled', disabled);
198 $item_element.prop('disabled', disabled);
199 });
199 });
200
200
201 // Remove items that no longer exist.
201 // Remove items that no longer exist.
202 this.$container.find('input').each(function(i, obj) {
202 this.$container.find('input').each(function(i, obj) {
203 var value = $(obj).val();
203 var value = $(obj).val();
204 var found = false;
204 var found = false;
205 _.each(items, function(item, index) {
205 _.each(items, function(item, index) {
206 if (item == value) {
206 if (item == value) {
207 found = true;
207 found = true;
208 return false;
208 return false;
209 }
209 }
210 });
210 });
211
211
212 if (!found) {
212 if (!found) {
213 $(obj).parent().remove();
213 $(obj).parent().remove();
214 }
214 }
215 });
215 });
216
216
217 var description = this.model.get('description');
217 var description = this.model.get('description');
218 if (description.length === 0) {
218 if (description.length === 0) {
219 this.$label.hide();
219 this.$label.hide();
220 } else {
220 } else {
221 this.$label.text(description);
221 this.$label.text(description);
222 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
222 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
223 this.$label.show();
223 this.$label.show();
224 }
224 }
225 }
225 }
226 return RadioButtonsView.__super__.update.apply(this);
226 return RadioButtonsView.__super__.update.apply(this);
227 },
227 },
228
228
229 update_attr: function(name, value) {
229 update_attr: function(name, value) {
230 // Set a css attr of the widget view.
230 // Set a css attr of the widget view.
231 this.$container.css(name, value);
231 this.$container.css(name, value);
232 },
232 },
233
233
234 handle_click: function (e) {
234 handle_click: function (e) {
235 // Handle when a value is clicked.
235 // Handle when a value is clicked.
236
236
237 // Calling model.set will trigger all of the other views of the
237 // Calling model.set will trigger all of the other views of the
238 // model to update.
238 // model to update.
239 this.model.set('value_name', $(e.target).val(), {updated_view: this});
239 this.model.set('value_name', $(e.target).val(), {updated_view: this});
240 this.touch();
240 this.touch();
241 },
241 },
242 });
242 });
243
243
244
244
245 var ToggleButtonsView = widget.DOMWidgetView.extend({
245 var ToggleButtonsView = widget.DOMWidgetView.extend({
246 initialize: function() {
246 initialize: function() {
247 this._css_state = {};
247 this._css_state = {};
248 ToggleButtonsView.__super__.initialize.apply(this, arguments);
248 ToggleButtonsView.__super__.initialize.apply(this, arguments);
249 },
249 },
250
250
251 render: function() {
251 render: function() {
252 // Called when view is rendered.
252 // Called when view is rendered.
253 this.$el
253 this.$el
254 .addClass('widget-hbox widget-toggle-buttons');
254 .addClass('widget-hbox widget-toggle-buttons');
255 this.$label = $('<div />')
255 this.$label = $('<div />')
256 .appendTo(this.$el)
256 .appendTo(this.$el)
257 .addClass('widget-label')
257 .addClass('widget-label')
258 .hide();
258 .hide();
259 this.$buttongroup = $('<div />')
259 this.$buttongroup = $('<div />')
260 .addClass('btn-group')
260 .addClass('btn-group')
261 .attr('data-toggle', 'buttons-radio')
261 .attr('data-toggle', 'buttons-radio')
262 .appendTo(this.$el);
262 .appendTo(this.$el);
263
263
264 this.model.on('change:button_style', function(model, value) {
264 this.model.on('change:button_style', function(model, value) {
265 this.update_button_style();
265 this.update_button_style();
266 }, this);
266 }, this);
267 this.update_button_style('');
267 this.update_button_style('');
268 this.update();
268 this.update();
269 },
269 },
270
270
271 update : function(options){
271 update : function(options){
272 // Update the contents of this view
272 // Update the contents of this view
273 //
273 //
274 // Called when the model is changed. The model may have been
274 // Called when the model is changed. The model may have been
275 // changed by another view or by a state update from the back-end.
275 // changed by another view or by a state update from the back-end.
276 if (options === undefined || options.updated_view != this) {
276 if (options === undefined || options.updated_view != this) {
277 // Add missing items to the DOM.
277 // Add missing items to the DOM.
278 var items = this.model.get('value_names');
278 var items = this.model.get('value_names');
279 var disabled = this.model.get('disabled');
279 var disabled = this.model.get('disabled');
280 var that = this;
280 var that = this;
281 var item_html;
281 var item_html;
282 _.each(items, function(item, index) {
282 _.each(items, function(item, index) {
283 if (item.trim().length == 0) {
283 if (item.trim().length == 0) {
284 item_html = "&nbsp;";
284 item_html = "&nbsp;";
285 } else {
285 } else {
286 item_html = utils.escape_html(item);
286 item_html = utils.escape_html(item);
287 }
287 }
288 var item_query = '[data-value="' + item + '"]';
288 var item_query = '[data-value="' + item + '"]';
289 var $item_element = that.$buttongroup.find(item_query);
289 var $item_element = that.$buttongroup.find(item_query);
290 if (!$item_element.length) {
290 if (!$item_element.length) {
291 $item_element = $('<button/>')
291 $item_element = $('<button/>')
292 .attr('type', 'button')
292 .attr('type', 'button')
293 .addClass('btn btn-default')
293 .addClass('btn btn-default')
294 .html(item_html)
294 .html(item_html)
295 .appendTo(that.$buttongroup)
295 .appendTo(that.$buttongroup)
296 .attr('data-value', item)
296 .attr('data-value', item)
297 .on('click', $.proxy(that.handle_click, that));
297 .on('click', $.proxy(that.handle_click, that));
298 that.update_style_traits($item_element);
298 that.update_style_traits($item_element);
299 }
299 }
300 if (that.model.get('value_name') == item) {
300 if (that.model.get('value_name') == item) {
301 $item_element.addClass('active');
301 $item_element.addClass('active');
302 } else {
302 } else {
303 $item_element.removeClass('active');
303 $item_element.removeClass('active');
304 }
304 }
305 $item_element.prop('disabled', disabled);
305 $item_element.prop('disabled', disabled);
306 });
306 });
307
307
308 // Remove items that no longer exist.
308 // Remove items that no longer exist.
309 this.$buttongroup.find('button').each(function(i, obj) {
309 this.$buttongroup.find('button').each(function(i, obj) {
310 var value = $(obj).data('value');
310 var value = $(obj).data('value');
311 var found = false;
311 var found = false;
312 _.each(items, function(item, index) {
312 _.each(items, function(item, index) {
313 if (item == value) {
313 if (item == value) {
314 found = true;
314 found = true;
315 return false;
315 return false;
316 }
316 }
317 });
317 });
318
318
319 if (!found) {
319 if (!found) {
320 $(obj).remove();
320 $(obj).remove();
321 }
321 }
322 });
322 });
323
323
324 var description = this.model.get('description');
324 var description = this.model.get('description');
325 if (description.length === 0) {
325 if (description.length === 0) {
326 this.$label.hide();
326 this.$label.hide();
327 } else {
327 } else {
328 this.$label.text(description);
328 this.$label.text(description);
329 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
329 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
330 this.$label.show();
330 this.$label.show();
331 }
331 }
332 }
332 }
333 return ToggleButtonsView.__super__.update.apply(this);
333 return ToggleButtonsView.__super__.update.apply(this);
334 },
334 },
335
335
336 update_attr: function(name, value) {
336 update_attr: function(name, value) {
337 // Set a css attr of the widget view.
337 // Set a css attr of the widget view.
338 this._css_state[name] = value;
338 this._css_state[name] = value;
339 this.update_style_traits();
339 this.update_style_traits();
340 },
340 },
341
341
342 update_style_traits: function(button) {
342 update_style_traits: function(button) {
343 for (var name in this._css_state) {
343 for (var name in this._css_state) {
344 if (this._css_state.hasOwnProperty(name)) {
344 if (this._css_state.hasOwnProperty(name)) {
345 if (name == 'margin') {
345 if (name == 'margin') {
346 this.$buttongroup.css(name, this._css_state[name]);
346 this.$buttongroup.css(name, this._css_state[name]);
347 } else if (name != 'width') {
347 } else if (name != 'width') {
348 if (button) {
348 if (button) {
349 button.css(name, this._css_state[name]);
349 button.css(name, this._css_state[name]);
350 } else {
350 } else {
351 this.$buttongroup.find('button').css(name, this._css_state[name]);
351 this.$buttongroup.find('button').css(name, this._css_state[name]);
352 }
352 }
353 }
353 }
354 }
354 }
355 }
355 }
356 },
356 },
357
357
358 update_button_style: function(previous_trait_value) {
358 update_button_style: function(previous_trait_value) {
359 var class_map = {
359 var class_map = {
360 primary: ['btn-primary'],
360 primary: ['btn-primary'],
361 success: ['btn-success'],
361 success: ['btn-success'],
362 info: ['btn-info'],
362 info: ['btn-info'],
363 warning: ['btn-warning'],
363 warning: ['btn-warning'],
364 danger: ['btn-danger']
364 danger: ['btn-danger']
365 };
365 };
366 this.update_mapped_classes(class_map, 'button_style', previous_trait_value, this.$buttongroup.find('button'));
366 this.update_mapped_classes(class_map, 'button_style', previous_trait_value, this.$buttongroup.find('button'));
367 },
367 },
368
368
369 handle_click: function (e) {
369 handle_click: function (e) {
370 // Handle when a value is clicked.
370 // Handle when a value is clicked.
371
371
372 // Calling model.set will trigger all of the other views of the
372 // Calling model.set will trigger all of the other views of the
373 // model to update.
373 // model to update.
374 this.model.set('value_name', $(e.target).data('value'), {updated_view: this});
374 this.model.set('value_name', $(e.target).data('value'), {updated_view: this});
375 this.touch();
375 this.touch();
376 },
376 },
377 });
377 });
378
378
379
379
380 var SelectView = widget.DOMWidgetView.extend({
380 var SelectView = widget.DOMWidgetView.extend({
381 render : function(){
381 render : function(){
382 // Called when view is rendered.
382 // Called when view is rendered.
383 this.$el
383 this.$el
384 .addClass('widget-hbox widget-select');
384 .addClass('widget-hbox widget-select');
385 this.$label = $('<div />')
385 this.$label = $('<div />')
386 .appendTo(this.$el)
386 .appendTo(this.$el)
387 .addClass('widget-label')
387 .addClass('widget-label')
388 .hide();
388 .hide();
389 this.$listbox = $('<select />')
389 this.$listbox = $('<select />')
390 .addClass('widget-listbox form-control')
390 .addClass('widget-listbox form-control')
391 .attr('size', 6)
391 .attr('size', 6)
392 .appendTo(this.$el);
392 .appendTo(this.$el);
393 this.update();
393 this.update();
394 },
394 },
395
395
396 update : function(options){
396 update : function(options){
397 // Update the contents of this view
397 // Update the contents of this view
398 //
398 //
399 // Called when the model is changed. The model may have been
399 // Called when the model is changed. The model may have been
400 // changed by another view or by a state update from the back-end.
400 // changed by another view or by a state update from the back-end.
401 if (options === undefined || options.updated_view != this) {
401 if (options === undefined || options.updated_view != this) {
402 // Add missing items to the DOM.
402 // Add missing items to the DOM.
403 var items = this.model.get('value_names');
403 var items = this.model.get('value_names');
404 var that = this;
404 var that = this;
405 _.each(items, function(item, index) {
405 _.each(items, function(item, index) {
406 var item_query = ' :contains("' + item + '")';
406 var item_query = 'option[value_name="' + item + '"]';
407 if (that.$listbox.find(item_query).length === 0) {
407 if (that.$listbox.find(item_query).length === 0) {
408 $('<option />')
408 $('<option />')
409 .text(item)
409 .text(item)
410 .attr('value_name', item)
410 .attr('value_name', item)
411 .appendTo(that.$listbox)
411 .appendTo(that.$listbox)
412 .on('click', $.proxy(that.handle_click, that));
412 .on('click', $.proxy(that.handle_click, that));
413 }
413 }
414 });
414 });
415
415
416 // Select the correct element
416 // Select the correct element
417 this.$listbox.val(this.model.get('value_name'));
417 this.$listbox.val(this.model.get('value_name'));
418
418
419 // Disable listbox if needed
419 // Disable listbox if needed
420 var disabled = this.model.get('disabled');
420 var disabled = this.model.get('disabled');
421 this.$listbox.prop('disabled', disabled);
421 this.$listbox.prop('disabled', disabled);
422
422
423 // Remove items that no longer exist.
423 // Remove items that no longer exist.
424 this.$listbox.find('option').each(function(i, obj) {
424 this.$listbox.find('option').each(function(i, obj) {
425 var value = $(obj).text();
425 var value = $(obj).text();
426 var found = false;
426 var found = false;
427 _.each(items, function(item, index) {
427 _.each(items, function(item, index) {
428 if (item == value) {
428 if (item == value) {
429 found = true;
429 found = true;
430 return false;
430 return false;
431 }
431 }
432 });
432 });
433
433
434 if (!found) {
434 if (!found) {
435 $(obj).remove();
435 $(obj).remove();
436 }
436 }
437 });
437 });
438
438
439 var description = this.model.get('description');
439 var description = this.model.get('description');
440 if (description.length === 0) {
440 if (description.length === 0) {
441 this.$label.hide();
441 this.$label.hide();
442 } else {
442 } else {
443 this.$label.text(description);
443 this.$label.text(description);
444 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
444 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$label.get(0)]);
445 this.$label.show();
445 this.$label.show();
446 }
446 }
447 }
447 }
448 return SelectView.__super__.update.apply(this);
448 return SelectView.__super__.update.apply(this);
449 },
449 },
450
450
451 update_attr: function(name, value) {
451 update_attr: function(name, value) {
452 // Set a css attr of the widget view.
452 // Set a css attr of the widget view.
453 this.$listbox.css(name, value);
453 this.$listbox.css(name, value);
454 },
454 },
455
455
456 handle_click: function (e) {
456 handle_click: function (e) {
457 // Handle when a value is clicked.
457 // Handle when a value is clicked.
458
458
459 // Calling model.set will trigger all of the other views of the
459 // Calling model.set will trigger all of the other views of the
460 // model to update.
460 // model to update.
461 this.model.set('value_name', $(e.target).text(), {updated_view: this});
461 this.model.set('value_name', $(e.target).text(), {updated_view: this});
462 this.touch();
462 this.touch();
463 },
463 },
464 });
464 });
465
465
466 return {
466 return {
467 'DropdownView': DropdownView,
467 'DropdownView': DropdownView,
468 'RadioButtonsView': RadioButtonsView,
468 'RadioButtonsView': RadioButtonsView,
469 'ToggleButtonsView': ToggleButtonsView,
469 'ToggleButtonsView': ToggleButtonsView,
470 'SelectView': SelectView,
470 'SelectView': SelectView,
471 };
471 };
472 });
472 });
General Comments 0
You need to be logged in to leave comments. Login now