= The Project Scope Widget = Many application front pages contain a search form. The search can usually be across the whole Launchpad or only in one project. The ProjectScopeWidget is used to select that scope. The scope type is actually determined by the field's vocabulary. In this example, we will use the Project vocabulary which allows any project to be selected. >>> from zope.schema import Choice >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest >>> from canonical.launchpad.webapp.testing import verifyObject >>> from lp.app.widgets.project import ProjectScopeWidget >>> empty_request = LaunchpadTestRequest() >>> scope_field = Choice( ... __name__='scope', vocabulary='ProjectGroup', required=False) >>> scope_field = scope_field.bind(object()) >>> widget = ProjectScopeWidget( ... scope_field, scope_field.vocabulary, empty_request) The widget complies to both IInputWidget and IBrowserWidget. >>> from zope.app.form.browser.interfaces import IBrowserWidget >>> from zope.app.form.interfaces import IInputWidget >>> verifyObject(IInputWidget, widget) True >>> verifyObject(IBrowserWidget, widget) True When the request is empty, the widget doesn't have any input: >>> widget.hasInput() False >>> widget.hasValidInput() False It's a radio widget, so it assumes that it always will have input. If the widget isn't required, getInputValue() returns None if there isn't any input. >>> widget.required False >>> widget.getInputValue() is None True If the widget is required, getInputValue() raises UnexpectedFormData if there is no input. >>> widget.required = True >>> widget.getInputValue() Traceback (most recent call last): ... UnexpectedFormData: No valid option was selected. By default, the 'All projects' scope is selected: >>> print widget()