netbox
netbox copied to clipboard
Extend `fieldsets` to support rendering complex form layouts
NetBox version
v3.7.0
Feature type
New functionality
Proposed functionality
Introduce several new classes that would enable more complex form rendering via the fieldsets
attribute on a form. For example, the following is defined on SiteForm.Meta
:
fieldsets = (
(_('Site'), (
'name', 'slug', 'status', 'region', 'group', 'facility', 'asns', 'time_zone', 'description',
'tags',
)),
(_('Tenancy'), ('tenant_group', 'tenant')),
(_('Contact Info'), ('physical_address', 'shipping_address', 'latitude', 'longitude')),
)
This causes the form to render three discrete groups of fields with the assigned headings:
This proposal seeks to extend this ability by enabling several forms of more complex rendering, detailed below.
Static Attribute Rendering
Display an object attribute (not necessarily a form field) of an existing object, rendered as a read-only field.
fieldsets = (
(None, (
ObjectAttribute('parent'), 'name', 'image',
)),
)
Side-by-Side Fields
Display several fields inline on a single row within the form.
fieldsets = (
(_('Dimensions'), (
'type', 'width', 'u_height', InlineFields('outer_width', 'outer_depth', 'outer_unit'),
)),
)
Tabbed Groups
Allow fields to be arranged in tabbed subgroups. Selecting the tab for a group will display its fields and hide fields from its peers.
fieldsets = (
(
_('Interface Assignment'),
TabbedFieldGroups(
(_('Device'), 'interface'),
(_('VirtualMachine'), 'vminterface'),
(_('FHRP Group'), 'fhrpgroup'),
), 'primary_for_parent,
),
)
Use case
There are several instances across NetBox where we use custom HTML templates to render object edit forms, because we need to deviate from the standard form rendering and accommodate a more complex layout. Some instances include:
- Displaying an attribute as a read-only field (e.g. the object to which an image attachment is assigned)
- Grouping several fields under tabs (e.g. IP address interface/FHRP group)
- Displaying several fields inline (e.g. rack width, depth, and unit)
Moving this logic into the form fieldset definitions will allow us to ditch most of our custom templates.
Database changes
No response
External dependencies
No response
Side-by-Side Fields
Like this, but... in the example you don't specify how it gets "Outer Dimensions" as the label for the side-by-sides. I am assuming there will be a label= property on that class?
This will definitely allow some clean-up of some of the more custom forms we have going I would imagine, so I am all for it.
I would like to perhaps add another type of field (or even field group) for consideration:
Constrained
Allow for a field type to be constrained and hidden except for when certain attributes are also set (dynamically on the page):
Example:
- Interface form
- Only show "Wireless" properties when the interface type is a valid wireless type.
Perhaps it might make sense to instead ditch the tuple as well and use a specific class for rendering the "field groups"
in the example you don't specify how it gets "Outer Dimensions" as the label for the side-by-sides. I am assuming there will be a label= property on that class?
Honestly I was just toying around with some example code; we'll probably tackle it either with a label
attribute on the class but ultimately it will depend on how exactly we end up implementing this.
I would like to perhaps add another type of field (or even field group) for consideration:
I want to limit the scope of this for now to ensure we make progress on it. The goal right now is just to replicate existing static layouts; custom templates remain an option where more advanced logic is needed.
I like @DanSheps idea of having some context awareness such as for the wireless fieldset. But that might be out of scope, from what I'm reading.