Python Developer Guide
Other documentationsDemoCommunityGitHub
  • Forest Admin
  • Getting started
    • How it works
    • Quick start
      • Flask
      • Django
    • Create your agent
    • Troubleshooting
    • Migrating legacy agents
      • Pre-requisites
      • Recommendations
      • Migration steps
      • Code transformations
        • API Charts
        • Live Queries
        • Smart Charts
        • Route overrides
        • Smart Actions
        • Smart Fields
        • Smart Relationships
        • Smart Segments
  • Data Sources
    • Getting Started
      • Collection selection
      • Naming conflicts
      • Query interface and Native Queries
        • Fields and projections
        • Filters
        • Aggregations
    • Provided data sources
      • SQLAlchemy
      • Django
        • Polymorphic relationships
    • Write your own
      • Translation strategy
        • Structure declaration
        • Capabilities declaration
        • Read implementation
        • Write implementation
        • Intra-data source Relationships
      • Contribute
  • Agent customization
    • Getting Started
    • Actions
      • Scope and context
      • Result builder
      • Static Forms
      • Widgets in Forms
      • Dynamic Forms
      • Form layout customization
      • Related data invalidation
    • Charts
      • Value
      • Objective
      • Percentage
      • Distribution
      • Leaderboard
      • Time-based
    • Fields
      • Add fields
      • Move, rename and remove fields
      • Override binary field mode
      • Override writing behavior
      • Override filtering behavior
      • Override sorting behavior
      • Validation
    • Hooks
      • Collection hook
      • Collection override
    • Pagination
    • Plugins
      • Write your own
    • Relationships
      • To a single record
      • To multiple records
      • Computed foreign keys
      • Under the hood
    • Search
    • Segments
  • Frontend customization
    • Smart Charts
      • Create a table chart
      • Create a bar chart
      • Create a cohort chart
      • Create a density map
    • Smart Views
      • Create a Map view
      • Create a Calendar view
      • Create a Shipping view
      • Create a Gallery view
      • Create a custom tinder-like validation view
      • Create a custom moderation view
  • Deploying to production
    • Environments
      • Deploy on AWS
      • Deploy on Heroku
      • Deploy on GCP
      • Deploy on Ubuntu
    • Development workflow
    • Using branches
    • Deploying your changes
    • Forest Admin CLI commands
      • init
      • login
      • branch
      • switch
      • set-origin
      • push
      • environments:create
      • environments:reset
      • deploy
  • Under the hood
    • .forestadmin-schema.json
    • Data Model
      • Typing
      • Relationships
    • Security & Privacy
Powered by GitBook
On this page
  • Form layout
  • Layout items
  • General properties
  • Separator element
  • HTML Block element
  • Row element
  • Multi pages form
  • Description
  • Limitations

Was this helpful?

  1. Agent customization
  2. Actions

Form layout customization

This is the official documentation of the forestadmin-agent-django and forestadmin-agent-flask Python agents.

Form layout

The form layout feature lets you organize your fields in pages or rows, and add separators or html blocks. This is especially useful if you have many fields to display, and you want to break down your action form into more manageable chunks !

Theses form elements are available since the version 1.16.0 of the agent.

Layout items

Name
Nested elements
Description

None

Allow to add a horizontal separator between two form elements

None

Allow to show HTML content

Fields

Allow to put two (and only two) fields (and not layout elements) in a row

Fields & layouts elements (but no pages)

General properties

Some layouts items will have options, but here are the common properties to all the layout elements

Name
Usage
Expected value
Description

type

required

Layout

component

required

Separator, Row, HtmlBlock, or Page

The layout component

if_

optional

Separator element

Name
Usage
Expected value
Description

component

required

"Separator"

To enable this component

This item doesn't have specific options.

Example:

agent.customize_collection("customer").add_action("What's your name",{
    "scope": "Single",
    "execute": lambda context, result_builder: result_builder.success(),
    "form": [
        {"type": "String", "label": "firstName"},
        {"type": "Layout", "component": "Separator"},
        {"type": "String", "label": "lastName"},
    ]}
)

HTML Block element

Name
Usage
Expected value
Description

component

required

"HtmlBlock"

To enable this component

content

required

This is the HTML content to show

Example:

agent.customize_collection("customer").add_action("Boring form", {
    "scope": "Global",
    "execute": lambda context, result_builder: result_builder.success(),
    "form": [
        {
            "type": "String",
            "label": "firstName",
            "default_value": lambda ctx: ctx.caller.first_name,
        },
        {
            "type": "String",
            "label": "lastName",
            "default_value": lambda ctx: ctx.caller.last_name,
        },
        {
            "type": "Layout",
            "component": "HtmlBlock",
            "content": lambda ctx: f"""
<div style="text-align:center;">
    <p>
        <strong>Hi {ctx.form_values["firstName"]} {ctx.form_values["lastName"]}</strong>,
        <br/>here you can put
        <strong style="color: red;">all the html</strong> you want.
    </p>
</div>
<div style="display: flex; flex-flow: row wrap; justify-content: space-around;">
    <a href="https://www.w3schools.com" target="_blank">
        <img src="https://www.w3schools.com/html/w3schools.jpg">
    </a>
    <iframe src="https://www.youtube.com/embed/xHPKuu9-yyw?autoplay=1&mute=1"></iframe>
</div>
""",
        },
    ]}
)

Row element

Name
Usage
Expected value
Description

component

required

"Row"

To enable this component

fields

required

Example:

agent.customize_collection("customer").add_action("Personal form", {
    "scope": "Global",
    "execute": lambda context, result_builder: result_builder.success(),
    "form": [
        # ...
        {
            "type": "Layout",
            "component": "Row",
            "fields": [
                {
                    "label": "gender",
                    "type": "Enum",
                    "enum_values": ["M", "F", "other"],
                },
                {
                    "label": "specify",
                    "description": "you may specify here"
                    "type": "String",
                    "if_": lambda ctx: ctx.form_values.get("gender") == "other",
                },
            ]
        },
        # ...
    ]}
)

Multi pages form

Description

The pages feature is a way to break up your action form into more manageable chunks, by showing only a subset of fields at the same time, and letting the user navigate between the pages.

Limitations

Please note this list of limitations:

  • You cannot mix fields and pages at the root of your form, or put nest a page in a page

  • The next (or previous) button is not clickable on the last (or first) page

Name
Usage
Expected value
Description

component

required

"Page"

To enable this component

elements

required

Array of fields and layout elements

next_button_label

optional

String

The label on the next button

previous_button_label

optional

String

The label on the previous button

Example:

agent.customize_collection("customer").add_action("Create user with address", {
    "scope": "Global",
    "execute": lambda context, result_builder: result_builder.success(),
    "form": [
        {
            "type": "Layout",
            "component": "Page",
            "next_button_label": "Go to address",
            "elements": [
                {"type": "String", "id": "Firstname", "label": "First name"},
                {"type": "String", "id": "Lastname", "label": "Last name"},
                {"type": "Layout", "component": "Separator"},
                {"type": "Date", "id": "Birthdate", "label": "Birth date"},
            ],
        },
        {
            "type": "Layout",
            "component": "Page",
            "previous_button_label": "Go back to identity",
            "elements": [
                {
                    "type": "Layout",
                    "component": "Row",
                    "fields": [
                        {"type": "Number", "id": "StreetNumber", "label": "Street number"},
                        {"type": "String", "id": "StreetName", "label": "Street name"},
                    ],
                },
                {"type": "Layout", "component": "Separator"},
                {"type": "String", "id": "PostalCode", "label": "Postal code"},
                {"type": "String", "id": "City"},
                {"type": "Layout", "component": "Separator"},
                {"type": "String", "label": "Country"},
            ],
        },
    ]}
)
PreviousDynamic FormsNextRelated data invalidation

Last updated 4 months ago

Was this helpful?

Allow to use multi pages forms. When using multi pages form, you must have only pages at the root of your form.

It differentiate a field from layout elements. See over values in

callable with parameter

Only display the field if the function returns true. This one is the exact same one as presented in

String or callable with parameter, returning a string formatted as html

This element is designed to work with only two inner fields. You can control the display of each field using the if_ property. If only one field is displayed, it will occupy the entire line. However, if the conditions defined by the if_ properties result in more than two fields being displayed, only the first two will be shown. If there is nothing inside, it will be removed.

Array of two

These two fields are the ones you want to display in a line No layout elements are allowed in a Row component; only fields

If you're using if conditions in a page; keep in mind that if all the elements in your page are hidden, the page will automatically be removed. You can avoid this by behavior by adding an unconditional inside your page explaining why is your page empty.

The layout elements defined in this page and the fields defined

⚠️
htmlBlock
⚠️
⚠️
context
context
in the others documentation
Separator
HTML block
Row
Page
Example
Example
Example
page 1
page 2
static form documentation
fields
dynamic forms