diff --git a/IPython/html/static/style/ipython.min.css b/IPython/html/static/style/ipython.min.css index e590069..a1eaa0c 100644 --- a/IPython/html/static/style/ipython.min.css +++ b/IPython/html/static/style/ipython.min.css @@ -1477,6 +1477,12 @@ h6:hover .anchor-link { .widget_item .dropdown-menu li a { color: inherit; } +.widget-valid { + margin-top: 9px; + margin-bottom: 10px; + margin-left: 3px; + margin-right: 3px; +} .widget-hbox { /* Horizontal widgets */ /* Old browsers */ diff --git a/IPython/html/static/style/style.min.css b/IPython/html/static/style/style.min.css index f505adb..12f5af1 100644 --- a/IPython/html/static/style/style.min.css +++ b/IPython/html/static/style/style.min.css @@ -10269,6 +10269,12 @@ h6:hover .anchor-link { .widget_item .dropdown-menu li a { color: inherit; } +.widget-valid { + margin-top: 9px; + margin-bottom: 10px; + margin-left: 3px; + margin-right: 3px; +} .widget-hbox { /* Horizontal widgets */ /* Old browsers */ diff --git a/IPython/html/static/widgets/js/widget_bool.js b/IPython/html/static/widgets/js/widget_bool.js index dc107ec..e576e28 100644 --- a/IPython/html/static/widgets/js/widget_bool.js +++ b/IPython/html/static/widgets/js/widget_bool.js @@ -41,19 +41,19 @@ define([ /** * Handles when the checkbox is clicked. * - * Calling model.set will trigger all of the other views of the + * Calling model.set will trigger all of the other views of the * model to update. */ var value = this.model.get('value'); this.model.set('value', ! value, {updated_view: this}); this.touch(); }, - + update : function(options){ /** * Update the contents of this view * - * Called when the model is changed. The model may have been + * Called when the model is changed. The model may have been * changed by another view or by a state update from the back-end. */ this.$checkbox.prop('checked', this.model.get('value')); @@ -71,7 +71,6 @@ define([ } return CheckboxView.__super__.update.apply(this); }, - }); @@ -107,12 +106,12 @@ define([ }; this.update_mapped_classes(class_map, 'button_style', previous_trait_value); }, - + update : function(options){ /** * Update the contents of this view * - * Called when the model is changed. The model may have been + * Called when the model is changed. The model may have been * changed by another view or by a state update from the back-end. */ if (this.model.get('value')) { @@ -136,12 +135,12 @@ define([ } return ToggleButtonView.__super__.update.apply(this); }, - - handle_click: function(e) { + + handle_click: function(e) { /** * Handles and validates user input. * - * Calling model.set will trigger all of the other views of the + * Calling model.set will trigger all of the other views of the * model to update. */ var value = this.model.get('value'); @@ -150,8 +149,45 @@ define([ }, }); + + var ValidView = widget.DOMWidgetView.extend({ + render: function() { + /** + * Called when view is rendered. + */ + this.$el.addClass("widget-valid"); + this.model.on("change", this.update, this); + this.update(); + }, + update: function() { + /** + * Update the contents of this view + * + * Called when the model is changed. The model may have been + * changed by another view or by a state update from the back-end. + */ + var icon, color, readout; + if (this.model.get("value")) { + icon = "fa-check"; + color = "green"; + readout = ""; + } else { + icon = "fa-close"; + color = "red"; + readout = this.model.get("readout"); + } + this.$el.text(readout); + $('').prependTo(this.$el).addClass(icon); + this.after_displayed(function() { + this.$el.css("color", color); + }, this); + } + }); + + return { 'CheckboxView': CheckboxView, 'ToggleButtonView': ToggleButtonView, + 'ValidView': ValidView, }; }); diff --git a/IPython/html/static/widgets/less/widgets.less b/IPython/html/static/widgets/less/widgets.less index 0e8d4bf..7c589f7 100644 --- a/IPython/html/static/widgets/less/widgets.less +++ b/IPython/html/static/widgets/less/widgets.less @@ -209,6 +209,13 @@ color: inherit; } +.widget-valid { + margin-top: 9px; + margin-bottom: 10px; + margin-left: 3px; + margin-right: 3px; +} + .widget-hbox { /* Horizontal widgets */ .hbox(); diff --git a/IPython/html/widgets/__init__.py b/IPython/html/widgets/__init__.py index bd8d237..bf9a421 100644 --- a/IPython/html/widgets/__init__.py +++ b/IPython/html/widgets/__init__.py @@ -2,7 +2,7 @@ from .widget import Widget, DOMWidget, CallbackDispatcher, register from .trait_types import Color -from .widget_bool import Checkbox, ToggleButton +from .widget_bool import Checkbox, ToggleButton, Valid from .widget_button import Button from .widget_box import Box, FlexBox, HBox, VBox from .widget_float import FloatText, BoundedFloatText, FloatSlider, FloatProgress, FloatRangeSlider diff --git a/IPython/html/widgets/widget_bool.py b/IPython/html/widgets/widget_bool.py index 976c721..a74aacc 100644 --- a/IPython/html/widgets/widget_bool.py +++ b/IPython/html/widgets/widget_bool.py @@ -60,17 +60,30 @@ class ToggleButton(_Bool): icon: str font-awesome icon name """ - _view_name = Unicode('ToggleButtonView', sync=True) tooltip = Unicode(help="Tooltip caption of the toggle button.", sync=True) icon = Unicode('', help= "Font-awesome icon.", sync=True) button_style = CaselessStrEnum( - values=['primary', 'success', 'info', 'warning', 'danger', ''], + values=['primary', 'success', 'info', 'warning', 'danger', ''], default_value='', allow_none=True, sync=True, help="""Use a predefined styling for the button.""") +@register('IPython.Valid') +class Valid(_Bool): + + """Displays a boolean `value` in the form of a green check (True / valid) + or a red cross (False / invalid). + + Parameters + ---------- + value: {True,False} + value of the Valid widget +""" + readout = Unicode(help="Message displayed when the value is False", sync=True) + _view_name = Unicode('ValidView', sync=True) + # Remove in IPython 4.0 CheckboxWidget = DeprecatedClass(Checkbox, 'CheckboxWidget') ToggleButtonWidget = DeprecatedClass(ToggleButton, 'ToggleButtonWidget')