DEV Community

Cover image for Cabloy Form Layout: Organize Complex Forms in DTOs with Tabs, Groups, and Sections
Uncle Pushui
Uncle Pushui

Posted on

Cabloy Form Layout: Organize Complex Forms in DTOs with Tabs, Groups, and Sections

Automatically rendered forms work well when there are only a few fields. As a form grows to include profile information, contact details, and business records, structure starts to matter: how should fields be grouped? Which fields should sit side by side? Which content belongs in a separate tab?

Cabloy Form Layout is designed for exactly this. It lets you describe the placement and hierarchy of multiple form fields in a DTO, then lets the frontend render that structure from the configuration.

Put simply: Form Layout decides where fields go. The existing schema and form configuration still decide field types, labels, validation, and other field behavior.

What Form Layout Can Do

With Form Layout, you can configure common form requirements in a DTO:

  • Change the order in which fields appear.
  • Put related fields into a titled business group.
  • Use multiple columns on wider screens and a single column on smaller screens.
  • Split independent content, such as Basic Information and Training Records, into separate tabs.
  • Apply the same structural approach across create, update, and view forms.

The main nodes are straightforward:

  • field: places one field.
  • section: arranges fields in one or more columns.
  • group: organizes related fields together.
  • tabs / tab: divides separate content areas into tabs.

Example: Structuring the Student Form

The following Student Create DTO layout is slightly simplified for illustration. It focuses on the Form Layout portion and omits the outer DTO definition, page actions, and other field configuration.

ZovaRender.block('basic-form:blockFormLayout', {
  formLayout: {
    children: [
      {
        type: 'tabs',
        children: [
          {
            type: 'tab',
            title: $locale('BasicInformation'),
            children: [
              {
                type: 'group',
                title: $locale('StudentProfile'),
                children: [
                  {
                    type: 'section',
                    columns: { default: 1, md: 2 },
                    children: [
                      { type: 'field', name: 'name' },
                      { type: 'field', name: 'mobile' },
                      {
                        type: 'field',
                        name: 'imageId',
                        span: { default: 1, md: 2 },
                      },
                    ],
                  },
                ],
              },
            ],
          },
          {
            type: 'tab',
            title: $locale('TrainingRecords'),
            children: [
              { type: 'field', name: 'level' },
              { type: 'field', name: 'trainingRecords' },
            ],
          },
        ],
      },
    ],
  },
});
Enter fullscreen mode Exit fullscreen mode

Read the example from the outside in to see what it produces.

1. tabs and tab: Split the Form by Business Area

The outer tabs node creates a tabbed area. It contains two tab nodes:

  • BasicInformation
  • TrainingRecords

Tabs help readers focus on one area at a time when a form contains independent business content. If a form has only a few fields, a simple group is usually easier to scan than a tabbed interface.

2. group: Give Related Fields a Clear Context

The group in the Basic Information tab is titled StudentProfile. It puts the student's name, mobile number, and image under one shared business context.

Think of a group as a titled grouping for related fields. Contact details, shipping addresses, and approval information are all common examples.

3. section: Control Responsive Columns

The section controls the field grid. columns: { default: 1, md: 2 } means one column by default and two columns at the md breakpoint and above.

As a result, name and mobile can appear side by side on wider screens and naturally stack on smaller screens.

4. field: Reference Fields Already Defined in the DTO Schema

Each field uses name to reference a field that already exists in the DTO schema, such as name. Its widget, label, and validation rules continue to use the field's existing configuration.

imageId also uses span: { default: 1, md: 2 }. It takes one column in the default layout and both columns in the two-column layout. This is useful for an image, note, or description that should occupy a full row.

Choosing the Right Node

Start with the smallest structure that expresses what the form needs:

Requirement Use
Only change field order field
Show fields side by side on wider screens section
Give related fields a shared title and boundary group
Separate genuinely independent business content tabs / tab

A common composition is: Tabs divide business areas, Groups express business context, Sections handle responsive columns, and Fields place individual fields.

You do not need every container for every form. Use field alone for a simple form, add a section when columns help, and add a group only when fields truly belong to the same business block.

One Easy-to-Miss Detail

Form Layout controls field placement, not field visibility.

If a field should not appear, configure its visibility in the field's schema metadata. Leaving it out of formLayout does not necessarily hide it; an eligible visible field can still appear at the end of the form.

Summary

Form Layout lets a DTO describe the structure of a complex form:

  • Use field to set field order.
  • Use section for responsive columns.
  • Use group for business grouping.
  • Use tabs / tab to separate independent content.

The key division of responsibility is simple: DTO metadata describes the form structure; the schema and form runtime continue to govern each field's behavior. When fields change, update the layout in the DTO instead of maintaining field placement repeatedly across multiple pages.

Further Reading

Top comments (0)