Porting my old dynamic form render from React to SolidJS
Tags: programming, javascript, solidjs, webdev
Published: 2023-02-16 02:35:27

A few years ago I posted an implementation of a [Dynamic Form Render](https://github.com/GinoLlerena/dynamicform) 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](https://github.com/GinoLlerena/mysolidform/blob/main/src/data/data.js). 

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

![TABLE 1 - LIST OF TYPES ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6lsq1q65cb0mlhx3lrw7.png)

The basic structure of the template follows the next pattern:

```
{
   formId: "",
   name: "",
   formElements:  ""
}
```

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"
 }]
}

```
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w3qglobmza8jm9gneikg.png)


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"
}
```

 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](https://github.com/GinoLlerena/mysolidform/blob/main/src/store/store.js) for this purpose ,[createStore](https://www.solidjs.com/tutorial/stores_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'}]
})
```

The dynamic form render makes use of the component FormRender:

```
<FormRender 
          formElements={store.formElements}
          setValueMap={setValueMap}
          valueMap={valueMap}
          setStore={setStore}
 />
```

It requires the configuration of the following properties:


![TABLE 7 - THE FORM RENDER PROPERTIES](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k91masltigtsn70wzqr5.png)

Here we have the dynamic form rendered, in action:


![TABLE 8 - THE FORM RENDER IN ACTION](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qfocnvfhk5samih0j9r9.png)


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](https://github.com/GinoLlerena/mysolidform)

**Recommended pages:**

https://www.solidjs.com/

https://solid-dnd.com/