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:
 | 
			
		||||
            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…
	
	Add table
		Add a link
		
	
		Reference in a new issue