LogoLogo
Getting StartedDevelopersDeployment GuideGet Help
  • Quick Links
  • Welcome to Form.io
    • Getting Started With Form.io
    • Launch a Form
    • Overview of Form.io
  • Developer Tool Ecosystem
    • PDF Solution
    • Enterprise Form Builder
    • Form View Pro
    • The Security Module
    • Accessibility Compliance Module
    • Developer License
    • SQL Connector - Deprecated
    • Integration Libraries
    • Form.io CLI Tool
  • User Guide
    • Introduction
    • Form.io Developer Portal
    • Teams
    • Projects
      • Project UI
      • Project Settings
      • Stages
      • Multi-Tenancy
    • Resources
      • ResourceJS
    • Forms
      • Form Creation
      • Form Types
      • PDF Forms
      • Embedding a Form
      • Form Revisions
      • Form Settings
    • Form Building
      • Form Builder UI
      • Form Components
        • Component Settings
        • Basic Components
          • Resource as Select Component Data Source
        • Advanced Components
        • Layout Components
        • Data Components
        • Premium Components
          • Nested Forms
        • Custom Components
      • Logic & Conditions
      • Existing Resource Fields
      • Actions
    • Submissions
      • Accessing Submissions
      • Importing Submissions
    • Form.io eSignature - Coming Soon
    • Form.io Reporting Module
    • PDF Template Designer
    • Form View Pro
    • Form Manager
    • Enterprise Form Builder Module
      • Installation
      • User Guide
  • Developer Guide
    • Introduction
      • Application Development
      • API Documentation
    • Form Development
      • Form Renderer
      • Form Builder
      • Form Embedding
      • Form Evaluations
      • Form Templates
      • Custom Components
      • Translations
    • JavaScript Development
      • JavaScript SDK
      • JavaScript Frameworks
      • JavaScript Utilities
    • Authentication and Authorization
      • SAML
      • OAuth
      • LDAP
      • Resource Based Authentication
      • Email Authentication
      • Two-Factor Authentication
    • Roles and Permissions
      • Field Match-Based Access
      • Field-Based Resource Access
      • Group Permissions
    • Integrations
      • Email Integrations
      • File Storage
      • Google Developer Console
      • eSign Integrations
      • Relational Databases
    • Modules
    • Fetch Plugin API
    • CSS Frameworks
    • Offline Mode
    • Audit Logging
  • Deployments
    • Self-Hosted Deployment
      • Local Deployment
        • Local File Storage
      • Kubernetes
      • Cloud Deployment
        • AWS Deployment
          • AWS Lambda
          • Form.io/AWS Elastic Beanstalk End-To-End Encrypted Deployment
        • Azure Deployment
          • Azure App Service
            • Azure MSSQL Connector - Deprecated
          • Azure Virtual Machine
          • Azure Kubernetes Service
          • Set up the DB
        • GCP Deployment
          • GCP Cloud Run
      • On-Premise Deployment
      • Enterprise Server
      • PDF Server
    • Deployment Configurations
      • DNS Configuration
      • Load Balancer Configuration
    • Licenses
      • License Management
      • Library Licenses
    • Portal Base Project
      • Portal SSO
      • Portal Translations
    • Maintenance and Migration
      • Changes to Premium Libraries
  • FAQ
    • FAQ
    • Tutorials & Workflows
      • Password Reset
      • Dynamic Select Filtering
      • Approval Workflow
      • SSO Email Token
      • Embedding A Video
      • Data Source Validation
      • Select Data Source Options
      • Nested Form Workflows
        • Nested Wizard Forms
      • Save as Draft
      • Role-Based Conditions
      • Custom Component
      • Dynamic Radio and Select Box Values
      • Override CKEDITOR
    • Errors
    • Examples
    • License Utilization Checks
  • Contact Us
Powered by GitBook
On this page
  • Overview
  • Prerequisites
  • Creating the Custom Component
  • Creating the Custom Template
  • Adding the Custom Component to your Application
  • JavaScript Application (webpack)
  • Angular Application
  • React Application
  • Getting the Rating Component into the Developer Portal

Was this helpful?

  1. FAQ
  2. Tutorials & Workflows

Custom Component

PreviousRole-Based ConditionsNextDynamic Radio and Select Box Values

Last updated 2 months ago

Was this helpful?

Overview

The custom component code in this tutorial can be found at

  1. All components in Form.io are . We have created a base class call in which all components extend from to create new component classes. Then from those newly created component classes we create more component classes and so on. In this tutorial you will learn how to

    • Create your own custom component class

    • Bundle your custom component via webpack

    • Add a custom component to your [JavaScript / Angular / React] application

    • Add a custom component to the enterprise portal application

  2. The custom component in this tutorial is a Rating component. The features that will be implemented are

    • Changing icons (using bootstrap icons)

    • Changing the size of the icons

    • Changing the color of the icons

    • Changing the number of icons

Prerequisites

  1. Install

  2. An IDE for developing code such as or

  3. A understanding of JavaScript, HTML, CSS, and Modules Bundlers

Creating the Custom Component

This section of the tutorial will teach you how to create a custom component. We will be going over some of the basics on custom component creation by creating a Rating Component. This section is to teach you...

  • How to extend from the base component class

  • What are the fundamental methods of the base component should you implement

  • Creating a edit form for your component

  1. Start by creating a new project folder in your IDE. We will be naming this project RatingComponent

  2. In your project directory run the commands npm init -y and npm install @formio/js

  3. Create a folder structure in your IDE that looks like the following

Custom_Components
  |- package.json
  |- package-lock.json
  |- /src
    |- /rating
      |- /editForm
        |- Rating.edit.display.js
      |- Rating.form.js
      |- Rating.js
    |- /templates
      |- form.js
  |- index.js
  1. Add the following code to Rating.js.

import {Formio} from "@formio/js";
import editForm from './Rating.form.js'

const Field = Formio.Components.components.field;

export default class Rating extends Field {
  static editForm = editForm

  static schema(...extend) {
    return Field.schema({
      type: 'rating',
      label: 'rating',
      key: 'rating',
      icon: 'bi bi-star',
      iconSize: '2rem',
      color: 'blue',
      numberOfIcons: 5,
    }, ...extend);
  }

  static get builderInfo() {
    return {
      title: 'Rating',
      icon: 'star',
      group: 'basic',
      documentation: '/userguide/#rating',
      weight: 0,
      schema: Rating.schema()
    };
  }

  constructor(component, options, data) {
    super(component, options, data);
  }

  render() {
    return super.render(this.renderTemplate('rating', {
      numberOfIcons: this.component.numberOfIcons,
      filledIcons: Number(this.dataValue?.split('/')[0])
    }))
  }

  attachIcon(icons, index) {
    const icon = icons.item(index);
    icon.addEventListener('click', () => {
      if(!this.component.disabled) {
        this.setValue(`${index + 1}/${this.component.numberOfIcons}`);
      }
    })
  }

  attachIcons() {
    const icons = this.refs.icon;
    for (let i = 0; i < icons.length; i++) {
      this.attachIcon(icons, i);
    }
  }

  attach(element) {
    this.loadRefs(element, {
      rating: 'single',
      icon: 'multiple'
    });
    this.attachIcons();
    return super.attach(element);
  }

  get defaultSchema() {
    return Rating.schema();
  }

  setValue(value){
    const changed = super.setValue(value);
    this.redraw();
    return changed;
  }
}
const Field = Formio.Components.components.field;

export default class Rating extends Field {
static schema(...extend) {
    return Component.schema({
      type: 'rating',
      label: 'rating',
      key: 'rating',
      icon: 'bi bi-star',
      iconSize: '2rem',
      color: 'blue',
      numberOfIcons: 5,
    }, ...extend);
  }
static get builderInfo() {
    return {
      title: 'Rating', // Title in the builder
      icon: 'star', // Icon in the builder
      group: 'basic', // Group in the builder
      documentation: 'yourcustomlink', // Link to documentation
      weight: 0, // Position in the builder
      schema: Rating.schema() // The schema used when dragged onto the builder
    };
  }
constructor(component, options, data) {
    super(component, options, data);
  }
render() {
    return super.render(this.renderTemplate('rating', {
      numberOfIcons: this.component.numberOfIcons,
      filledIcons: Number(this.dataValue?.split('/')[0])
    }))
  }
attachIcon(icons, index) {
  const icon = icons.item(index);
  icon.addEventListener('click', () => {
    if(!this.component.disabled) {
      this.setValue(`${index + 1}/${this.component.numberOfIcons}`);
    }
  })
}

attachIcons() {
  const icons = this.refs.icon;
  for (let i = 0; i < icons.length; i++) {
    this.attachIcon(icons, i);
  }
}

attach(element) {
  this.loadRefs(element, {
    rating: 'single',
    icon: 'multiple'
  });
  this.attachIcons();
  return super.attach(element);
}

The attach method is another important function extended from the base component. The attach method is were you will add event listeners and attach functionality to your component. This method is ran after your component has been rendered on the DOM.

this.setValue(`${index+1}/${this.component.numberOfIcons}`);

The setValue method is a function that takes a value and updates the component data modal. This function is useful for when you want to make updates to what data your component is holding. This data can be of any type (string, number, object, etc). For example, if this.setValue('3/5') was called then when making a submission to the form with this component the submission data would look something like...

{
    data: {
        customComponentKey: '3/5'
    }
}

Its important to note that if you want to retrieve the value that is set by setValue then you can call this.dataValue. The dataValue getter function retrieve the current value of you component. You may have seen this earlier when we called

filledIcons: Number(this.dataValue?.split('/')[0])
get defaultSchema() {
    return Rating.schema();
  }

The get defaultSchema function returns the schema of your component. It is used when merging all the json schemas upon component creation. There is not much more to say about this function other than your component will behave unexpectedly if this function is not included.

static editForm = editForm

Setting the static editForm variable allows you to define the edit form of your component. This is the edit form that is displayed when you drag and drop a component onto the form builder. For example the edit form of a textfield component looks like the following

Lets create this editForm in the Rating.form.js file

  1. Add the following code to Rating.form.js

import {Formio} from "@formio/js";

const baseEditForm = Formio.Components.baseEditForm
import RatingEditDisplay from "./editForm/Rating.edit.display.js";
export default function (...extend){
    return baseEditForm([
        {
            key: 'display',
            components: RatingEditDisplay
        },
        {
            key: 'layout',
            ignore: true
        }
    ], ... extend)
}

A editForm is just a function that returns some JSON. In order to create a custom editForm for your component we use a function called baseEditForm. The baseEditForm is a function that takes an array of json to extend the editForm of the base component class. It is in this array were you will define the component structure of each tab in your editForm. The key property is the tab title in your editForm and the components is a json representation of an editForm within that tab. You can create completely new tabs and override existing base tabs. It is best practice to create separate files for defining the components for your tabs with the following naming convention [ComponentName].edit.[TabName].js

Note the ignore: true . By setting ignore to true you can remove entire tabs of the baseEditForm. For example, the above code will result in the layout tab being removed from the edit form

  1. Add the following code to Rating.edit.display.js

export default [
    {
        type: 'number',
        key: 'numberOfIcons',
        label: 'Number of Icons',
        input: 'true',
        tooltip: "The number of icons displayed in the form"
    },
    {
        type: 'textfield',
        key: 'icon',
        label: 'Icon',
        input: 'true',
        tooltip: 'The bootstrap icon class that will go in the <i> tag'
    },
    {
        type: 'textfield',
        key: 'color',
        label: 'Color',
        input: 'true',
        tooltip: 'The color of the icons'
    },
    {
        type: 'textfield',
        key: 'iconSize',
        label: 'Icon Size',
        tooltip: 'The size of the icon'
    },
    {
        key: 'placeholder',
        ignore: true
    }
]

You may have noticed that the properties in each of these JSONs looks just like the JSON we define in the schema of our component or the json schema of the textfield shown earlier. This is because Form.io editForms are Form.io forms under the hood! When you are interacting with editForms in the form builder, you are actually using a Form.io form. This is possible because all Form.io forms can be created through a simple JSON schema! It is important to note that the key property in the JSON should match the property in the component schema. This allows for changes made to the properties of the editForm to be reflected in the properties of the component. For example the keys numberOfIcons, icon, color, and iconSize need to match the properties in static schema Note the ignore: true . By setting ignore to true you can remove edit fields of the tab you are defining. For example, the above code will result in placeholder field being removed from the display tab

Creating the Custom Template

Templates in Form.io are functions that take a context object and return a html string. They have a structure that looks like the following

const myTemplate = function(ctx) {
  return 'Your custom template html here';
};

These template functions are passed an object conventionally named ctx. This ctx is what we call a context object. It is passed data about the component that is being rendered. Earlier in this tutorial we passed numberOfIcons and filledIcons into an object as the second parameter to the renderTemplate function

render() {
    return super.render(this.renderTemplate('rating', {
      numberOfIcons: this.component.numberOfIcons,
      filledIcons: Number(this.dataValue?.split('/')[0])
    }))
  }

In this tutorial we will be creating a custom template that will be used by our custom component.

Get started by adding the following code to form.js

export default function (ctx) {
  return `
    <div ref="rating">
      ${(function (){
        let icons = '';
        for (let i = 0; i < ctx.numberOfIcons; i++) {
          icons += `<i style="color: ${ctx.component.color}; font-size: ${ctx.component.iconSize}" class="${ctx.component.icon}${i < ctx.filledIcons ? '-fill' : ''}" ref="icon"></i>`;
        }
        return icons;
      })()}
    </div>
  `
}

A couple things to note here

  • The ctx object is passed data to it that we can use to create our custom component html. For example we call ctx.component.color. This corresponds to the static schema we defined earlier in this tutorial. We can interpolate our component schema values into our html by calling ctx.component.[schemaProperty]

  • The ref attribute. This is the most important attribute of your custom components template. It allows you to attach references to specific html elements by giving the reference a name. For example the ref="rating" ref="icon" allows you to reference 'rating' and 'icon' html elements in your custom component code. I will walk through step by step how this works...

  1. The renderer renders your custom component onto the DOM. Lets say the render function outputted the following HTML

<div ref="rating">      
  <i style="color: blue; font-size: 2em" class="bi bi-star" ref="icon"></i>
  <i style="color: blue; font-size: 2em" class="bi bi-star" ref="icon"></i>
  <i style="color: blue; font-size: 2em" class="bi bi-star" ref="icon"></i>
  <i style="color: blue; font-size: 2em" class="bi bi-star" ref="icon"></i>
  <i style="color: blue; font-size: 2em" class="bi bi-star" ref="icon"></i>
</div>
  1. In the attach function of your custom component you would call this.loadRefs passing in the element given by attach and an object specifiying the refs you would like to load. In this case we need to load rating and icon. Notice that we give rating the 'single' value and icon the 'multiple' value. This is because there is only one ref attribute that has the value 'rating' and there multiple ref attributes that have the value 'icon'. The 'single' and 'multiple' values will dictate whether the ref will be saved as an HTMLElement or HTMLCollection.

this.loadRefs(element, {
    rating: 'single',
    icon: 'multiple'
});
  1. Now that the refs are loaded we can call this.refs to access the references to the HTMLElement(s). For example, in our attachIcons function we reference the icons by calling this.refs.icon. The idea behind this is now that you have a reference to your HTMLElement(s) you can attach event listeners and properties to those references. In this example we are able to attach a click event listener to our icons because we are able to reference the HTMLElement via this.refs.icon

attachIcon(icons, index) {
    const icon = icons.item(index);
    icon.addEventListener('click', () => { // Attach event listener to icon element
      this.setValue(`${index+1}/${this.component.numberOfIcons}`);
    })
  }

  attachIcons() {
    const icons = this.refs.icon;
    for (let i = 0; i < icons.length; i++) {
      this.attachIcon(icons, i);
    }
  }

Adding the Custom Component to your Application

To add the custom component to your application you can use the Formio.use function. The Formio.use function allows you to add plugins to your formio forms. In this case we will be adding our component and template as plugins. We will be going over how to add your custom component to a...

  • JavaScript Application (via webpack)

  • Angular Application

  • React Application

JavaScript Application (webpack)

To show how to bundle the custom component into a JavaScript app we first need to create a simple application. We will be using same nodejs project folder used to house the custom component files to house our application files as well.

  1. Start by installing the following dependencies

    • npm install webpack webpack-cli webpack-dev-server html-webpack-plugin

  2. Create a webpack.config.js file in the root directory of your project

  3. Create a index.html and index.js files under the src directory. Your project structure should look like

Custom_Components
  |- package.json
  |- package-lock.json
  |- webpack.config.js
  |- /src
    |- index.html
    |- index.js
    |- /rating
      |- /editForm
        |- Rating.edit.display.js
      |- Rating.form.js
      |- Rating.js
    |- /templates
      |- form.js
  1. In webpack.config.js add the following code

 const path = require('path')
 const HtmlWebpackPlugin = require("html-webpack-plugin");
 
 module.exports = {
    mode: "development",
    entry: {
       index: "./src/index.js"
    },
    plugins: [
       new HtmlWebpackPlugin({
          title: "MyApp",
          template: "./src/index.html"
       })
    ],
    devtool: "inline-source-map",
    output: {
       filename: "[name].bundle.js",
       path: path.resolve(__dirname, 'dist'),
       clean: true
    },
    devServer: {
       static: './dist'
    },
 }
  1. In your index.html file add the following html. Notice that we have included the cdn for bootstrap icons. This is necessary in order to load our icons for the custom component

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
    <link rel='stylesheet' href='https://cdn.form.io/js/5.0.0/formio.full.min.css'>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.3.0/font/bootstrap-icons.css">
</head>
<body>
<div id="builder"></div>
<div id="formio"></div>
</body>
</html>
  1. In your index.js file add the following JavaScript. Notice how we are using Formio.use here. Formio.use allows you to add your custom component and custom template to formio so that it can be used by functions such as Formio.createForm and Formio.builder.

import {Formio} from '@formio/js'
import rating from "./rating/Rating.js";
import ratingTemplate from './templates/form';

Formio.use(
  {
    components: {
      rating // Adds our rating class to the list of formio components
    },
    templates: {
      bootstrap: {
        rating: {
          form: ratingTemplate // Adds the rating template to the list of formio templates
        }
      }
    }
  }
);

// Formio.createForm(document.getElementById('formio'), {
//   components: [
//     {
//       "label": "rating",
//       "tableView": false,
//       "key": "rating",
//       "type": "rating",
//       "input": true
//     }
//   ]
// });

// Formio.builder(document.getElementById('builder'), {}, {
// })
  1. Try it out! Uncomment Formio.createForm or Formio.builder and run webpack serve to see the custom component in action.

Angular Application

Importing the custom component and custom template into an angular application is very similar to how you would in vanilla JavaScript. To get the custom component in your angular application all you need to do is move your custom component and custom template code into your app and call the Formio.use function at the top level of your angular application. For example, if you created a angular application using the ng new command then your application code may look something like...

import {bootstrapApplication} from '@angular/platform-browser';
import {appConfig} from './app/app.config';
import {AppComponent} from './app/app.component';
import {Formio} from "@formio/js";
import rating from './customcomponent/rating/Rating'
import ratingTemplate from './customcomponent/templates/form';

Formio.use({
  components: {
      rating
    },
  templates: {
    bootstrap: {
      rating: {
        form: ratingTemplate
      }
    }
  }
})

bootstrapApplication(AppComponent, appConfig)
  .catch((err) => console.error(err));

You will either need to allow angular to process Javascript files by setting allowJs: true in tsconfig.json or convert your custom component and custom template files to typescript

You can test to see if the custom component works by using the formio directive in a template

<formio [form]="{components: [{type: 'rating'}]}"></formio>

React Application

Importing the custom component and custom template into a react application is very similar to how you would in vanilla JavaScript. To get the custom component in your react application all you need to do is move your custom component and custom template code into your app and call the Formio.use function at the top level of your react application. For example, if you created a react application using the npm create vite command then your application code may look something like...

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
import rating from './customcomponent/rating/Rating';
import ratingTemplate from './customcomponent/templates/form';
import {Formio} from '@formio/js';

Formio.use({
    components: {
        rating
    },
    templates: {
        bootstrap: {
            rating: {
                form: ratingTemplate
            }
        }
    }
})

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

You will either need to allow angular to process Javascript files by setting allowJs: true in tsconfig.json or convert your custom component and custom template files to typescript

You can test to see if the custom component works by rendering

<Form form={{components: [{type: 'rating'}]}} />

Getting the Rating Component into the Developer Portal

module.exports = {
    ...
    externals: {
        "@formio/js": "Formio"
    }
}
  1. Now run the command webpack. You shoud now see a /dist directory with your index.bundle.js file in it.

  2. You now need to take the code inside index.bundle.js and host it. If you already have a way to host your code then you can skip the following steps

    • Open up GitHub and create a new repository called MyCustomComponent

    • Click uploading an existing file

    • Upload the index.bundle.js file

    • Click Commit changes

    • You should now have a repository called MyCustomComponent with index.bundle.js inside

      • https://cdn.jsdelivr.net/gh/user/MyCustomComponent/index.bundle.js

      • Replace user with your GitHub username

  1. Now that you have a CDN with your bundled code you can get the custom component onto the enterprise form builder

  2. Open up your developer portal and create a new project

  3. In the navigation bar click Settings

  4. Click on Custom JS & CSS

  5. Under Custom Javascript and Custom CSS add the links to your custom component code and bootstrap icons. If you followed the steps to using GitHub to host your custom component code then your Custom CSS and JavaScript should look like the following

  6. Save Settings (Click OK if you're asked if you would like to load the JavaScript)

  7. Create a new Web Form

  8. You should now see Rating component under the basic tab in the form builder

  1. You can now use the Rating component when creating Forms!

It is important to understand that the Developer Portal and your application are two separate applications. This means that if you have added the custom component onto the Developer Portal and are embedding the form into your application via an embed link then you must have the custom component on your application as well in order for the custom component to work. If you see "Unknown component: rating" when trying to create a form using the rating component then the rating component is not being properly bundled into your application. Check the Formio.use function and make sure that you have followed the steps outlined in this tutorial correctly.

Creating a for your component

Every component in Formio extends from the a . This allows you to inherit all the methods and instance variables from the component you are extending from.

Schema is a static method that defines the json properties of your component. It also defines the default values of your json properties as well as override some of the json properties you are extending from. The best way to understand what schema is doing is to , drag a component onto the builder, and then click the edit JSON option on the component. You will see the components JSON schema.

BuilderInfo is a static method that defines how the component will display on the form builder. For example, the above code would make the Rating Component show up in the builder like this

The constructor is useful for defining instance variables that will be used internally by your component.

The render method is one of the most important functions extended from the base component. It allows you to define how your component will render when using Formio.createForm. In this tutorial we will be using a to define the html of our custom component.

It is important to note the this.loadRefs method called at the top of the attach method. This load refs method will look for attributes specified in the method on the component html element and put them in the object refs on the instance of your component. For example, the above this.loadRefs will... - Look for a single ref attribute on the component element and save it in this.refs - Look for multiple ref attributes on the component element and save it in this.refs We will dive deeper into refs in the section of this tutorial

This adds numberOfIcons and filledIcons to the ctx object when rendering our template. For example, the above code would allow you to call ctx.numberOfIcons. Additionally the template is also passed some default context data. You can find the additional data in the and the

It is important to include in your application as the custom rating component uses bootstrap icons when rendering

To get custom components into the Developer Portal Application, you will be modifying the settings in your project. We will be adding our custom component JavaScript code as well as bootstrap icons to the Developer Portal by adding the links to the Custom JS and Custom CSS fields in the settings. Because the Custom JS field only accepts a single JavaScript file we will need to bundle our custom component code into a single .js file.

Please follow the webpack setup in as this setup will be used to bundle our code.

Before bundling the custom component into a single file we need to make one small change in webpack.config.js. Add the following code to webpack.config.js. This that excludes formiojs in the bundle of custom component code. Because the Developer Portal Application already includes formiojs in the application we need to exclude formiojs from our custom component code as it is not needed

is an easy way to create CDNs from GitHub repositories. If you followed the steps above your CDN should be

https://github.com/formio/contrib/tree/master/src/components/rating
JavaScript classes
Component
Node.js
Visual Studio Code
Webstorm
custom template
base component
Learn more about class inheritance here
You can learn more about class constructors here
custom template
evalContext function
data variable in the renderTemplate function
bootstrap icons
externals is a webpack configuration
jsDeliver
Creating the Custom Template
Adding the Custom Component to your Application
create a form builder
Custom JS & CSS