Learn how to create a custom field type in angular using formly forms and TinyMCE
Requirements
Setup / Installation
- Add formly and TinyMCE to your project
# Formly
ng add @ngx-formly/schematics --ui-theme=bootstrap
# TinyMCE
npm install @tinymce/tinymce-angular
npm install --save tinymce # Optional
- Lazy loading TinyMCE dependencies
{
"version": 1,
"projects": {
"app-name": {
"architect": {
"build": {
"assets": [
...
{
"glob": "**/*",
"input": "./node_modules/tinymce",
"output": "/tinymce/"
}
]
...
}
}
}
}
}
In the configuration above we tell angular to look inside ./node_modules/tinymce
directory whenever we request assets from the path /tinymce/
. This enables us to inject dependencies whenever needed rather than including them globally.
Now we can inject tinymce/tinymce.min.js
in the component where we register our formly components.
import { EditorModule, TINYMCE_SCRIPT_SRC } from "@tinymce/tinymce-angular";
/* ... */
@NgModule({
/* ... */
imports: [
EditorModule,
// Formly
ReactiveFormsModule,
FormsModule,
FormlyModule.forRoot({
types: [],
}),
],
providers: [
{ provide: TINYMCE_SCRIPT_SRC, useValue: "tinymce/tinymce.min.js" },
],
})
export class CustomFormlyModule {}
- Create the formly components
import { Component, OnInit } from "@angular/core";
import { FieldType } from "@ngx-formly/material";
import { FormControl } from "@angular/forms";
import { TINYMCE_DEFAULT_CONFIG } from "../../../config";
@Component({
selector: "formly-editor-type",
templateUrl: "./editor-type.component.html",
})
export class EditorTypeComponent extends FieldType implements OnInit {
readonly formControl: FormControl;
tinyMceConfig = {
base_url: "/tinymce",
suffix: ".min",
contextmenu: false,
branding: false,
menubar: false,
height: 400,
plugins: [
"advlist autolink lists link image charmap print preview anchor",
"searchreplace visualblocks code fullscreen",
"insertdatetime media table paste",
],
toolbar: "undo redo | formatselect | link | bold italic | bullist numlist",
};
ngOnInit() {
super.ngOnInit();
}
}
<h3>{{to.label}}</h3>
<editor
[init]="tinyMceConfig"
[formControl]="formControl"
[formlyAttributes]="field"
></editor>
- Declare the custom component in our module
import { EditorModule, TINYMCE_SCRIPT_SRC } from '@tinymce/tinymce-angular';
import { EditorTypeComponent } from './components/editor/editor-type.component';
/* ... */
@NgModule({
/* ... */
imports: [
EditorModule,
// Formly
ReactiveFormsModule,
FormsModule,
FormlyModule.forRoot({
types: [
{
name: 'editor',
component: EditorTypeComponent,
},
],
})
],
providers: [
{ provide: TINYMCE_SCRIPT_SRC, useValue: 'tinymce/tinymce.min.js' }
],
declarations: [EditorTypeComponent]
})
export class CustomFormlyModule {}
Usage
import { Component } from "@angular/core";
import { FormGroup } from "@angular/forms";
import { FormlyFieldConfig } from "@ngx-formly/core";
@Component({
template: `
<form [formGroup]="form" (ngSubmit)="onSubmit(model)">
<formly-form
[form]="form"
[fields]="fields"
[model]="model"
></formly-form>
<button type="submit" class="btn btn-default">Submit</button>
</form>
`,
})
export class AppComponent {
form = new FormGroup({});
model = {};
fields: FormlyFieldConfig[] = [
{
key: "content",
type: "editor",
templateOptions: {
label: "Article Content",
},
},
];
onSubmit() {
console.log(this.model);
}
}
You can now use a TinyMCE editor in your formly forms and store some HTML data for your needs.