Personal tools
You are here: Home Documentation Tutorials Working with Forms in Grok Customising individual Form Fields

Customising individual Form Fields

Learn how to customise individual form fields.
A walkthrough of the basics of automatically generating HTML forms using Grok, as well as a discussion of a few more advanced Form manipulations.
Page 6 of 9.

Form fields are rendered into HTML by widgets. A widget is similar to a view, except that they are designed to work specifically upon schema fields.

For example, a Text schema field has a TextAreaWidget that is used for input. A DateTime schema field has a DateTimeWidget and a DateTimeDisplayWidget, depending upon whether the field is meant for input or is being displayed as read-only.

The setupWidgets method of the Form class is automatically called for you before the form is rendered. This method is intended to be overridden, so that you can customise the input or display of individual form fields by using modified or different widgets.

def setUpWidgets(self, ignore_request = False):
    super(MammothForm, self).setUpWidgets(ignore_request)
    self.widgets['furryness'].width = 20

When overridding setupWidgets, first use super() to call the default setupWidgets method. This will set a widgets attribute on your form, and each widget can be referred to by the name of the form field that it is rendering.

In the Mammoth manager application, we want to make the TextArea widget used for the furryness field smaller. We also want to display both the title and the description from the schema field for the weight attribute.

class MammothForm(grok.AddForm):
    grok.context(MammothApplication)
    grok.name('index')
    form_fields = grok.AutoFields(Mammoth)
    label = "Let's Make a Mammoth"
    template = grok.PageTemplateFile('custom_edit_form.pt')

    def setUpWidgets(self, ignore_request = False):
        super(MammothForm, self).setUpWidgets(ignore_request)
        self.widgets['furryness'].width = 20
        self.widgets['furryness'].height = 3
        self.widgets['weight'].label = '%s (%s)' % (
            self.form_fields['weight'].field.title,
            self.form_fields['weight'].field.description,
        )

    @grok.action('Add Mammoth')
    def add(self, **data):
        mammoth = Mammoth()
        self.applyData(mammoth, **data)
        import datetime
        name = str(datetime.datetime.now()).replace(' ','-')
        self.context[name] = mammoth
        return self.redirect(self.url(self.context[name]))

Now we have a smaller text box, and a custom label for the weight:

customwidgets.jpg

Remember that every form field is going to have a field attribute that refers to the schema field that the form field is being applied to. Form fields and the widgets used to render each of those fields are unique to every form in your application. The schema fields however are global and are typically used to describe your data model, and this information may be used by many different components. You want to make sure that you only modify form fields and widgets within your form and never modify a schema field. Otherwise these changes will likely produce unwanted side-effects.