Extend fieldsets to support rendering complex form layouts #9065

Closed
opened 2025-12-29 20:45:00 +01:00 by adam · 3 comments
Owner

Originally created by @jeremystretch on GitHub (Jan 8, 2024).

Originally assigned to: @jeremystretch on GitHub.

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:

site_form

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',
    )),
)

image_attachment

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'),
    )),
)

rack_dimensions

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,
    ),
)

ipaddress_assignment

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

Originally created by @jeremystretch on GitHub (Jan 8, 2024). Originally assigned to: @jeremystretch on GitHub. ### 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`: ```python 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: ![site_form](https://github.com/netbox-community/netbox/assets/13487278/03410cae-ff63-43c0-b27d-92fcd392e85a) 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. ```python fieldsets = ( (None, ( ObjectAttribute('parent'), 'name', 'image', )), ) ``` ![image_attachment](https://github.com/netbox-community/netbox/assets/13487278/00c26c5a-c81e-4068-9d32-c74e9b0fb42d) #### Side-by-Side Fields Display several fields inline on a single row within the form. ```python fieldsets = ( (_('Dimensions'), ( 'type', 'width', 'u_height', InlineFields('outer_width', 'outer_depth', 'outer_unit'), )), ) ``` ![rack_dimensions](https://github.com/netbox-community/netbox/assets/13487278/4d78d2a2-0e48-491f-94f4-7eb77450ebe5) #### 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. ```python fieldsets = ( ( _('Interface Assignment'), TabbedFieldGroups( (_('Device'), 'interface'), (_('VirtualMachine'), 'vminterface'), (_('FHRP Group'), 'fhrpgroup'), ), 'primary_for_parent, ), ) ``` ![ipaddress_assignment](https://github.com/netbox-community/netbox/assets/13487278/357a92bb-8106-468d-9b13-184dcb80db5f) ### 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_
adam added the status: acceptedtype: feature labels 2025-12-29 20:45:00 +01:00
adam closed this issue 2025-12-29 20:45:00 +01:00
Author
Owner

@DanSheps commented on GitHub (Jan 9, 2024):

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"

@DanSheps commented on GitHub (Jan 9, 2024): > #### 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"
Author
Owner

@jeremystretch commented on GitHub (Jan 9, 2024):

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.

@jeremystretch commented on GitHub (Jan 9, 2024): > 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.
Author
Owner

@eronlloyd commented on GitHub (Jan 28, 2024):

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.

@eronlloyd commented on GitHub (Jan 28, 2024): 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.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#9065