= Noneable widgets = In the spirit of Postel's Law, the Noneable widgets permits users to enter just whitespace, while ensuring that the schema's field value is None. == Noneable TextLine widget == This custom widget is used to normalise the value of meaning less text value to None. >>> from lp.app.widgets.textwidgets import NoneableTextWidget The IMilestone code_name field cannot be an empty string or a string composed of whitespace; the value is considered to be None. >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest >>> from lp.registry.interfaces.milestone import IMilestone >>> field = IMilestone['code_name'] >>> request = LaunchpadTestRequest( ... form={'field.code_name' : ' '}) >>> widget = NoneableTextWidget(field, request) The widget converted the meaningless value to None. >>> print widget.getInputValue() None Excess whitespace and newlines are stripped. >>> request = LaunchpadTestRequest( ... form={'field.code_name' : ' flower \n'}) >>> widget = NoneableTextWidget(field, request) >>> print widget.getInputValue() flower == Noneable Description widget == This custom widget is used to normalise the value of meaning less text value to None. >>> from lp.app.widgets.textwidgets import ( ... NoneableDescriptionWidget) The IMilestone description field cannot be an empty string or a string composed of whitespace; the value is considered to be None. >>> field = IMilestone['summary'] >>> request = LaunchpadTestRequest( ... form={'field.summary' : ' '}) >>> widget = NoneableDescriptionWidget(field, request) The widget converted the meaningless value to None. >>> print widget.getInputValue() None Excess whitespace is stripped, but newlines are preserved. >>> request = LaunchpadTestRequest( ... form={'field.summary' : ' flower \n grass '}) >>> widget = NoneableDescriptionWidget(field, request) >>> widget.getInputValue() u'flower \n grass'