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
					
				
					 3 changed files with 63 additions and 5 deletions
				
			
		| 
						 | 
					@ -457,23 +457,62 @@ class Form:
 | 
				
			||||||
        if self.schema:
 | 
					        if self.schema:
 | 
				
			||||||
            self.schema[key] = node
 | 
					            self.schema[key] = node
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def set_widget(self, key, widget):
 | 
					    def set_widget(self, key, widget, **kwargs):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Set/override the widget for a field.
 | 
					        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 key: Name of field.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        :param widget: Instance of
 | 
					        :param widget: Either a :class:`deform:deform.widget.Widget`
 | 
				
			||||||
           :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`.
 | 
					        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
 | 
					        self.widgets[key] = widget
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # update schema if necessary
 | 
					        # update schema if necessary
 | 
				
			||||||
        if self.schema and key in self.schema:
 | 
					        if self.schema and key in self.schema:
 | 
				
			||||||
            self.schema[key].widget = widget
 | 
					            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):
 | 
					    def set_grid(self, key, grid):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        Establish a :term:`grid` to be displayed for a field.  This
 | 
					        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 wuttjamaican.db.model import Upgrade
 | 
				
			||||||
from wuttaweb.views import MasterView
 | 
					from wuttaweb.views import MasterView
 | 
				
			||||||
from wuttaweb.forms import widgets
 | 
					 | 
				
			||||||
from wuttaweb.forms.schema import UserRef, WuttaEnum, FileDownload
 | 
					from wuttaweb.forms.schema import UserRef, WuttaEnum, FileDownload
 | 
				
			||||||
from wuttaweb.progress import get_progress_session
 | 
					from wuttaweb.progress import get_progress_session
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -147,7 +146,7 @@ class UpgradeView(MasterView):
 | 
				
			||||||
            f.set_node('created_by', UserRef(self.request))
 | 
					            f.set_node('created_by', UserRef(self.request))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # notes
 | 
					        # notes
 | 
				
			||||||
        f.set_widget('notes', widgets.NotesWidget())
 | 
					        f.set_widget('notes', 'notes')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # status
 | 
					        # status
 | 
				
			||||||
        if self.creating:
 | 
					        if self.creating:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -142,6 +142,26 @@ class TestForm(TestCase):
 | 
				
			||||||
        self.assertIs(form.widgets['foo'], new_widget)
 | 
					        self.assertIs(form.widgets['foo'], new_widget)
 | 
				
			||||||
        self.assertIs(schema['foo'].widget, 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):
 | 
					    def test_set_grid(self):
 | 
				
			||||||
        form = self.make_form(fields=['foo', 'bar'])
 | 
					        form = self.make_form(fields=['foo', 'bar'])
 | 
				
			||||||
        self.assertNotIn('foo', form.widgets)
 | 
					        self.assertNotIn('foo', form.widgets)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue