Horizon Forms

Horizon ships with some very useful base form classes, form fields, class-based views, and javascript helpers which streamline most of the common tasks related to form handling.

Form Classes

class horizon.forms.base.DateForm(*args, **kwargs)[source]

A simple form for selecting a start date.

class horizon.forms.base.SelfHandlingForm(request, *args, **kwargs)[source]

A base Form class which includes processing logic in its subclasses.

api_error(message)[source]

Adds an error to the form’s error dictionary after validation based on problems reported via the API. This is useful when you wish for API errors to appear as errors on the form rather than using the messages framework.

Form Fields

class horizon.forms.fields.DynamicChoiceField(add_item_link=None, add_item_link_args=None, *args, **kwargs)[source]

A subclass of ChoiceField with additional properties that make dynamically updating its elements easier.

Notably, the field declaration takes an extra argument, add_item_link which may be a string or callable defining the URL that should be used for the “add” link associated with the field.

widget

alias of DynamicSelectWidget

class horizon.forms.fields.DynamicSelectWidget(attrs=None, choices=())[source]

A subclass of the Select widget which renders extra attributes for use in callbacks to handle dynamic changes to the available choices.

class horizon.forms.fields.DynamicTypedChoiceField(add_item_link=None, add_item_link_args=None, *args, **kwargs)[source]

Simple mix of DynamicChoiceField and TypedChoiceField.

Form Views

class horizon.forms.views.ModalFormView(**kwargs)[source]

The main view class from which all views which handle forms in Horizon should inherit. It takes care of all details with processing SelfHandlingForm classes, and modal concerns when the associated template inherits from horizon/common/_modal_form.html.

Subclasses must define a form_class and template_name attribute at minimum.

See Django’s documentation on the FormView class for more details.

get_form(form_class)[source]

Returns an instance of the form to be used in this view.

get_object_display(obj)[source]

For dynamic insertion of resources created in modals, this method returns the display name of the created object. Defaults to returning the name attribute.

get_object_id(obj)[source]

For dynamic insertion of resources created in modals, this method returns the id of the created object. Defaults to returning the id attribute.

Forms Javascript

Switchable Fields

By marking fields with the "switchable" and "switched" classes along with defining a few data attributes you can programmatically hide, show, and rename fields in a form.

The triggers are fields using a select input widget, marked with the “switchable” class, and defining a “data-slug” attribute. When they are changed, any input with the "switched" class and defining a "data-switch-on" attribute which matches the select input’s "data-slug" attribute will be evaluated for necessary changes. In simpler terms, if the "switched" target input’s "switch-on" matches the "slug" of the "switchable" trigger input, it gets switched. Simple, right?

The "switched" inputs also need to define states. For each state in which the input should be shown, it should define a data attribute like the following: data-<slug>-<value>="<desired label>". When the switch event happens the value of the "switchable" field will be compared to the data attributes and the correct label will be applied to the field. If a corresponding label for that value is not found, the field will be hidden instead.

A simplified example is as follows:

source = forms.ChoiceField(
    label=_('Source'),
    choices=[
        ('cidr', _('CIDR')),
        ('sg', _('Security Group'))
    ],
    widget=forms.Select(attrs={
        'class': 'switchable',
        'data-slug': 'source'
    })
)

cidr = fields.IPField(
    label=_("CIDR"),
    required=False,
    widget=forms.TextInput(attrs={
        'class': 'switched',
        'data-switch-on': 'source',
        'data-source-cidr': _('CIDR')
    })
)

security_group = forms.ChoiceField(
    label=_('Security Group'),
    required=False,
    widget=forms.Select(attrs={
        'class': 'switched',
        'data-switch-on': 'source',
        'data-source-sg': _('Security Group')
    })
)

That code would create the "switchable" control field source, and the two "switched" fields cidr and security group which are hidden or shown depending on the value of source.

NOTE: A field can only safely define one slug in its "switch-on" attribute. While switching on multiple fields is possible, the behavior is very hard to predict due to the events being fired from the various switchable fields in order. You generally end up just having it hidden most of the time by accident, so it’s not recommended. Instead just add a second field to the form and control the two independently, then merge their results in the form’s clean or handle methods at the end.

Table Of Contents

Previous topic

Horizon Tabs and TabGroups

Next topic

Horizon Middleware

This Page