wiki:S3/S3SQLForm

Version 14 (modified by Fran Boon, 12 years ago) ( diff )

No longer Beta

S3SQLForm

By default, S3CRUD generates create/update forms based on introspection of the table: all fields which are set to either readable or writable will be included in the form, in the order in which they are defined in the table.

This default form can be replaced by setting the "crud_form" hook to an instance of S3SQLCustomForm (e.g. in the controller), which allows you to explicitly select the fields and the order in which they appear in the form, and even to include fields from components.

S3CRUD will then use this form definition instead of the default form.

Example:

def inline():

    from s3.s3forms import S3SQLCustomForm, S3SQLInlineComponent

    crud_form = S3SQLCustomForm(
                    "first_name",
                    "last_name",
                    S3SQLInlineComponent(
                        "contact",
                        name="test",
                        label=T("Contact Information"),
                        fields=["contact_method", "value"]
                    ),
                    "age_group",
                    "date_of_birth",
                    S3SQLInlineComponent(
                        "note",
                        label=T("Notes"),
                        fields=["timestmp", "note_text"]
                    ),
                    "identification.status"
                    )

    s3db.configure("pr_person", crud_form=crud_form)

    return s3_rest_controller("pr", "person")

Syntax

S3SQLCustomForm takes instances of subclasses of S3SQLFormElement as parameters. Currently implemented S3SQLFormElement subclasses are:

ClassForm Element
S3SQLFieldRegular form widget for fields in either the main table or in a subtable (single-record component)
S3SQLInlineComponentA subform for multi-record components

Strings in the parameter list will be interpreted as field selectors, and used to instantiate S3SQLFields for the fields they address. Note that only fields in the main table or single-record components can be specified this way - everything else will raise a SyntaxError.

The order in which the form elements appear in the parameter list determines the order in which they appear in the form.

Form elements or actions which the user is not permitted to access will be rendered either read-only or not at all (according to the actual permission). The same applies for elements (e.g. components) which are deactivated in the deployment.

Regular Fields

Regular fields in the main table can be specified simply by their field name.

    crud_form = S3SQLCustomForm(
                    "first_name",
                    "last_name",
                    "age_group",
                    "date_of_birth",
                    )

Fields can be specified in arbitrary order, but must not be repeated within the list.

Fields in Subtables

Fields in components which are set to multiple=False (single-record components = sub-tables) can also be specified as field selector strings using the "."-notation:

    crud_form = S3SQLCustomForm(
                    "identification.status"
                    )

Fields from single-record components can be specified anywhere in the form elements list, they do not need to stand together or at a particular place in the field order. However - the same field must not be repeated.

The form element will use the default widget for the respective field in the subtable.

If the user is not permitted to access this component, then the widget will not be rendered at all. If the user has only read access, it will be rendered read-only.

Inline Components

Components with multiple=True (multi-record components) can be specified as instances of S3SQLInlineComponent:

    crud_form = S3SQLCustomForm(
                    S3SQLInlineComponent(
                        "contact",
                        name="test",
                        label=T("Contact Information"),
                        fields=["contact_method", "value"]
                    ),
                    S3SQLInlineComponent(
                        "note",
                        label=T("Notes"),
                        fields=["timestmp", "note_text"]
                    ),
                    )

These form elements will be rendered as embedded tables of the existing records in the component with the option to add, update and delete rows (depending on permissions for this components).

Arguments

The first argument of S3SQLInlineComponent is the resource alias name (usually the tablename without module prefix).

You can also specify a label (title) for the subform using the "label" argument (optional)

The "fields" argument specifies the fields to display in the subform, and the order in which they shall appear. This argument is required.

Filtering of Inline-Components

To filter an inline component by e.g. type, you can a filterby option like in:

    S3SQLInlineComponent(
        "contact",
        name="email",
        label=T("Email Addresses"),
        fields=["value"],
        filterby = dict(
            field = "contact_method",
            options = "EMAIL"
        )
    ),

The filterby settings is a dict (or a list of dicts for multiple filters), containing:

AttributeExplanation
fieldthe name of field to filter by
optionsthe allowed options for this field, a single value or a list of values
invertTrue to invert this filter (default False)
defaultdefault value for this field (if only one option is given and invert is False, then that option will automatically be the default value - unless you specify something else)

Where multiple sub-forms for the same component (but with different filters) shall be embedded, they must each have a distinct "name" argument. Otherwise this argument is optional.

Sorting of Inline-Components

It is possible to sort the inline-items by specifying an orderby option with a field selector relative to the component table:

    s3forms.S3SQLInlineComponent(
        "location",
        label = T("Countries"),
        fields = ["location_id"],
        orderby = "location_id$name"
    ),

To specify a different sort order, the orderby-option also accepts a tuple like:

    s3forms.S3SQLInlineComponent(
        "location",
        label = T("Countries"),
        fields = ["location_id"],
        orderby = ("location_id$name", "desc")
    ),

The sort order defaults to "asc".

Note: the field selector used in orderby must give exactly one value per row (i.e. use only forward-links, not component fields or list:types), otherwise the same component item would appear multiple times in the form (due to the left join involved).

Note: the sorting always only affects existing items - new items would still be added at the end of the inline component.


Note: See TracWiki for help on using the wiki.