Formio and its Angular sibling are great frameworks to create user-editable web forms. The standard components cover the usual suspects, but when you need something slightly different, you find out that creating custom components is half-heartedly supported. Custom components are considered a "community feature", with Bálint as main contributor (March 2020).
I had mixed luck when trying to compile the rating component. It has cost me weeks of debugging - main problems being version conflicts and occasional infinite loops which were resolved later.
I gave up and started from scratch, with only the latest versions available: "angular-formio": "4.6.10"
and Angular 9.0.7
. Within one day, everthing worked - well, at least for me, your mileage may vary and you assume that ongoing formio development will introduces new issues.
The example generates inline and multiline radio buttons, yes/no buttons as a special case, large checkbox-like buttons and a multi-checkbox component.
I need these because the usual radio buttons are much to small and difficult to hit on tablets for patients' self-assessment.
I found a simple way to re-use and modify existing component editors for custom components. In the example, I have removed the CSS text field and added a select box to display other styles such of Bootstrap buttons.
Check files radio-buttons-formio.ts
and assets/radio-buttons.edit.json
for the most important changes.
-
Find the existing component that is similar to you new component. For radio buttons, I choose the edit form for standard radio buttons
Components.components.radio.editForm
. -
Write the stringified version of the component to the log using
console.log(JSON.stringify(Components.components.radio.editForm()))
-
Copy the string from the debugger window into a new file
assets/radio-buttons.edit.json
. Tell me if there is an easier method to do the JSON export, but since I have to do it only once, it was good enough for me. -
Use Notepad++ with the JS-plugin to format the JSON code for humans.
-
Make edits in the file. I removed the mostly-useless CSS class text field, and added a select box to select one of the Bootstrap button styles. The key of the field is
buttonStyle
.
{
"components": [{
"type": "tabs",
"key": "tabs",
"components": [{
...
"type": "select",
"input": true,
"key": "buttonStyle",
"label": "Bootstrap button color style",
"tooltip": "<a href='https://getbootstrap.com/docs/4.0/components/buttons/'>Button style</a>",
"weight": 400,
"defaultValue": "primary",
"dataSrc": "values",
"data": {
"values": [{
"label": "Primary",
"value": "primary"
}, {
"label": "Secondary",
"value": "secondary"
...
- Use
import radioButtonEditFormJson from '../../assets/radio-buttons.edit.json'
inradio-buttons.formio.ts
to get the parsed JSON
function radioEditForm() {
// You can do some additional dynamic changes by modifying JSON here
return radioButtonEditFormJson
}
- Add function name without () as editForm in COMPONENT_OPTIONS.
const COMPONENT_OPTIONS: FormioCustomComponentInfo = {
type: 'radiobuttons',
selector: 'radio-buttons',
title: 'Radio Buttons',
group: 'basic',
icon: 'fa fa-star',
fieldOptions: ['label', 'values', 'key', 'hidden', 'buttonStyle'],
editForm: radioEditForm // Use editForm from Radio buttons
- Add the field name
buttonStyle
and other fields you need tofieldOptions
- When you get an error message
Consider using '--resolveJsonModule' to import module with '.json' extension
, add the following tocompilerOptions
intsconfig.json
:
"resolveJsonModule": true,
"esModuleInterop": true,
- Now you can use
buttonStyle
by importing it into the component
@Input()
buttonStyle: string
- and in .html
class="btn-outline-{{buttonStyle}}
When you want to present a recommended subselection of components for users, you can create a custom form. See app.component.ts and app.component.html for quick-and-dirty solution.
Thanks to @travist.
Some Cypress tests have been added. Use ng e2e
to start; have some coffee ready, the first start may need more than 1 minute.
Using fortawesome for access to version 5.x fontawesome now. Workaround for missing icons. Future versions of formio will support version 5.x icons.
onInit
of the component is called 6 times when a key in any editor is pressed. Reported as #507.
Here is a reproducable case that generates an infinite loop in the browser: