Search results

Form Validation

The RichTextEditor supports both the reactive and template-driven form-building technologies.

Template driven forms

The template-drive forms use the angular directives in view to handle the forms controls. To enable the template-driven, import the FormsModule into corresponding app component.

For more details about template-driven forms, refer to:https://angular.io/guide/forms#template-driven-forms.

Mention the name attribute to RichTextEditor element that can be used to identify the form element. To register a RichTextEditor element to ngForm, give the ngModel to it. So, the FormsModule will automatically detect the RichTextEditor as a form element. After that, the RichTextEditor value will be selected based on the ngModel value.

The following example demonstrates how to achieve a two-way data binding.

Source
Preview
app.component.ts
app.module.ts
main.ts
index.html
import { Component, ViewChild } from '@angular/core';
import { ToolbarService, LinkService, ImageService, HtmlEditorService, RichTextEditorComponent  } from '@syncfusion/ej2-angular-richtexteditor';
  @Component({
      selector: 'app-root',
      template: `<form>
              <div class="form-group" #rteForm="ngForm">
                  <ejs-richtexteditor #templateRTE id="name" #name='ngModel' [(value)]='value' required name="name" [(ngModel)]="value" (created)="rteCreated()"></ejs-richtexteditor>
                  <div *ngIf="(name.invalid && (name.dirty || name.touched))" class="alert alert-danger">
                      <div *ngIf="name.errors.required">
                          Value is required.
                      </div>
                  </div>
              </div>
              <div>
                  <button type="submit" ejs-button [disabled]="!rteForm.valid">Submit</button>
                  <button type="reset" ejs-button style="margin-left: 20px">Reset</button>
              </div>
          </form>`,
      providers: [ToolbarService, LinkService, ImageService, HtmlEditorService]
  })
  export class AppComponent  {
    public value: any = null;
  @ViewChild('templateRTE') rteEle: RichTextEditorComponent;

  rteCreated(): void {
      this.rteEle.element.focus();
  }
  }
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RichTextEditorAllModule } from '@syncfusion/ej2-angular-richtexteditor';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { DropDownListComponent } from '@syncfusion/ej2-angular-dropdowns';
import { AppComponent } from './app.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        ButtonModule,
        RichTextEditorAllModule,
        FormsModule,
        ReactiveFormsModule
    ],
    declarations: [AppComponent, DropDownListComponent],
    bootstrap: [AppComponent]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Syncfusion Angular RichTextEditor</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="//cdn.syncfusion.com/ej2/ej2-richtexteditor/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
    <script src="https://unpkg.com/core-js/client/shim.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.4.1/core.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/zone.js/0.6.25/zone.min.js"></script>
    <script src="https://unpkg.com/reflect-metadata@0.1.3"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
    <style>
    #loader {
        color: #008cff;
        font-family:  'Helvetica Neue','calibiri';
        font-size: 16px;
        height: 40px;
        left: 45%;
        position: absolute;
        top: 45%;
        width: 30%;
    }
</style>
</head>

<body>
    <app-root>
        <div id='loader'>Loading....</div>
    </app-root>
</body>

</html>

Reactive forms

The reactive forms use the reactive model-driven technique to handle form data between the component and view. So, it is called as model-driven forms. It listens the form data changes between App component and view also returns the valid states and values of form elements.

For more details about Reactive Forms, refer to: https://angular.io/guide/reactive-forms.

For the reactive forms, import a ReactiveFormsModule into app module as well as the FormGroup,FormControl should be imported to app component. The FormGroup is used to declare formGroupName for the form group and the FormControl is used to declare formControlName for form controls. You can declare the formControlName to RichTextEditor a value object must be created to the FormGroup and each value will be the default value of the form control.

The following example demonstrates how to use the reactive forms.

Source
Preview
app.component.ts
app.module.ts
main.ts
index.html
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { ToolbarService, LinkService, ImageService, HtmlEditorService, RichTextEditorComponent } from '@syncfusion/ej2-angular-richtexteditor';
import { FormBuilder, FormControl, FormGroup, Validators, FormGroupName } from '@angular/forms';
    @Component({
        selector: 'app-root',
        template:`<form [formGroup]="heroForm" #formDir="ngForm">
                <div class="form-group">
                    <ejs-richtexteditor id="name" #fromRTE formControlName="name" name="name" (created)="rteCreated()">
                    </ejs-richtexteditor>
                    <div *ngIf="heroForm.controls.name.invalid && (heroForm.controls.name.dirty || heroForm.controls.name.touched)" class="alert alert-danger">
                        <div *ngIf="heroForm.controls.name.errors.required">
                            Value is required.
                        </div>
                    </div>
                </div>
                <div>
                    <button type="submit" ejs-button [disabled]="!heroForm.valid">Submit</button>
                    <button type="button" ejs-button (click)="formDir.resetForm({})" style="margin-left: 20px">Reset</button>
                </div>
            </form>`,
        providers: [ToolbarService, LinkService, ImageService, HtmlEditorService]
    })
    export class AppComponent  {
      public value: string;
    @ViewChild('fromRTE') rteEle: RichTextEditorComponent;
    hero: any = { name: '', alterEgo: '', power: '' };
    heroForm: FormGroup;
    ngOnInit(): void {
        this.heroForm = new FormGroup({
            'name': new FormControl(null, [
                Validators.required,
            ]),
            'alterEgo': new FormControl(this.hero.alterEgo, [
                Validators.required]),
            'power': new FormControl(this.hero.power, Validators.required)
        });
    }
    rteCreated(): void {
        this.rteEle.element.focus();
    }
    }
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RichTextEditorAllModule } from '@syncfusion/ej2-angular-richtexteditor';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { DropDownListComponent } from '@syncfusion/ej2-angular-dropdowns';
import { AppComponent } from './app.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,
        ButtonModule,
        RichTextEditorAllModule,
        FormsModule,
        ReactiveFormsModule
    ],
    declarations: [AppComponent, DropDownListComponent],
    bootstrap: [AppComponent]
})
export class AppModule { }
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Syncfusion Angular RichTextEditor</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="//cdn.syncfusion.com/ej2/ej2-richtexteditor/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
    <script src="https://unpkg.com/core-js/client/shim.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.4.1/core.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/zone.js/0.6.25/zone.min.js"></script>
    <script src="https://unpkg.com/reflect-metadata@0.1.3"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
    <style>
    #loader {
        color: #008cff;
        font-family:  'Helvetica Neue','calibiri';
        font-size: 16px;
        height: 40px;
        left: 45%;
        position: absolute;
        top: 45%;
        width: 30%;
    }
</style>
</head>

<body>
    <app-root>
        <div id='loader'>Loading....</div>
    </app-root>
</body>

</html>