diff --git a/IPython/html/static/notebook/js/widgets/selection.js b/IPython/html/static/notebook/js/widgets/selection.js index 77de43cd4..61c328faa 100644 --- a/IPython/html/static/notebook/js/widgets/selection.js +++ b/IPython/html/static/notebook/js/widgets/selection.js @@ -274,4 +274,82 @@ define(["notebook/js/widget"], function(widget_manager){ }); widget_manager.register_widget_view('ToggleButtonsView', ToggleButtonsView); + + var ListBoxView = IPython.WidgetView.extend({ + + // Called when view is rendered. + render : function(){ + this.$el + .addClass('widget-hbox') + .html(''); + this.$label = $('
') + .appendTo(this.$el) + .addClass('widget-hlabel') + .hide(); + this.$listbox = $('') + .addClass('widget-listbox') + .attr('size', 6) + .appendTo(this.$el); + this.$el_to_style = this.$listbox; // Set default element to style + this.update(); + }, + + // Handles: Backend -> Frontend Sync + // Frontent -> Frontend Sync + update : function(){ + + // Add missing items to the DOM. + var items = this.model.get('values'); + for (var index in items) { + var item_query = ' :contains("' + items[index] + '")'; + if (this.$listbox.find(item_query).length == 0) { + + var that = this; + $('') + .html(items[index]) + .attr('value', items[index]) + .appendTo(this.$listbox) + .on('click', function(e){ + that.model.set('value', $(e.target).html(), this); + that.model.update_other_views(that); + }); + } + } + + // Select the correct element + this.$listbox.val(this.model.get('value')); + + // Disable listbox if needed + var disabled = this.model.get('disabled'); + this.$listbox.prop('disabled', disabled); + + // Remove items that no longer exist. + this.$listbox.find('option').each(function(i, obj) { + var value = $(obj).html(); + var found = false; + for (var index in items) { + if (items[index] == value) { + found = true; + break; + } + } + + if (!found) { + $(obj).remove(); + } + }); + + var description = this.model.get('description'); + if (description.length == 0) { + this.$label.hide(); + } else { + this.$label.html(description); + this.$label.show(); + } + return IPython.WidgetView.prototype.update.call(this); + }, + + }); + + widget_manager.register_widget_view('ListBoxView', ListBoxView); }); diff --git a/IPython/html/static/notebook/less/widgets.less b/IPython/html/static/notebook/less/widgets.less index 7de290c00..f75a9b548 100644 --- a/IPython/html/static/notebook/less/widgets.less +++ b/IPython/html/static/notebook/less/widgets.less @@ -149,6 +149,12 @@ The widget area typically looks something like this: margin-bottom: 0px; } + /* Listbox */ + .widget-listbox { + width: 364px; + margin-bottom: 0px; + } + /* Single Line Textbox - used for IntTextView and FloatTextView */ .widget-numeric-text { width: 150px; diff --git a/examples/widgets/Part 1 - Basics.ipynb b/examples/widgets/Part 1 - Basics.ipynb index d24d53188..643d5d1ae 100644 --- a/examples/widgets/Part 1 - Basics.ipynb +++ b/examples/widgets/Part 1 - Basics.ipynb @@ -311,6 +311,7 @@ "| SelectionWidget | ToggleButtonsView |\n", "| | RadioButtonsView |\n", "| | *DropdownView* |\n", + "| | ListBoxView |\n", "| StringWidget | LabelView |\n", "| | TextAreaView |\n", "| | *TextBoxView* |\n"