Form
Collect user information via forms in modals or embedded in your UI
About this component
The Form
component is a super versatile tool that can fit right into your product UI or pop up in a modal for things like surveys. They can be used for wide range of use cases including registration flows, surveys, feedback forms, and more. The component supports form validation (client and server-side), conditional fields, branching logic, and multi-step Flows.
When to Use Forms:
- Embedded in UI: Forms work great for tasks like product registration, helping users get started smoothly without leaving the page.
- Modal Surveys: Use forms in modals for surveys or feedback, making it easy for users to share their thoughts without disrupting their experience.
Why Forms Are Powerful:
- Conditional and Branching Logic: Forms can adapt based on user responses, guiding them through a tailored experience that feels intuitive.
- Custom React Steps: You can embed custom React components to invite teammates or perform API lookups, adding a personal touch to your forms.
- Customizable Input Types: With a variety of built-in input types—like text fields, multiple-choice options, and dropdowns—you can design forms that suit your specific needs.
Best Practices for Forms:
- Provide Progress Indicators: Adding progress bars or step indicators (like “Step X of Y”) can help users see how far they’ve come and what’s left to do. This makes the process feel less daunting and more manageable.
- Streamlined Data Collection: Frigade makes it easy to create new forms quickly, allowing you to gather user data and send it wherever you need it in your system.
Resources
- Create a form and send events to Slack
- Launch pop-up forms and surveys with no-code using Collections
- Target your form to specific users with Targeting
- See industry examples of forms
Demo
- See forms in action in our live demo
Customization
To learn about how to customize Frigade components, see the customization documentation and examples of custom themes in action.
Examples
The following section includes ready-made examples and code for various form use cases.
Simple Modal Form
Churn Survey
Dynamic Fields
Sometimes you may want to conditionally render a dynamic field based on the value of another field. The example above dynamically changes the second dropdown based on the value of the first dropdown.
Sometimes you may want to conditionally render a dynamic field based on the value of another field. The example above dynamically changes the second dropdown based on the value of the first dropdown.
This component requires a custom form field for dynamically changing the input. You can achieve this by using the formContext
provided by react-hook-forms.
In this case, we define a custom field type called DynamicFollowUpBasedOnField
that renders a SelectField
component.
The options of the follow-up
dropdown depends on the value of food
. If the user selects pizza
, the follow-up
dropdown will show options for pizza toppings. If the user selects pasta
, the follow-up
dropdown will show options for pasta sauces.
Branching Forms
This example shows how to implement branching in a form based on the user’s choice in the first step.
This example shows how to implement branching in a form based on the user’s choice in the first step.
If you want a form to conditionally skip a step based on the result of a previous step, you can use the visibilityCriteria
property in the step configuration.
For instance, the example below will jump directly to page 3 if the user picks a specific option on the first page/step:
visibilityCriteria
will work with both form data or any other Targeting condition.
Supported Field Types
The component supports the following builtin field types that correspond to their respective HTML input types:
-
select
-
radio
-
text
-
textarea
-
checkbox
Overriding Field Attributes
You can override or add any attribute for a field by using the props
property in the field configuration.
For instance, this is useful if you want to use the text
field type, but override the type
to email
or tel
. It can also be used to add any attribute such as a css class, data, or styling.
Custom Field Types
The Form SDK is built on top of react-hook-form, which means you can use the majority of its features in your forms. You can define your own custom field types using the fieldTypes
prop.
For instance, you can implement a simple calendar datepicker field type as such:
It is also possible to conditionally render a field based on the value of another field by using the formContext provided by react-hook-form.
For instance, if you want a custom field called company-size
to show up when a user selects company
in the customer-type
field:
Form Validation
The component supports client-side and server-side validation out of the box. You can define validation rules for each field in the form configuration using the pattern
property with a regular expression. The example below shows how to validate an email field:
Server-side Validation
You can perform server-side validation by returning a Promise from the onPrimary
event handler. If the promise resolves to false
, the current step in the form will not be marked as completed. The onPrimary
event handler also contains all form data collected in the session, which allows you to send the data to your server for validation or storage.
Prefilling a form
Forms can be prefilled by using Dynamic Variables by linking the value
of a field
to the variables
prop of the Form component. The example below shows how to prefill a form with the user’s name:
Customization
To learn about how to customize Frigade components, see the customization documentation and examples of custom themes in action.
SDK Properties
Optional component to wrap the child components in, e.g. as={Dialog}
will render the Flow in a modal Dialog. Defaults to Box
.
Whether to automatically mark the Flow started (i.e. in progress) when the Flow is eligible to be shown.
You will need to call flow.start()
or step.start()
from the parent component if you set this to false
. Most components should not need to override this behavior.
Defaults to true
.
Emotion CSS prop to apply to the component. See Theming documentation for more information.
Example usage:
Whether the Flow is dismissible or not
Custom field types to be used in the Form.
You can use this to build your own custom form fields in a Form
.
For example, if you want to use a custom field type called calendar
:
The Flow ID to render. You can find the Flow ID in the Frigade dashboard.
If true, the Flow will be mounted even if it has already been completed or dismissed. However, if the user does not match the Flow’s targeting, the Flow will not be mounted.
Register the Flow as a modal to prevent popup collisions (only one modal Flow will render at a time).
Handler for when the Flow is completed. This is event is fired immediately after the user completes the Flow.
Handler for when the Flow is dismissed (skipped). This is event is fired immediately after the user dismisses the Flow.
Handler for when primary button is clicked.
If this function returns false or a promise that resolves to false
, the step will not be automatically completed when clicked.
Handler for when secondary button is clicked.
If this function returns false or a promise that resolves to false
, the step will not be automatically completed when clicked.
Variables to pass to the Flow. You can use variables in the Flow configuration to customize copy.
For instance, you can use title: Hello, ${name}!
in the Flow configuration and pass variables={{name: 'John'}}
to customize the copy.
Optional component to wrap the child components in, e.g. as={Dialog}
will render the Flow in a modal Dialog. Defaults to Box
.
Whether to automatically mark the Flow started (i.e. in progress) when the Flow is eligible to be shown.
You will need to call flow.start()
or step.start()
from the parent component if you set this to false
. Most components should not need to override this behavior.
Defaults to true
.
Emotion CSS prop to apply to the component. See Theming documentation for more information.
Example usage:
Whether the Flow is dismissible or not
Custom field types to be used in the Form.
You can use this to build your own custom form fields in a Form
.
For example, if you want to use a custom field type called calendar
:
The Flow ID to render. You can find the Flow ID in the Frigade dashboard.
If true, the Flow will be mounted even if it has already been completed or dismissed. However, if the user does not match the Flow’s targeting, the Flow will not be mounted.
Register the Flow as a modal to prevent popup collisions (only one modal Flow will render at a time).
Handler for when the Flow is completed. This is event is fired immediately after the user completes the Flow.
Handler for when the Flow is dismissed (skipped). This is event is fired immediately after the user dismisses the Flow.
Handler for when primary button is clicked.
If this function returns false or a promise that resolves to false
, the step will not be automatically completed when clicked.
Handler for when secondary button is clicked.
If this function returns false or a promise that resolves to false
, the step will not be automatically completed when clicked.
Variables to pass to the Flow. You can use variables in the Flow configuration to customize copy.
For instance, you can use title: Hello, ${name}!
in the Flow configuration and pass variables={{name: 'John'}}
to customize the copy.
The individual steps/pages of the form
Unique identifier for the step. Do not change this once the step has been created.
The title of the step
The description of the step
Url to an image to display in the step
Url to an icon to display in the step. This is only supported by the carousel checklist component.
Url to a video to display in the step such as YouTube, Vimeo, or a direct link to an mp4 file
Config for the primary button in this step.
Primary button action. (defaults to step.complete).
Possible values: false
, flow.back
, flow.complete
, flow.forward
, flow.restart
, flow.skip
, flow.start
, step.complete
, step.skip
, step.reset
, step.start
Primary button URI target (defaults to _self).
Primary button title. If omitted, the primary button will not be shown.
Primary button URI.
Deprecated: use primaryButton.title
instead. The title of the primary button
Deprecated: use primaryButton.uri
instead. The url to open when the primary button is clicked
Deprecated: use primaryButton.target
instead. The target of the primary button url (default: _blank; use _self to open in the same window). Setting it to # will open the existing page and dismiss any Frigade modals.
Config for the secondary button in this step.
Secondary button action. (defaults to step.complete).
Possible values: false
, flow.back
, flow.complete
, flow.forward
, flow.restart
, flow.skip
, flow.start
, step.complete
, step.skip
, step.reset
, step.start
Secondary button URI target (defaults to _self).
Secondary button title. If omitted, the secondary button will not be shown.
Secondary button URI.
Deprecated: use secondaryButton.title
instead. The title of the secondary button
Deprecated: use secondaryButton.uri
instead. The url to open when the secondary button is clicked
Deprecated: use secondaryButton.target
instead. The target of the secondary button url (default: _blank; use _self to open in the same window). Setting it to # will open the existing page and dismiss any Frigade modals.
Targeting that automatically completes the step. E.g.: user.property(‘connectedBank’) == true
Targeting that automatically blocks the step from starting until it becomes true. E.g.: user.property(‘connectedBank’) == true
Targeting that automatically shows the step when it becomes true. E.g.: user.property(‘connectedBank’) == true
Override the default UI props for the corresponding component
The data contained on the form step, typically text input boxes, multiple choice questions, etc.
Unique identifier for the step. Do not change this once the step has been created.
The label of the field
The default value of the field (used for prefilling). For checkboxes, use ‘true’ or ‘false’.
Whether the field can accept multiple values. Only used for the select
type field.
The type of the field. The built-in supported types are: text
, textarea
, select
, checkbox
, and radio
. If you are using custom form field types, the name here should match it.
The placeholder of the field
The maximum length of the field
Whether the field is required or not. Use a string here to show a custom error message.
The options for the field. Only used for select fields.
The label of the option
The value of the option
The validation rules for the field. See documentation for more information.
Regex pattern to match the field against
The error message to display if the pattern does not match
Optional additional properties for the field. These will be passed to the frontend component as HTML attributes and merged with the default props for the given field type.