Rolling Your Own Dynamic Forms

by Rachel Davies

Looking for a library that helps you to serve up dynamic forms based on your own schemas? Tes engineers recently open-sourced rolling-fields, a simple library that dynamically generates fields for your form on-the-fly.

Here’s a basic example that shows how to use rolling-fields in your code. You simply wrap DynamicFieldBuilder inside your form and pass in a field schema via props. Rolling-fields renders fields based on this schema inside your form.

import DynamicFieldBuilder from 'rolling-fields';
   const fieldSchema = [
      { name: 'name', type: string },
      { name: 'ready', type: boolean },
      { type: 'submit', text: 'Go' },
    ];

   <form>
    <DynamicFieldBuilder fields={fieldSchema} />
   </form>

Relevant Fields

We want to build forms that are relevant to our users based on their journey through a form. To show fields based on the current user input, we can use DynamicFieldBuilder multiple times within a single form – supplying separate schemas for each set of fields a user might need to see, as they make their way through our form.

I’ve put together a simple demo project to show how this can work.

The empty form starts like this:

empty form

as selections are made in the form, relevant fields are shown:

form changes based on input values

Check out rolling-demo to get the full source code.

Living Schema

However, hard-coding field schemas directly in your React app (as in the above examples) does not give you the full benefit of rolling-fields. You can use Formik to do exactly the same thing. At Tes, we use rolling-fields inside Formik forms because rolling-fields gives us additional benefits.

rolling-fields enables us to use a field schema loaded from an external data source to build our forms dynamically at run-time. Where exactly you store your schema data is entirely up to you. You might want to store schemas in JSON files or pull them from your database. The job of rolling-fields is purely to build the fields to include in your form from the schema.

The beauty of building a form from a field schema read at run-time is that your form is not hardcoded. You don’t need to redeploy to production to make changes to your form. This approach enables you to add and remove fields with ease plus make other smaller tweaks to field definitions outside your JS code. You simply make changes to the field schema in your data store and rolling-fields hydrates your form with the latest schema when the form is served.

Useful Application

We want to use a run-time schema so it can be edited without redeploying our code and we want to use that schema to build forms that show only relevant fields. What kind of real-world scenario does this help us resolve? Let’s walk through a possible application to illustrate some of the advantages.

Suppose you want to build a portal offering training courses provided by different colleges. You might start by building a single generic form to be used by all the colleges available via the portal. Soon you would likely find that colleges want to collect different information from applicants depending on the subject of the course and the options they provide. Yes, you might just add these into a single form – now it would include all questions, for all courses offered by all colleges! The form would soon become a long form with a lot of questions not relevant for all applicants. The big gotcha is that a long form with irrelevant questions is boring and takes longer to fill out. The result of making one big form for everyone would likely be a drop-off in course applications and colleges that can’t fill their courses via your portal.

A nicer option for users would be to serve a form that only includes relevant questions that make sense for a specific course at the selected college. This is where rolling-fields comes to the rescue! rolling-fields can be used to build our course application form dynamically, based on the user request. We can use details, such as the course and college, from their request to determine whether any additional input fields should be included to the form along with the core questions.

Saving Data

Naturally, when users submit completed forms, we want to keep their answers somewhere. One aspect of using a dynamic form to bear in mind is deciding an appropriate schema to store data with optional fields. Depending on your needs, you might choose a schema-less solution, such as storing responses in a JSON field in a regular database (such as MySQL or Postgres) or go for a document database like MongoDB. Otherwise, remember that some data may not be present when you are defining the database schema. At Tes, we find that using GraphQL works well with dynamic forms in the front-end and requests can map to regular SQL in the back-end.

Wrapping Up

rolling-fields is a simple library that can be used to dynamically generate fields for your form. rolling-fields helps our team at Tes solve some ubiqitous problems in form design, enabling us to keep forms fresh, short and more relevant to our users.