# Application Development

The most advanced way to use Form.io is to embed the Form.io renderer directly within any Web based application you are developing. The Form.io platform supports a large number of different application development frameworks such as the following.

| Framework        | Github URL                                                                                                 |
| ---------------- | ---------------------------------------------------------------------------------------------------------- |
| Vanilla JS       | [**https://github.com/formio/formio.js**](https://github.com/formio/formio.js)                             |
| Angular          | [**https://github.com/formio/angular**](https://github.com/formio/angular)                                 |
| Angular Material | [**https://github.com/formio/angular-material-formio**](https://github.com/formio/angular-material-formio) |
| AngularJS        | [**https://github.com/formio/ngFormio**](https://github.com/formio/ngFormio)                               |
| React            | [**https://github.com/formio/react-formio**](https://github.com/formio/react-formio)                       |
| Vue              | [**https://github.com/formio/vue-formio**](https://github.com/formio/vue-formio)                           |
| Aurelia          | [**https://github.com/formio/aurelia-formio**](https://github.com/formio/aurelia-formio)                   |
| React Native     | [**https://github.com/formio/react-native-formio**](https://github.com/formio/react-native-formio)         |

Each one of these landing pages provides its own documentation on how to create new applications using these frameworks. For this tutorial, however, we will pick one (**Angular**) and demonstrate how an application can be created using this powerful platform. For this tutorial, we will build an application that demonstrates many of the different features of the Form.io platform; An **Event Registration Application** using the [**Angular framework**](https://angular.io).

Let's get started by Creating a new project.

## Create your Project

After you create a new account at <https://portal.form.io>, you will see a page that looks like the image below. The first thing we will do is to create a new Project, which we can do by clicking the **Angular** button, or by clicking on the **Create Project** button.

![](https://3305536326-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MPHoF2HwOA0s5HV_AIB%2Fuploads%2FRk0itSkt9aFHZzShvME8%2FAppdev1.png?alt=media\&token=14af943b-3ec3-4b76-9893-fd1d13e60fb6)

Provide your project information like so, and then click **Create Project**

![](https://3305536326-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MPHoF2HwOA0s5HV_AIB%2Fuploads%2Ft00hOX82g15aiQpgAxa9%2Fappdev2.png?alt=media\&token=532fa42c-861c-47c3-90cb-30a69a1f40a0)

## Create Resources

An Event Registration application will need to store some “structured” objects called **Events**. These are called **Resources** in Form.io, so let's create a new **Event** by clicking on the following.

![](https://3305536326-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MPHoF2HwOA0s5HV_AIB%2Fuploads%2FPiHm7mo6OOi9uAzjiEQg%2Fappdev3.png?alt=media\&token=7e632646-48e8-439c-8f8a-1257ccc5b63f)

We will then build our **Event** object using a form builder. We could also provide some field validations and such, but for now we will keep the form simple.

![](https://3305536326-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MPHoF2HwOA0s5HV_AIB%2Fuploads%2FQ04GVa1BD7wqpAUuhyRd%2Fappdev4.png?alt=media\&token=92e72f1b-5f94-4deb-a168-dfbc13878441)

When you are done, click on **Create Resource.** This immediately demonstrates one of the differentiating features of Form.io, where Data Models and Resources can be constructed using a simple drag-and-drop form builder interface. We can even control who has access to create this Event within the Access section.

### Assigning Permissions

You now need to allow **Authenticated** users to read all events. We will also want them to be able to **create their own**, **update their own**, and **delete their own** events. To do this, click on **Access** section, and configure the settings as follows.

![](https://3305536326-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MPHoF2HwOA0s5HV_AIB%2Fuploads%2FUyuPoSzsZ7v9RxQmDNI7%2Fappdev5.png?alt=media\&token=727a7a6f-0f98-4262-b6ef-cd98299eb84a)

The settings should automatically save when you add this role to these permissions.

## Event Registration Form

Now that we have an Event resource, we need a way for people to register to attend the Event. This is a great use case for a **Form** that provides “unstructured” data that references Resources.

Let’s create a new form by clicking on the **Forms** section and pressing **New Form**, and then selecting ***API Web Form***.

![](https://3305536326-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MPHoF2HwOA0s5HV_AIB%2Fuploads%2F2wpVRkOIpx89O1sbQnwX%2FLaunch4.png?alt=media\&token=e5d12948-766b-49fe-bca1-5496ed3ed4b9)

Here we will build a **Registration** form. The first field we will add to this form is a **Select** component field like so…

![](https://3305536326-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MPHoF2HwOA0s5HV_AIB%2Fuploads%2F56HVY8dzUWhdThWVvn9F%2Fappdev6.png?alt=media\&token=cb2997b8-7399-43b9-87d6-6a8e99a44638)

Once we add this, field, we will give it a label of **Event**.

![](https://3305536326-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MPHoF2HwOA0s5HV_AIB%2Fuploads%2F3WsOtTGTDxjLTeGWBWGY%2Fappdev7.png?alt=media\&token=de535a51-cdf5-4b7e-a55a-3c6eb8756b86)

We will then click on the **Data** tab, and then set the **Data Source** to **Resource**, and then select the **Event** Resource like so.

![](https://3305536326-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MPHoF2HwOA0s5HV_AIB%2Fuploads%2F686XGbfGzgr9BvHWvWL4%2Fappdev8.png?alt=media\&token=adb73e46-baee-4b5e-9121-6faec26a5099)

Finally for the **Item Template**, we will provide the following code.

```
<span>{{ item.data.title }}</span>
```

Like the following shows.

![The Item Template for an Event resource select dropdown](https://3305536326-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MPHoF2HwOA0s5HV_AIB%2F-MRr2WD6cHqSWRl04anO%2F-MRr2lZnuKa1-Hf-1UcH%2FForm.IO%202021-01-24%2019-00-48.png?alt=media\&token=62decb46-3540-4ee7-af6f-68b2b89cbaaa)

Next, we can press the **Save** button to add the field to our form. Now that we have an **Event** resource field, we can add other fields to the registration form like so…

![](https://3305536326-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MPHoF2HwOA0s5HV_AIB%2Fuploads%2FXFH6xbybJKw1fILnfXw7%2Fappdev9.png?alt=media\&token=1d9a1890-0f78-4506-9471-ea10aacd6b49)

We will now press the **Create Form** button to save our form. Now, let us configure the access permissions of this form.

### Access Permissions

We also need to ensure that **Authenticated** users can submit the Registration Form, so we will go to the **Access** section and configure the following.

![](https://3305536326-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MPHoF2HwOA0s5HV_AIB%2Fuploads%2F6kcU9sjIkFSj2UpnRVVo%2Fappdev10.png?alt=media\&token=ba375a95-fb84-41fd-a7bb-565b214e7752)

The permissions should automatically save when you set them.

We are now done setting up our Form.io Resources + Forms for our application, now let's build an app!

## Create an Application

To get started quickly in [**Angular**](https://angular.io/), we recommend using the [**Angular CLI**](https://cli.angular.io/) tool to create our application. We can do this by typing the following within your terminal.

```
npm install -g @angular/cli
ng new eventmanager --style=scss --routing=true --strict=false
```

This will now create a new application within the folder **eventmananger**, we can navigate into that folder by typing the following in the terminal.

```
cd eventmanager
```

We will now bring in all of our dependencies into the application by typing the following within the application folder.

```
npm install --save bootstrap@4 bootstrap-icons formiojs @angular/elements ngx-bootstrap --legacy-peer-deps;
npm install --save @formio/angular --tag=rc --legacy-peer-deps
```

Or if you are using yarn, you can instead run the following

<pre><code><strong>yarn add bootstrap@4 bootstrap-icons formiojs @angular/elements ngx-bootstrap;
</strong><strong>yarn add @formio/angular@rc
</strong></code></pre>

We can now setup the styles for our application by editing the following file.

***src/styles.scss***

```
$bootstrap-icons-font-dir:'../node_modules/bootstrap-icons/font/fonts';
@import "bootstrap/scss/bootstrap.scss";
@import "bootstrap-icons/font/bootstrap-icons.scss";
```

We will now start our application by typing the following in the terminal.

```
ng serve
```

You should now be able to go to **<http://localhost:4200>** in your browser to see the default Angular page.

We can now create a home page, by typing the following in the terminal.

```
ng g component home
```

And then provide the following code in the following file.

***src/app/home/home.component.html***

```
<div class="jumbotron">
  <h3>Event Registration Application</h3>
  <p>This is an example home page for the Event Registration Application</p>
</div>
```

And then add the following to the routes.

***src/app/app-routing.module.ts***

```
...
import { HomeComponent } from './home/home.component';

const routes: Routes = [
  {
    path: '',
    component: HomeComponent
  }
];

...
```

Next, we will need to make sure that our root component, which is called AppComponent is able to display the content at this route. To do this, we will need to add a **router-outlet** to the template of this component. You can do this by opening up the following file and changing it to only have the following content.

***src/app/app.component.html***

```
<div class="container pt-3">
  <router-outlet></router-outlet>
</div>
```

Now, when you refresh you should see your home component as follows.

<figure><img src="https://3305536326-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MPHoF2HwOA0s5HV_AIB%2Fuploads%2FVI0Z1mgQSt0wIw4ECYhu%2FScreen%20Shot%202023-01-19%20at%207.50.14%20AM.png?alt=media&#x26;token=ab714ee6-1792-428f-ac97-25430d22cacb" alt=""><figcaption></figcaption></figure>

## Application Configuration

Now that we have an application running, we will need create a configuration file so that we can tell the application which Form.io project we are pointed to.

To do this, we will create a new **config.ts** file as follows.

***src/app/config.ts***

```
export const AppConfig = {
  appUrl: 'https://yourproject.form.io',
  apiUrl: 'https://api.form.io'
};
```

You will need to make sure that you replace “yourproject” with the name of your Project URL which you can find at the following location within your Project page.

![](https://3305536326-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MPHoF2HwOA0s5HV_AIB%2Fuploads%2FPU1KVnfw2Tf6g82rS2hy%2Fappdev11.png?alt=media\&token=d3e516d7-6600-4b42-85ac-d00071457082)

Next, we will need to register this AppConfig within the main module by adding the following to the **app.module.ts** file.

***src/app/app.module.ts***

```
...
...
import { AppConfig } from './config';
import { FormioAppConfig } from '@formio/angular';

@NgModule({
  ...
  providers: [
    {provide: FormioAppConfig, useValue: AppConfig},
  ],
  ...
})
export class AppModule { }
```

## User Authentication

Now that we have the configuration file in place, we can setup User Authentication.

[**Angular Auth Documentation**](https://github.com/formio/angular-formio/wiki/User-Authentication)

We accomplish this by first creating an Angular module that will contain the authentication routes.

```
ng g module auth
```

This will create a new folder within our application within the **src/app** folder, which we can then use to include all the necessary modules to bring in Authentication.

***src/app/auth/auth.module.ts***

```
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { FormioAuth, FormioAuthRoutes } from '@formio/angular/auth';


@NgModule({
  declarations: [],
  imports: [
    CommonModule,
    FormioAuth,
    RouterModule.forChild(FormioAuthRoutes())
  ]
})
export class AuthModule { }
```

We must now register the Authentication module by lazy loading the module within the “auth” route. We can accomplish this within the following file.

***src/app/app-routing.module.ts***

```
const routes: Routes = [
  {
    path: '',
    component: HomeComponent
  },
  {
    path: 'auth',
    loadChildren: () => import('./auth/auth.module').then(m => m.AuthModule)
  }
];
```

Next, we just need to register the service providers with configurations within the **app.module.ts** file.

***src/app/app.module.ts***

```
...
import { AppConfig } from './config';
import { FormioAppConfig } from '@formio/angular';
import { FormioResources } from '@formio/angular/resource';
import { FormioAuthService, FormioAuthConfig } from '@formio/angular/auth';

@NgModule({
  ...
  providers: [
    {provide: FormioAppConfig, useValue: AppConfig},
    FormioResources,
    FormioAuthService,
    {provide: FormioAuthConfig, useValue: {
      login: {
        form: 'user/login'
      },
      register: {
        form: 'user/register'
      }
    }}
  ],
  ...
```

We should now add a header to our application so that we can login, and see our login state.

We can now add a header to our application by adding the **nav** HTML to our existing router-outlet code we created earlier within the **app.component.html** file. It should look like the following.

***src/app/app.component.html***

```
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
  <div class="container">
    <a class="navbar-brand" href="#"><img style="height: 2em;" src="https://portal.form.io/images/formio-logo.png" /></a>
    <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarsExample07" aria-controls="navbarsExample07" aria-expanded="false" aria-label="Toggle navigation">
      <span class="navbar-toggler-icon"></span>
    </button>
    <div class="collapse navbar-collapse" id="navbarsExample07">
      <ul class="navbar-nav me-auto mb-2 mb-lg-0">
        <li class="nav-item">
          <a class="nav-link active" aria-current="page" href="#"><i class="bi-house-fill"></i></a>
        </li>
      </ul>
      <ul class="nav navbar-nav ml-auto">
        <li class="nav-item" routerLinkActive="active" *ngIf="!auth.authenticated">
          <a class="nav-link" routerLink="auth">Login | Register</a>
        </li>
        <li class="nav-item" *ngIf="auth.authenticated">
          <a class="nav-link" routerLink="/" (click)="auth.logout()"><span class="glyphicon glyphicon-off"></span> Logout</a>
        </li>
      </ul>
    </div>
  </div>
</nav>
<div class="container pt-3">
  <router-outlet></router-outlet>
</div>
```

Next, we will need to add some logic within the **AppComponent** class to handle the authentication workflow.

***src/app/app.component.ts***

```
import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { FormioAuthService } from '@formio/angular/auth';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = 'eventmanager';
  constructor(
    public auth: FormioAuthService,
    private router: Router
  ) {
    this.auth.onLogin.subscribe(() => {
      this.router.navigate(['/']);
    });

    this.auth.onLogout.subscribe(() => {
      this.router.navigate(['/auth/login']);
    });

    this.auth.onRegister.subscribe(() => {
      this.router.navigate(['/']);
    });
  }
}
```

We should now see the following within our application with a working authentication and registration system.

![](https://help.form.io/assets/img/userguide/authapp.png)

## Application Resources

Now that you have a running application with authentication, we can now add the **Event** resource using the **FormioResource** module.

[Angular Resource Documentation](https://github.com/formio/angular-formio/wiki/Resource-Management)

```
ng g module event
```

We will then add the following to the following module file.

***src/app/event/event.module.ts***

```
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import {
  FormioResource,
  FormioResourceRoutes,
  FormioResourceConfig,
  FormioResourceService
} from '@formio/angular/resource';

@NgModule({
  declarations: [],
  imports: [
    CommonModule,
    FormioResource,
    RouterModule.forChild(FormioResourceRoutes())
  ],
  providers: [
    FormioResourceService,
    {provide: FormioResourceConfig, useValue: {
      name: 'event',
      form: 'event'
    }}
  ]
})
export class EventModule { }

```

The next thing we will need to do is to register this event within the router.

***src/app/app-routing.module.ts***

```
const routes: Routes = [
  ...
  ...
  {
    path: 'event',
    loadChildren: () => import('./event/event.module').then(m => m.EventModule)
  }
];
```

Finally, you will add a link to the navigation bar to go to the Events section when you click it.

***src/app/app.component.html***

```
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
  <div class="container">
    <a class="navbar-brand" href="#"><img style="height: 2em;" src="https://portal.form.io/images/formio-logo.png" /></a>
    <ul class="nav navbar-nav mr-auto">
      ...
      <li class="nav-item" routerLinkActive="event" *ngIf="auth.authenticated">
        <a class="nav-link" routerLink="event"><i class="bi-calendar"></i> Events</a>
      </li>
    </ul>
    ...
  </div>
</nav>
...
```

You now have a complete Event management system!

![](https://help.form.io/assets/img/userguide/eventindex.png)

Let’s add our Registration form!

## Event Registration

We will now add the **Event Registration** form to the event. Since forms and resources are conceptually the same thing in Form.io, we can use a nested resource to attach forms to any resource within our application. We can start by adding a submodule within Angular.

```
ng g module event/register
```

We can now add the following to the created file.

***src/app/event/register/register.module.ts***

```
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import {
  FormioResource,
  FormioResourceRoutes,
  FormioResourceConfig,
  FormioResourceService
} from '@formio/angular/resource';

@NgModule({
  declarations: [],
  imports: [
    CommonModule,
    FormioResource,
    RouterModule.forChild(FormioResourceRoutes())
  ],
  providers: [
    FormioResourceService,
    {provide: FormioResourceConfig, useValue: {
      name: 'registration',
      form: 'registration',
      parents: [
        'event',
        {
          field: 'user',
          resource: 'currentUser',
          filter: false
        }
      ]
    }}
  ]
})
export class RegisterModule { }

```

Notice that we added the **parents** construct to our **providers**. This tells the Form.io Angular Resource system that this is nested within the Event resource as well as should contain the currently logged in User assigned to the new records as well.

Next, we need to mount this nested resource within the Event resource. To do this, we add it to the children of the Event resource routes as follows.

***src/app/event/event.module.ts***

<pre><code>...
import { RouterModule, Routes } from '@angular/router';
...

<strong>const eventRoutes: Routes = FormioResourceRoutes();
</strong>eventRoutes[2].children.push({
  path: 'registrations',
  loadChildren: () => import('./register/register.module').then(m => m.RegisterModule)
});

@NgModule({
  declarations: [],
  imports: [
    ...
    RouterModule.forChild(eventRoutes)
  ],
  ...
})
export class EventModule { }
</code></pre>

We can now navigate to the following url to see the Forms for a specific event, as well as all the registrations within that Event.

```
http://localhost:4200/event/[EVENTID]/registrations
```

Next, we will need to change the Event resource view so that we can add the tab to the interface.

```
ng g component event/resource
```

We can now add the following the the event resource html.

***src/app/event/resource/resource.component.html***

```
<ul class="nav nav-tabs" style="margin-bottom: 10px;">
  <li class="nav-item"><a class="nav-link" routerLink="../"><i class="bi-chevron-left"></i></a></li>
  <li class="nav-item"><a class="nav-link" routerLink="view" routerLinkActive="active">View</a></li>
  <li class="nav-item"><a class="nav-link" routerLink="registrations" routerLinkActive="active">Registrations</a></li>
  <li class="nav-item"><a class="nav-link" routerLink="edit" routerLinkActive="active">Edit</a></li>
  <li class="nav-item"><a class="nav-link" routerLink="delete" routerLinkActive="active"><span class="bi-trash"></span></a></li>
</ul>
<router-outlet></router-outlet>
```

Next, we will need to extend the **FormioResourceComponent**

***src/app/event/resource/resource.component.ts***

```
import { Component } from '@angular/core';
import { FormioResourceComponent } from '@formio/angular/resource';

@Component({
  selector: 'app-resource',
  templateUrl: './resource.component.html',
  styleUrls: ['./resource.component.scss']
})
export class ResourceComponent extends FormioResourceComponent {}
```

And finally, we can register this within the routes using the following.

***src/app/event/event.module.ts***

```
const eventRoutes: Routes = FormioResourceRoutes({
  resource: ResourceComponent
});
```

This should create the following interface, where we can now view all of the registrations within an Event.

![](https://help.form.io/assets/img/userguide/eventform.png)

Let’s now change the Event view page to add a **Register for this Event** button!

## Event View

To change the view of the Event, we can use the same method we did for the Resource component, but this time we will create one for the event view.

```
ng g component event/view
```

We can now modify the following template with the following.

***src/app/event/view/view\.component.html***

```
<div class="row">
  <div class="col col-sm-6">
    <div class="card">
      <div class="card-header bg-primary text-white">
        <h3 class="card-title">Event Information</h3>
      </div>
      <ul class="list-group list-group-flush">
        <li class="list-group-item"><strong>Title:</strong> {{ service.resource.data.title }}</li>
        <li class="list-group-item"><strong>Description:</strong> {{ service.resource.data.description }}</li>
        <li class="list-group-item"><strong>Date:</strong> {{ service.resource.data.date }}</li>
      </ul>
    </div>
  </div>
  <div class="col col-sm-6">
    <div class="card">
      <div class="card-header bg-success text-white">
        <h3 class="card-title">Event Registration</h3>
      </div>
      <div class="card-body">
        <a routerLink="../registrations/new" class="btn btn-primary">Register for this Event</a>
      </div>
    </div>
  </div>
</div>
```

Next, we need to extend the **FormioResourceView** as follows.

***src/app/event/view/view\.component.ts***

```
import { Component } from '@angular/core';
import { FormioResourceViewComponent } from '@formio/angular/resource';

@Component({
  selector: 'app-view',
  templateUrl: './view.component.html',
  styleUrls: ['./view.component.scss']
})
export class ViewComponent extends FormioResourceViewComponent {}
```

And finally, we will register this with the **FormioResourceRoutes** as follows.

***src/app/event/event.module.ts***

```
const eventRoutes: Routes = FormioResourceRoutes({
  resource: ResourceComponent,
  view: ViewComponent
});
```

This produces the following result…

![](https://help.form.io/assets/img/userguide/eventview.png)

We now have a full working Event Management system, which even allows for other users to create an account and Register for this event. We hope that this walkthrough guide provides you a solid footing on building your next Progressive Web Application on Form.io!

If you would like to download the code behind this application, then go to [**Event Manager Github Page**](https://github.com/formio/eventmanager).
