##// END OF EJS Templates
Support multiple types in selection widget.
Jonathan Frederic -
Show More
@@ -57,14 +57,14 b' define(["notebook/js/widgets/widget"], function(WidgetManager){'
57 // changed by another view or by a state update from the back-end.
57 // changed by another view or by a state update from the back-end.
58
58
59 if (options === undefined || options.updated_view != this) {
59 if (options === undefined || options.updated_view != this) {
60 var selected_item_text = this.model.get('value');
60 var selected_item_text = this.model.get('_value');
61 if (selected_item_text.length === 0) {
61 if (selected_item_text.length === 0) {
62 this.$droplabel.text(' ');
62 this.$droplabel.text(' ');
63 } else {
63 } else {
64 this.$droplabel.text(selected_item_text);
64 this.$droplabel.text(selected_item_text);
65 }
65 }
66
66
67 var items = this.model.get('values');
67 var items = this.model.get('_values');
68 var $replace_droplist = $('<ul />')
68 var $replace_droplist = $('<ul />')
69 .addClass('dropdown-menu');
69 .addClass('dropdown-menu');
70 var that = this;
70 var that = this;
@@ -107,7 +107,7 b' define(["notebook/js/widgets/widget"], function(WidgetManager){'
107
107
108 // Calling model.set will trigger all of the other views of the
108 // Calling model.set will trigger all of the other views of the
109 // model to update.
109 // model to update.
110 this.model.set('value', $(e.target).text(), {updated_view: this});
110 this.model.set('_value', $(e.target).text(), {updated_view: this});
111 this.touch();
111 this.touch();
112 },
112 },
113
113
@@ -139,7 +139,7 b' define(["notebook/js/widgets/widget"], function(WidgetManager){'
139 // changed by another view or by a state update from the back-end.
139 // changed by another view or by a state update from the back-end.
140 if (options === undefined || options.updated_view != this) {
140 if (options === undefined || options.updated_view != this) {
141 // Add missing items to the DOM.
141 // Add missing items to the DOM.
142 var items = this.model.get('values');
142 var items = this.model.get('_values');
143 var disabled = this.model.get('disabled');
143 var disabled = this.model.get('disabled');
144 var that = this;
144 var that = this;
145 _.each(items, function(item, index) {
145 _.each(items, function(item, index) {
@@ -159,7 +159,7 b' define(["notebook/js/widgets/widget"], function(WidgetManager){'
159 }
159 }
160
160
161 var $item_element = that.$container.find(item_query);
161 var $item_element = that.$container.find(item_query);
162 if (that.model.get('value') == item) {
162 if (that.model.get('_value') == item) {
163 $item_element.prop('checked', true);
163 $item_element.prop('checked', true);
164 } else {
164 } else {
165 $item_element.prop('checked', false);
165 $item_element.prop('checked', false);
@@ -199,7 +199,7 b' define(["notebook/js/widgets/widget"], function(WidgetManager){'
199
199
200 // Calling model.set will trigger all of the other views of the
200 // Calling model.set will trigger all of the other views of the
201 // model to update.
201 // model to update.
202 this.model.set('value', $(e.target).val(), {updated_view: this});
202 this.model.set('_value', $(e.target).val(), {updated_view: this});
203 this.touch();
203 this.touch();
204 },
204 },
205 });
205 });
@@ -230,7 +230,7 b' define(["notebook/js/widgets/widget"], function(WidgetManager){'
230 // changed by another view or by a state update from the back-end.
230 // changed by another view or by a state update from the back-end.
231 if (options === undefined || options.updated_view != this) {
231 if (options === undefined || options.updated_view != this) {
232 // Add missing items to the DOM.
232 // Add missing items to the DOM.
233 var items = this.model.get('values');
233 var items = this.model.get('_values');
234 var disabled = this.model.get('disabled');
234 var disabled = this.model.get('disabled');
235 var that = this;
235 var that = this;
236 _.each(items, function(item, index) {
236 _.each(items, function(item, index) {
@@ -245,7 +245,7 b' define(["notebook/js/widgets/widget"], function(WidgetManager){'
245 }
245 }
246
246
247 var $item_element = that.$buttongroup.find(item_query);
247 var $item_element = that.$buttongroup.find(item_query);
248 if (that.model.get('value') == item) {
248 if (that.model.get('_value') == item) {
249 $item_element.addClass('active');
249 $item_element.addClass('active');
250 } else {
250 } else {
251 $item_element.removeClass('active');
251 $item_element.removeClass('active');
@@ -285,7 +285,7 b' define(["notebook/js/widgets/widget"], function(WidgetManager){'
285
285
286 // Calling model.set will trigger all of the other views of the
286 // Calling model.set will trigger all of the other views of the
287 // model to update.
287 // model to update.
288 this.model.set('value', $(e.target).text(), {updated_view: this});
288 this.model.set('_value', $(e.target).text(), {updated_view: this});
289 this.touch();
289 this.touch();
290 },
290 },
291 });
291 });
@@ -316,21 +316,21 b' define(["notebook/js/widgets/widget"], function(WidgetManager){'
316 // changed by another view or by a state update from the back-end.
316 // changed by another view or by a state update from the back-end.
317 if (options === undefined || options.updated_view != this) {
317 if (options === undefined || options.updated_view != this) {
318 // Add missing items to the DOM.
318 // Add missing items to the DOM.
319 var items = this.model.get('values');
319 var items = this.model.get('_values');
320 var that = this;
320 var that = this;
321 _.each(items, function(item, index) {
321 _.each(items, function(item, index) {
322 var item_query = ' :contains("' + item + '")';
322 var item_query = ' :contains("' + item + '")';
323 if (that.$listbox.find(item_query).length === 0) {
323 if (that.$listbox.find(item_query).length === 0) {
324 $('<option />')
324 $('<option />')
325 .text(item)
325 .text(item)
326 .attr('value', item)
326 .attr('_value', item)
327 .appendTo(that.$listbox)
327 .appendTo(that.$listbox)
328 .on('click', $.proxy(that.handle_click, that));
328 .on('click', $.proxy(that.handle_click, that));
329 }
329 }
330 });
330 });
331
331
332 // Select the correct element
332 // Select the correct element
333 this.$listbox.val(this.model.get('value'));
333 this.$listbox.val(this.model.get('_value'));
334
334
335 // Disable listbox if needed
335 // Disable listbox if needed
336 var disabled = this.model.get('disabled');
336 var disabled = this.model.get('disabled');
@@ -368,7 +368,7 b' define(["notebook/js/widgets/widget"], function(WidgetManager){'
368
368
369 // Calling model.set will trigger all of the other views of the
369 // Calling model.set will trigger all of the other views of the
370 // model to update.
370 // model to update.
371 this.model.set('value', $(e.target).text(), {updated_view: this});
371 this.model.set('_value', $(e.target).text(), {updated_view: this});
372 this.touch();
372 this.touch();
373 },
373 },
374 });
374 });
@@ -13,18 +13,76 b' Represents an enumeration using a widget.'
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 from threading import Lock
17
16 from .widget import DOMWidget
18 from .widget import DOMWidget
17 from IPython.utils.traitlets import Unicode, List, Bool
19 from IPython.utils.traitlets import Unicode, List, Bool, Any, Dict
18
20
19 #-----------------------------------------------------------------------------
21 #-----------------------------------------------------------------------------
20 # SelectionWidget
22 # SelectionWidget
21 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
22 class _SelectionWidget(DOMWidget):
24 class _SelectionWidget(DOMWidget):
23 value = Unicode(help="Selected value", sync=True) # TODO: Any support
25 value = Any(help="Selected value")
24 values = List(help="List of values the user can select", sync=True)
26 values = List(help="List of values the user can select")
27 value_names = Dict(help="""List of string representations for each value.
28 These string representations are used to display the values in the
29 front-end.""")
25 disabled = Bool(False, help="Enable or disable user changes", sync=True)
30 disabled = Bool(False, help="Enable or disable user changes", sync=True)
26 description = Unicode(help="Description of the value this widget represents", sync=True)
31 description = Unicode(help="Description of the value this widget represents", sync=True)
27
32
33 _value = Unicode(sync=True) # Bi-directionally synced.
34 _values = List(sync=True) # Only back-end to front-end synced.
35 _reverse_value_names = Dict()
36
37 def __init__(self, *pargs, **kwargs):
38 """Constructor"""
39 DOMWidget.__init__(self, *pargs, **kwargs)
40 self.value_lock = Lock()
41 self.on_trait_change(self._string_value_set, ['_value'])
42
43 def _value_names_changed(self, name=None, old=None, new=None):
44 """Handles when the value_names Dict has been changed.
45
46 This method sets the _reverse_value_names Dict to the inverse of the new
47 value for the value_names Dict."""
48 self._reverse_value_names = {v:k for k, v in self.value_names.items()}
49 self._values_changed()
50
51 def _values_changed(self, name=None, old=None, new=None):
52 """Called when values has been changed"""
53 self._values = [self._get_string_repr(v) for v in self.values]
54
55 def _value_changed(self, name, old, new):
56 """Called when value has been changed"""
57 if self.value_lock.acquire(False):
58 try:
59 # Make sure the value is in the list of values.
60 if new in self.values:
61 # Set the string version of the value.
62 self._value = self._get_string_repr(new)
63 else:
64 raise TypeError('Value must be a value in the values list.')
65 finally:
66 self.value_lock.release()
67
68 def _get_string_repr(self, value):
69 """Get the string repr of a value"""
70 if value not in self.value_names:
71 self.value_names[value] = str(value)
72 self._value_names_changed()
73 return self.value_names[value]
74
75 def _string_value_set(self, name, old, new):
76 """Called when _value has been changed."""
77 if self.value_lock.acquire(False):
78 try:
79 if new in self._reverse_value_names:
80 self.value = self._reverse_value_names[new]
81 else:
82 self.value = None
83 finally:
84 self.value_lock.release()
85
28
86
29 class ToggleButtonsWidget(_SelectionWidget):
87 class ToggleButtonsWidget(_SelectionWidget):
30 view_name = Unicode('ToggleButtonsView', sync=True)
88 view_name = Unicode('ToggleButtonsView', sync=True)
General Comments 0
You need to be logged in to leave comments. Login now