Multi-step and Multi-page Forms

A multi-step form is a form split into multiple steps, where each part is submitted to the server as a distinct step before the next step is shown. Unlike tabbed forms, multi-step forms don't require any assistance from Magic Tabs

A multi-page form is a form where the parts of the form are spread across multiple pages and, in effect, multiple forms.

Each part of a multi-step or multi-page form has its own submit button and hence its own pipeline. This provides enormous flexibility in how a multi-step or multi-page form processes data. You can implement step specific validation and feedback. You can save at each step, or at the end. 

Different approaches to multi part forms

One of the USPs of Form Reform is flexibility, so it should not be surprising that we have multiple ways of creating multi part forms. 

With multi-step forms, the successive parts are contained within one page using the Behaviour tab of the Form Reform blocks to do one or more of

  • Hide when
  • Do not render when
  • Disable when

to manage how each form block behaves in each form state.

With multi-page forms, each part is a separate page and effectively a separate form. Require Form blocks are added to forms/pages to force dependencies between the parts of the form.

For really big or complex forms, multi-page forms may contain multi-part forms within the pages.

The techniques below are for multi-step forms. Similar principles apply to multi-page forms and are discussed later and you can even build multi-form multi-user workflows by incorporating Form Reform Display and the Result Picker input control from Form Reform Data Picker into a series of forms.

1. Accumulate previous steps using hidden blocks (example)

For the first step we render just the input blocks for that step. Input blocks for subsequent steps are configured Don Not Render in step 1. Then in each subsequent step the previously shown input blocks are persisted (Initial Value) and hidden (Behaviour) and the new input blocks for that step are rendered. The Submit button block for each step is only rendered in that specific step.

Over multiple steps, the hidden part of the form grows behind the scenes. The validity of all previously submitted steps is checked with each step.


  • Accumulating input blocks doesn't require any intermediate storage as the steps are subsequently hidden and accumulate. The hidden part of the form is the intermediate storage!
  • Easy to grow from a single step form or grow with extra steps.
  • Steps can be on one page or spread across a sequence of pages.


  • The browser side part of the form grows with each step, so could become difficult to manage for bigger multi step forms
  • The necessary overhead of continuing to validate all previous blocks could have a performance impact.
  • Changing the order of steps requires more work in the edit dialogues.
  • Even though validation of all blocks is repeated, the overall validation is not as secure because it resides in values that are accessible in the browser developer console.

2. Accumulate each step in a store

In this approach, for each form step only the input blocks and submit block for that step are actually rendered. Inputs blocks and submit blocks for all other steps are set to Do not render (Behaviour).

The submit pipeline for each step accumulates form inputs by saving to the session or a cookie with Save to Session or Save to Cookie handlers. Then subsequent steps use the corresponding  Merge From Session Store or Merge From Cookie Store handler to combine previous steps before the submit handler pipeline for the final step saves the entire submitted form more permanently.


  • Only the inputs handled by each step are accessible in the browser for that step. Hence this approach is inherently tamper resistant.
  • Step sequence can be rearranged with only minor configuration changes.
  • Steps can be on one page or spread across a sequence of pages.
  • Convenient for forms where a visitor may digress to other pages and subsequently return.


  • Submit pipelines are more complex because data from previously submitted steps needs to be saved and subsequently merged.

3. Render all steps in one go using hidden/disabled inputs.

This approach becomes necessary with AJAX forms. Here we initially render all the form blocks with the page, but set the form block Behaviour for all steps other than the current step to Hide and Disable. With each step of the form, the blocks hidden and disabled are toggled to leave those relevant to that step visible and enabled.

The submit pipeline for each step accumulates form input values by saving to the session or a cookie with Save to Session or Save to Cookie handlers. Then subsequent steps use the corresponding Merge From Session Store or Merge From Cookie Store handler to combine previous steps before the final step saves the entire submitted form more permanently.


  • Works with AJAX forms.
  • Fast and responsive after the first step because subsequent steps simply toggle the hidden and disabled behaviours of form blocks rendered with the page.


  • The initial page render can be big because all the hidden and disabled form blocks need to be rendered when the first step is shown.
  • A browser developer console can be used to sneak a look ahead at steps not yet shown.
  • A form must be contained within one page.

4. Accumulate in the final database record

Our multi step form techniques so far have accumulated steps in the visitor's browser or in visitor specific storage such as session or a cookie.

A variation is to save the data from each form step in a single database record for the form. The Save to Database handler has options to Extend an existing record, so the handler pipeline for submitting the first step would create a new record, then the submit pipeline for subsequent steps can be configured to extend the most recent record, which would be the record created by the first step.


  • Extract data on partially completed forms.
  • Particularly robust in situations where a form submission could be interrupted in an intermediate step, then resumed later.
  • Convenient for forms where a visitor may digress to other pages and subsequently return.


  • You can end up with database records for forms that have been abandoned by visitors that did not complete the final step. This can have implications for privacy and GDPR.
  • Partially completed and then abandoned forms lead to garbage and you will then need to implement measures to clear out the garbage.

5. Accumulate across multiple database records

A variation of the above to use separate records in the database. Your multi step form effectively becomes two or more separate forms. You can even give these separate aliases for the form name such as 'Work in Progress' and 'Completed Form'. If necessary, the Merge From Default Store handler can be used to combine intermediate step with the final step before saving.


  • Extract data on partially completed forms.
  • Particularly robust in situations where a form submission could be interrupted in an intermediate step, then resumed later.
  • Easier to distinguish completed forms from abandoned forms.
  • Convenient for forms where a visitor may digress to other pages and subsequently return.


  • Can still have implications for privacy and GDPR.
  • You may still need to implement measures to clear out abandoned forms.

How many form steps?

All of the above can be extended beyond 2-step forms. When installed, Form Reform is configured with 5 arbitrary form steps in addition to the message states. These form steps do not need to be used in sequence, other than a form always begins in Step 1.

If you need more steps, the number can be adjusted in application/config/ at jl_form_reform.visibility_states.max_form_steps.

Conditional steps

A further development of multi step forms is to have conditional steps using Condition If handlers in the submit processing pipeline and deciding which step follows through evaluating a condition.

For example, the processing pipeline for the first step of a form could include:

Condition If ... 

Set next form state to step 2

Condition Else

Set next form state to step 3

Condition End


Multi-page forms

The structure of a multi-page form has many similarities to a multi-step form. Similar mechanisms can be used to accumulate data as the parts of the form are completed. Rather than managing visibility of steps using form state and the behaviour tab, you manage access to form pages using one or more Require Form blocks.

The Require From block provides options to

  • Change a form state if a required form/page has not been submitted.
  • Redirect to the required page if it has not been submitted.
  • Fail validation of the current form if a required form/page has not been submitted.

To ensure you can't get locked out from editing a page, any user with edit permission will never be redirected.

When a form/page is submitted, the submit pipeline for a multi-page form will usually include a Redirect handler to redirect to the next page in the form.

For multi-page forms, another useful block is the Completion List provided by the From Reform Display extension. This can be configured to show visitors their progress through a group of related forms that comprise a multi-page form.


  • Convenient for separation of form parts.
  • Less complicated pages.
  • Simplicity of form state.
  • Can enforce sequence between parts.
  • Can allow parts to be submitted out of sequence.
  • Convenient for forms where a visitor may digress to other pages and subsequently return.


  • Multi-page forms cannot enforce conditional form parts. Conditional parts can be enforced using a multi-step form using form states.
  • Forms are spread across pages.
  • One or more Require Form blocks needs to be configured to enforce sequence between forms/parts.

Hybrid approaches

A multi-part form built using Form Reform is not limited to the above. Form Reform is all about flexibility and you could, where advantageous, build a multi-part form where two or more of the above are combined to achieve your desired outcome.

Building multi-form workflows

What we mean here is where different users progress something through various stages by submitting a form relevant to each stage.

For each stage of such a multi-form multi-user workflow we need:

  1. Each form's submission pipeline to add or change a status value to indicate where we are in the workflow.
  2. A page to display a listing of submissions from the previous stage of the workflow. This can typically be filtered using a List Results block from Form Reform Display and the status value.
  3. Use page permissions to determine who can view and act on a stage of the workflow.
  4. A form on such pages with a Result Picker input block from Form Reform Data Picker to select a previous submission from the List Results block, with further inputs to add data to the workflow and a submit pipeline to change the status value.

Repeat for each stage of the workflow. 

Such workflows do not need to be linear. You can use multiple forms or multiple submit pipelines at each stage to create branches and conditional steps of the workflow.

See Reviews for a description of using this technique to build a Review Management workflow.

Additional Pages

Reform the way you add new input controls

If you need a specialized template or a custom input element, you can design new templates  or new block types for form elements as you would any block type.

Blocks are easy for third party addition or extension. Block templates and are the first thing any Concrete CMS developer learns to code. They are one of the easiest things to code. The underlying mechanisms are well established and reliable.

Reform what you can do with form data

Form handlers are built about the same extensible plugin system as many of my other addons (Universal Content Puller, Omni Gallery, Extreme Clean ...).

The whole system is aimed at easy extension within Form Reform, by third party addons, by agencies and by site building developers.

Handlers can be easily added to do whatever you want with the form data.

Reform where you can save form data

Saving form data with Form Reform is simply a handler in the processing pipeline. You can save to multiple locations or just one location.

If you need to save data elsewhere, such as to a dedicated table, a table provided through another addon, to another database, send it to an API, forward it to another server, or anywhere you can imagine, you can adapt or develop a form handler to do so.

The complexity of the code depends on where you are saving or sending the data, but wrapping that into a form handler plugin for Form Reform is straight forward.

The Form Reform handler plugin system is designed for easy extension.

Form Reform

Reform the way forms are built. Build a form out of blocks. Take control of how form submissions are processed and how the submitted data is stored. Easy to extend. Easy to reconfigure. Tangible data. Easy to add your own integrations.

Form Reform Display

List and display form submissions from Form Reform.

Form Reform UTM

Not just Form Reform and not just UTM! Capture and hold incoming UTM (or other) tags and make the tag values available to Form Reform and/or Conditional Redirect as {{place_holders}}. You don't need Form Reform to use this.

Form Reform Dynamics

Form handlers for querying Microsoft Dynamics, forwarding and updating form data to Microsoft Dynamics.


A suite of advanced image capture and upload tools. Enhanced drag and drop file uploading. Make screengrabs from within Concrete CMS. Capture images directly from device webcams. Edit images before uploading.

Form Reform Attributes, Express and Users

Save submitted forms to Express objects and user attributes. Add and remove users from groups.

Form Reform Image Picker

Form Reform Image Picker provides an image picking input block for Form Reform. The Image Picker Input is preconfigured to connect to most Omni Gallery gallery and slider display widgets, the core gallery block, and thumbnail showing templates for the core page list block. Advanced settings allow the Image Picker Input to be configured to pick images from other galleries and sliders.

Form Reform Data Picker

Form Reform Data Picker provides data picking input blocks for Form Reform. The Table Picker Input is preconfigured to connect to Universal Content Puller table display widgets. Advanced settings allow the Table Picker Input to be configured to pick data from other HTML tables.

Form Reform Macros

Extends Form Reform with form handler macros. Provides a new dashboard page at System & Settings > Form Reform > Form Reform Macros to manage macros, and form handlers to run macros.

Form Reform Developer

A growing suite of resources to assist those developing blocks, handlers and more complex forms for Form Reform.

Learn with a simple form

While you may have plans to implement some much more complex forms using Form Reform, we strongly recommend you start with a simple form such as our contact form example in order to review the basic principles of using Form Reform before you move onto anything bigger.

  1. Start by submitting the form at Getting Started - Your First Form a few times, even making some deliberate mistakes.
  2. Watch our Getting Started with Form Reform video to see how the form is built.
  3. Read through the rest of Getting Started - Your First Form for more details of how this form is built.
  4. Create a test page on your site to build your own version of Getting Started - Your First Form and experiment.
  5. Develop your test page with some of the concepts introduced by our further examples and experiment with some of the other form inputs.