Form Templates
Describes the Form.io Form Template System
The Form.io template platform allows you to completely change the rendered HTML for any component within the Form.io platform. You can either create an entire template for all components, or simply override existing templates if you wish to just alter a few of the components.
There are several examples of templates that have been created which can be seen at the following URL's.
Bootstrap 3 - https://github.com/formio/bootstrap3
Semantic UI - https://github.com/formio/semantic
USWDS - https://github.com/formio/uswds
UK Government Design System - https://github.com/DigitalPatterns/formio-gds-template
Bulma - https://github.com/formio/bulma
Setting a CSS Framework
When setting up an application, you can select which CSS Framework you want to render the output to. Form.io currently supports the following frameworks:
Bootstrap 3 (bootstrap3)
Bootstrap 4 (bootstrap)
Semantic UI (semantic)
Other - Contact us for help implementing another framework!
The default template is currently Bootstrap 4 so if you want to use that, you don't have to do anything else. In order to switch to a different framework, you will need to set it globally so that the renderer will use the framework's templates.
If you are using a framework wrapper, you should import Templates from that wrapper instead of formio.js so that it will apply to the Formio instance within the wrapper as well. For example, if you are using react-formio
you should do:
Plugin registration
Templates can also be registered through the Plugin system, where an external template is provided to the renderer. For an example of how this is done, please see https://github.com/formio/semantic
While these examples represent complete templates, you can also create partial overrides as well.
Overriding templates
In addition to setting the global CSS Framework, you can also override specific templates within that framework. All templates within the renderer are pre-compiled templates. This means that instead of using HTML for each template, you will provide a template function, which simply takes a context variable and returns a string that is the HTML you would like to render. An example of a template function looks like the following.
Or if you are using ES6, it can be written easier as follows.
You can override a bunch of template functions by setting the current template with the templates you wish to override. This allows you to change the html output of the component even as the component continues to function the same. In order to do this, simply set the template on the Templates
object and the renderer will start using it.
You can do this one of two ways. First, by setting multiple templates:
Or individually:
You can extend an existing template by first getting the current template function and then call that function in addition to your own. This allows you to provide wrappers around certain elements within the renderer. Here is an example of how to do this.
IMPORTANT NOTE: These examples are in ES6. Depending on where you are making these changes, you may need to have them written in ES5 so that they will work with all browsers. Example.
Specific templates
Templates can be shared by multiple components. For example, the input
template is used by many components to render the html input element. Sometimes you may want to override it for only certain components but not all components. You can do this by setting the template name to include the specific information. This can either be the component type or the component property name (API key). You can even do both. The renderer will search in this order for the first match to determine which component to select:
If you set a template for 'input-number' it will only override the input template for number components. If you set a template for 'input-number-total' it would only override the input template for a number component with the property name of 'total';
Render modes
In addition to templates, there are a few render modes that allow different representations of the same component. The default mode is form
which will render all the components as form components. Another common mode is ```html`` which will render an html-only representation of the component without any form elements like inputs. This is useful for displaying data.
The built-in render modes are:
form - The default render to render as a form.
HTML - Render the data as generic html, instead of a form.
flat - Similar to form but will flatten out components like tabs and wizards that tend to hide data.
builder - A builder view of a component (not frequently used outside of the form builder).
To set the render mode, set it on the options when instantiating a form.
You can even create your own render modes and use them with your forms.
Custom Component Templates
You can create custom components using the same lifecycle methods.
An example can be found at https://github.com/formio/react-app-starterkit/blob/master/src/components/CheckMatrix.js
Template References (refs)
With the form.io templating functionality, the underlying DOM structure can be very different, even entirely custom. Because of this, adding events to the DOM necessitates being able to find the right part of the DOM to add the events. In order to do this, the formio.js library uses refs
to refer to parts of the DOM. These can then be selected regardless of where they are in the DOM.
When rendering a template, you can use the ref attribute to set a reference string. Then in the attach phase, you can get any DOM elements that have that ref, regardless of where they are. In order to facilitate this, formio.js has a "loadRefs" function that can find all the refs and adds them to this.refs
.
Layout component references
Layout components can contain other components within them including other components of the same type. For this reason, be careful with refs in layout components and be sure to append the component id to each key. This is so that loadRefs only selects the refs for that component and not any nested components.
Server Side Rendering
One of the goals of the 4.x branch was to make the formio.js renderer compatible with server side rendering. While this should be compatible with it due to the changes that were made, we haven't had a chance to fully test it out yet. We would greatly welcome some help in testing this out.
Here is how it is designed to work:
On the server side:
On the client side:
Last updated