fix: add way to set field widgets using pseudo-type
more to come on this idea hopefully..i think it's a good pattern?
This commit is contained in:
parent
bf8397ba23
commit
eda2326a97
|
@ -457,23 +457,62 @@ class Form:
|
|||
if self.schema:
|
||||
self.schema[key] = node
|
||||
|
||||
def set_widget(self, key, widget):
|
||||
def set_widget(self, key, widget, **kwargs):
|
||||
"""
|
||||
Set/override the widget for a field.
|
||||
|
||||
You can specify a widget instance or else a named "type" of
|
||||
widget, in which case that is passed along to
|
||||
:meth:`make_widget()`.
|
||||
|
||||
:param key: Name of field.
|
||||
|
||||
:param widget: Instance of
|
||||
:class:`deform:deform.widget.Widget`.
|
||||
:param widget: Either a :class:`deform:deform.widget.Widget`
|
||||
instance, or else a widget "type" name.
|
||||
|
||||
:param \**kwargs: Any remaining kwargs are passed along to
|
||||
:meth:`make_widget()` - if applicable.
|
||||
|
||||
Widget overrides are tracked via :attr:`widgets`.
|
||||
"""
|
||||
if not isinstance(widget, deform.widget.Widget):
|
||||
widget_obj = self.make_widget(widget, **kwargs)
|
||||
if not widget_obj:
|
||||
raise ValueError(f"widget type not supported: {widget}")
|
||||
widget = widget_obj
|
||||
|
||||
self.widgets[key] = widget
|
||||
|
||||
# update schema if necessary
|
||||
if self.schema and key in self.schema:
|
||||
self.schema[key].widget = widget
|
||||
|
||||
def make_widget(self, widget_type, **kwargs):
|
||||
"""
|
||||
Make and return a new field widget of the given type.
|
||||
|
||||
This has built-in support for the following types (although
|
||||
subclass can override as needed):
|
||||
|
||||
* ``'notes'`` => :class:`~wuttaweb.forms.widgets.NotesWidget`
|
||||
|
||||
See also :meth:`set_widget()` which may call this method
|
||||
automatically.
|
||||
|
||||
:param widget_type: Which of the above (or custom) widget
|
||||
type to create.
|
||||
|
||||
:param \**kwargs: Remaining kwargs are passed as-is to the
|
||||
widget factory.
|
||||
|
||||
:returns: New widget instance, or ``None`` if e.g. it could
|
||||
not determine how to create the widget.
|
||||
"""
|
||||
from wuttaweb.forms import widgets
|
||||
|
||||
if widget_type == 'notes':
|
||||
return widgets.NotesWidget(**kwargs)
|
||||
|
||||
def set_grid(self, key, grid):
|
||||
"""
|
||||
Establish a :term:`grid` to be displayed for a field. This
|
||||
|
|
|
@ -34,7 +34,6 @@ from sqlalchemy import orm
|
|||
|
||||
from wuttjamaican.db.model import Upgrade
|
||||
from wuttaweb.views import MasterView
|
||||
from wuttaweb.forms import widgets
|
||||
from wuttaweb.forms.schema import UserRef, WuttaEnum, FileDownload
|
||||
from wuttaweb.progress import get_progress_session
|
||||
|
||||
|
@ -147,7 +146,7 @@ class UpgradeView(MasterView):
|
|||
f.set_node('created_by', UserRef(self.request))
|
||||
|
||||
# notes
|
||||
f.set_widget('notes', widgets.NotesWidget())
|
||||
f.set_widget('notes', 'notes')
|
||||
|
||||
# status
|
||||
if self.creating:
|
||||
|
|
|
@ -142,6 +142,26 @@ class TestForm(TestCase):
|
|||
self.assertIs(form.widgets['foo'], new_widget)
|
||||
self.assertIs(schema['foo'].widget, new_widget)
|
||||
|
||||
# can also just specify widget pseudo-type (invalid)
|
||||
self.assertNotIn('bar', form.widgets)
|
||||
self.assertRaises(ValueError, form.set_widget, 'bar', 'ldjfadjfadj')
|
||||
|
||||
# can also just specify widget pseudo-type (valid)
|
||||
self.assertNotIn('bar', form.widgets)
|
||||
form.set_widget('bar', 'notes')
|
||||
self.assertIsInstance(form.widgets['bar'], widgets.NotesWidget)
|
||||
|
||||
def test_make_widget(self):
|
||||
form = self.make_form(fields=['foo', 'bar'])
|
||||
|
||||
# notes
|
||||
widget = form.make_widget('notes')
|
||||
self.assertIsInstance(widget, widgets.NotesWidget)
|
||||
|
||||
# invalid
|
||||
widget = form.make_widget('fdajvdafjjf')
|
||||
self.assertIsNone(widget)
|
||||
|
||||
def test_set_grid(self):
|
||||
form = self.make_form(fields=['foo', 'bar'])
|
||||
self.assertNotIn('foo', form.widgets)
|
||||
|
|
Loading…
Reference in a new issue