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:
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:
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 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'}]
})
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:
Here we have the dynamic form rendered, 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:
Top comments (0)