Skip to content

Form Renderer

Mike edited this page Oct 17, 2024 · 18 revisions

The most important aspect of the Form.io platform is the ability to render a form dynamically within your application and then hook that form up to the REST API provided by the Form.io API platform. The Form Renderer within Form.io provides this capability.

Installation

As mentioned in the previous section, to use this library within your project, you will first need to install it as a dependency.

npm install --save angular-formio

Once you have the module installed, you will now need to include the form renderer within your application by adding the FormioModule as a dependency within your application as follows.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormioModule } from 'angular-formio';
import { MainComponent } from './main';

@NgModule({
  imports: [
    BrowserModule,
    FormioModule
  ],
  declarations: [
    MainComponent
  ],
  providers: [],
  bootstrap: [
    MainComponent
  ]
})
export class AppModule {}

Rendering

Once you have the module installed, you can now include the <formio> directive within your Modules template like the following.

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: '<formio src="https://examples.form.io/example"></formio>'
})
export class MainComponent {}

This provides a way to render the form within your application.

JSON Form Rendering

In addition to providing the URL of the form you wish to render, you can also pass the JSON form directly to the renderer as follows.

<formio [form]='{
    "title": "My Test Form",
    "components": [
        {
            "type": "textfield",
            "input": true,
            "tableView": true,
            "inputType": "text",
            "inputMask": "",
            "label": "First Name",
            "key": "firstName",
            "placeholder": "Enter your first name",
            "prefix": "",
            "suffix": "",
            "multiple": false,
            "defaultValue": "",
            "protected": false,
            "unique": false,
            "persistent": true,
            "validate": {
                "required": true,
                "minLength": 2,
                "maxLength": 10,
                "pattern": "",
                "custom": "",
                "customPrivate": false
            },
            "conditional": {
                "show": "",
                "when": null,
                "eq": ""
            }
        },
        {
            "type": "textfield",
            "input": true,
            "tableView": true,
            "inputType": "text",
            "inputMask": "",
            "label": "Last Name",
            "key": "lastName",
            "placeholder": "Enter your last name",
            "prefix": "",
            "suffix": "",
            "multiple": false,
            "defaultValue": "",
            "protected": false,
            "unique": false,
            "persistent": true,
            "validate": {
                "required": true,
                "minLength": 2,
                "maxLength": 10,
                "pattern": "",
                "custom": "",
                "customPrivate": false
            },
            "conditional": {
                "show": "",
                "when": null,
                "eq": ""
            }
        },
        {
            "input": true,
            "label": "Submit",
            "tableView": false,
            "key": "submit",
            "size": "md",
            "leftIcon": "",
            "rightIcon": "",
            "block": false,
            "action": "submit",
            "disableOnInvalid": true,
            "theme": "primary",
            "type": "button"
        }
    ]
}'></formio>

This is a very simple example. This library is capable of building very complex forms which include e-signatures, columns, panels, field conditionals, validation requirements, and the list goes on and on.

Inputs

The inputs for the <formio> directive allow you to control how the form renderer behaves. For example, to set the submission of a form (which will pre-populate the form with data), you can provide the following code which will set the form.

<formio src="https://examples.form.io/example" [submission]='{
  "data": {
    "firstName": "Joe",
    "lastName": "Smith",
    "email": "joe@example.com"
  }
}'></formio>

The following inputs are accepted.

Name Type Description
src String To set the source URL of the form (or submission) to be rendered. Example: src="https://examples.form.io/example"
form Object To render the JSON schema of a form. Example: [form]='{"components":[...]}'
url String This is a way to passively provide the form URL to the renderer without it submitting data to that url. This is different than "src" in that if you provide your Form API url, it will not submit data to this url. This is commonly used in conjunction with the "form" attribute, where you also need to allow for File uploads (since they require an API call to the form url).
submission Object The submission JSON to pre-poulate the form. Example: [submission]='{"data": {"name": "Joe Smith"}}'
refresh EventEmitter<Any> This allows you to refresh the form or the submission that is rendered within the renderer. EventEmitter must be type Any. See the section on Updating form and submissions below.
service FormioService Your own instance of the FormioService object to perform the requests.
readOnly Boolean Make the form (and submission) read only. Great for when you are rendering a previous submission that should not be editable.
viewOnly Boolean Show the form in "viewOnly" mode, where it does not show a form, but rather a view only representation of a form + submission data.
hideComponents Array An array of components that you wish to hide once the form is done rendering.
hooks Object Used to provide "hooks" into the form renderer, such as a "beforeSubmit" hook to trigger when the form is submitting.
language String The language code you wish to show this rendered form in. Example: "us-en"
options Object A JSON object of the following options.
hooks Hooks that allow you to hook into the behavior of the form directly. For now there are only the following.
  • beforeSubmit - Called before the form submits. See section below on Hooking into form submissions.
alerts Provide configuration for the alters that are triggered.
  • submitMessage - Provide the submit message that is shown when the form submits.
errors Provide configuration for the errors that are triggered.
  • message - Provide the submit message that is shown when an error occurs.

Handle Submissions

Once you have the form rendered within your application, the next step is to handle the submission within your Component. You can do this by using the (submit) output of the form renderer.

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: '<formio src="https://examples.form.io/example" (submit)="onSubmit()"></formio>'
})
export class MainComponent {
  onSubmit(submission: any) {
    console.log(submission); // This will print out the full submission from Form.io API.
  }
}

Hooking into Form Submissions

Let's suppose you need to hook into the Form submission, make a call to your own service to perform a custom validation on that submission, and then when your validation passes, allow the submission to be handled. You may also want to tell the form that an error occurred within the Form submission and then provide the error. To do this, you will need to provide the options.hooks.beforeSubmit callback, which works as follows.

<formio src='https://examples.form.io/example' options='{
  "hooks": {
    "beforeSubmit": function(submission, callback) {
        console.log(submission);
        // Do something asynchronously.
        setTimeout(function() {
          // Callback with a possibly manipulated submission.
          callback(null, submission);
        }, 1000);
    }
  }
}'></formio>

You may also wish to provide your own custom error.

<formio src='https://examples.form.io/example' options='{
  "hooks": {
    "beforeSubmit": function(submission, callback) {
        console.log(submission);
        // Do something asynchronously.
        setTimeout(function() {
          // Callback with a possibly manipulated submission.
          callback({
            message: "Something bad happened.",
            component: null
          }, null);
        }, 1000);
    }
  }
}'></formio>

Updating forms and submissions

To update the form or the submission within the Angular renderer, you will need to pass along the refresh input property when rendering the form. The value of the refresh property will be an event emitter that will emit a FormioRefreshValue value that will update either the submission or the form.

As an example, if you wish to dynamically alter the form after it is rendered, you can do the following.

<formio [form]="myForm" [refresh]="refreshForm"></formio>
@Component({
  ...
  ...
})
export class MyComponent implements OnInit {
  ngOnInit() {
    this.myForm = {
      components: [....];
    };
    this.refreshForm = new EventEmitter();
  }

  changeForm() {
    this.myForm.components.push({
      type: 'textfield',
      label: 'New Field',
      key: 'newField',
      input: true
    });
    this.refreshForm.emit({
      form: this.myForm
    });
  }
}

If you wish to update both the form and submission, you can provide it as follows.

@Component({
  ...
  ...
})
export class MyComponent implements OnInit {
  ngOnInit() {
    this.myForm = {
      components: [....];
    };
    this.refreshForm = new EventEmitter();
  }

  changeForm() {
    this.myForm.components.push({
      type: 'textfield',
      label: 'New Field',
      key: 'newField',
      input: true
    });
    this.refreshForm.emit({
      form: this.myForm,
      submission: {
        data: {
          newField: 'Testing'
        }
      }
    });
  }
}

Outputs (Events)

With the <formio> directive, you can register for a number of different events that fire as the Form is being used and submitted. These events can be attached with the typical Angular 2 way using the following syntax.

<formio src="https://examples.form.io/example" (submit)="onSubmit($event)"></formio>

The following events are provided.

Name Description
(submit) Called when the form is submitted. The submission object is passed to the callback function.
(render) Called when the form is done rendering.
(beforeSubmit) Called before a submission is made. The submission object is passed to the callback function. Note: If you need to manipulate the data, or even provide custom validations, then you should use the options.hooks.beforeSubmit handler instead. See documentation above.
(change) Called when the form has been changed as in when someone is filling it out.
(invalid) Called when the form is invalid.
(nextPage) Called when the form is in Wizard mode and goes to the next page.
(prevPage) Called when the form is in Wizard mode and goes to the previous page.
(customEvent) Called when the form contains a Button configured with a custom event and is pressed.
(errorChange) Called when the form errors change.
(formLoad) Called when the form is done loading.
(ready) Called when the form renderer is ready. This returns the Form instance object to the callback function.

Custom Components

The Form.io renderer also provides a way to introduce your own custom components within the renderer / builder. To see an example of how this works, please take a look at the Angular Demo application. This application introduces the CheckMatrix component which can be seen @ https://github.com/formio/angular-demo/blob/master/src/app/components/CheckMatrix.js.

To register this component, you simply need to add the following to your main app.module.ts file.

import './CheckMatrix';