Build dynamic forms using JET! — Part 5/5
Web components can be treated as the unit of re-usability in JET, It also helps us to encapsulate complex view and model logic behind simple interface so that the component can be easily distributed and consumed by other developers.
The Web Component Breakup
Component Metadata
The Component Interface description aka component metadata generally defined in the component.json file defines the 3 primary ways your component can interact with the rest of the page.
- properties: the attributes your component accepts when it is declared in html. eg. metadata, value are the properties accepted by the below component .
<demo-component metadata=”[[ metadata]]” value=”{{ value }}”></demo-component>
2. methods: you can expose methods/JS functions via the html DOM element of the component which you could invoke via JS.
3. events: Your component can dispatch events to let page know about an event.
Component View Model
The view model or simply model layer is responsible for creating the JS layer where your component logic would reside.
Component View
The view layer would contain the html or the rendering logic.
Component Loader
The loader (generally loader.js file) is responsible for loading all the files and bootstrapping it so that the component gets registered as web component.
Dynamic Form as Web Component
Finally we are wrapping up this series by creating a dynamic form component. It works on the ideas that we discussed in parts 1–4.
See the final app hosted here. you can play along with the component using the live editor built using the monaco-editor.
Dissecting the Dynamic Form Component
component.json
The component has been built to accept many properties, some of them like labelEdge, labelWidth etc are standard form properties which we apply to the internal oj-form-layout component. The most important ones are metadata, and value (others have default values) as you can see used in the final demo app here. So we have got our metadata using which we could render the form and a value using which we could provide default value and collect the user entered values.
dynamic-form-viewModel.js
The view-model contains the logic for creating the form, mainly these functions are responsible.
- generateField : Fetches the control/field dependencies using RequireJs. Inserts the field into _metadataArr, applies property using the applyProperties method and finally resolves the promise if everything goes fine.
- bindingsApplied : It’s a lifecycle method which gets invoked after the JS model gets bounded with the html. It loops over the form fields and inserts one field after another. Once the fields are inserted, it subscribes to the value property to update value changes and sets the display properties for oj-form-layout.
- applyProperties : Uses the setProperties method on each component to set the user specified properties. this step includes add properties like labelHint, validators etc.
- validate : checks with oj-validaton-group to validate the form state.
- showMessages : displays all the error/warn/info messages , useful for displaying form errors.
- focusOn : moves the focus on a particular field. useful for focusing on fields with error.
dynamic-form-view.html
The html or view part is very straightforward and it uses the following:
- oj-validation-group : responsible for validating the form and communicating the state to the page via valid property of the component.
- oj-form-layout: Responsible for generating the for layout and making it responsive .
- oj-bind-for-each : Loops through the form fields and renders them.
- oj-bind-if : conditional rendering based on field type.