DEV Community

Gino Llerena
Gino Llerena

Posted on

Porting my old dynamic form render from React to SolidJS

A few years ago I posted an implementation of a Dynamic Form Render working in ReactJS. Now with the advent of SolidJS I have ported that app to it with the intention of learning a little bit about this awesome library.

The idea behind a dynamic form implies designing a structure of components where each one of them represents an element inside of the form. A JSON object fits well with this kind of structure and each object inside of a list represents a text, textarea, radio and so on, as can be seen in this template.

As a starting point, our goal is to support the following element types:

TABLE 1 - LIST OF TYPES

The basic structure of the template follows the next pattern:

{
   formId: "",
   name: "",
   formElements:  ""
}
Enter fullscreen mode Exit fullscreen mode

TABLE 2 - BASIC FORM STRUCTURE

The first two properties represent an Id and Name, just for future extension, with the idea of having multiple forms as templates to be used in specific situations. The formElements property is intended to be a collection of ordered objects, and each object stores the particular configuration of one type of element inside the form.

Next there is an example of one object using Radio buttons with a collection of options. The elementId property works as an identifier, the type stores the kind of element (radio in this example) and formElementValues is the list of options available for this collection of radio buttons.

{
 "displayName": "Status", 
 "displayOrder": 9, 
 "elementId": "status", 
 "type": "radio", 
 "isHidden": ()=>(false),  
 "formElementValues": [{ 
   "displayName": "Approved", 
   "displayOrder": 1, 
   "elementvalueId": "approved" 
 }, {
   "displayName": "Declined",
   "displayOrder": 2,
   "elementvalueId": "declined"
 }, {
   "displayName": "Pending",
   "displayOrder": 3,
   "elementvalueId": "pending"
 }]
}

Enter fullscreen mode Exit fullscreen mode

TABLE 3 - JSON OBJECT REPRESENTING A COLLECTION OF RADIO BUTTONS

The object above allows us to display the following component in a form:

A RADIO BUTTON IN A FORM RENDER

Each value collected by the form has to be stored and used later, and to achieve that purpose another JSON object works well. In this implementation a JSON object called valueMap is used and each property matches the elementId inside of the form element.

Example of a valueMap with the data collected.
{
  "firstname": "John",
  "lastname": "Smith",
  "standardCompanyname": "SolidJS",
  "jobtitle": "Software Engineer",
  "gender": "male",
  "status": "approved"
}
Enter fullscreen mode Exit fullscreen mode

TABLE 4 - A VALUE MAP SAMPLE

It is important to note that the elementId in TABLE 3, “status” matches with the analog property in TABLE 4 with the “approved” value.

Brief technical details about this implementation:

The data store for this purpose ,createStore, is used because it gives some benefits to working with nested objects.

import { createStore } from 'solid-js/store'
import { data } from '../data/data';


export const [store, setStore] = createStore(data)


export const [valueMap, setValueMap] = createStore({
   firstname: '',
   relatives: [{id: '1', firstName: 'Juan', lastName: 'Lopez'}]
})
Enter fullscreen mode Exit fullscreen mode

The dynamic form render makes use of the component FormRender:

<FormRender 
          formElements={store.formElements}
          setValueMap={setValueMap}
          valueMap={valueMap}
          setStore={setStore}
 />
Enter fullscreen mode Exit fullscreen mode

It requires the configuration of the following properties:

TABLE 7 - THE FORM RENDER PROPERTIES

Here we have the dynamic form rendered, in action:

TABLE 8 - THE FORM RENDER IN ACTION

Final Notes:

  • The resulting code is cleaner than the original version, and the pattern used by SolidJS enforces that.
  • The similarity of both libraries allows us a smooth transition.
  • This is my first implementation using SolidJS and maybe some patterns have been broken, sorry for that.

The complete code can be found here

Recommended pages:

https://www.solidjs.com/

https://solid-dnd.com/

Top comments (0)