DEV Community

Trung Vo
Trung Vo

Posted on

Build a rich text editor in Angular with ngx-quill

If you notice, the current jira.trungk18.com is using a rich text HTML editor. This tutorial will help you to create one using ngx-quill.

That's how a rich text editor looks.

Angular Jira Clone Part 07 - Build a rich text editor

See all tutorials for Jira clone

Source code and demo

Rich Editor Module

Like a markdown text editor, I will reuse a rich text editor in many places on a web application. So that I will create a brand new module, RichTextEditorModule, for that purpose. At the moment, it will have only one component, RichTextEditorComponent.

Angular Jira Clone Part 07 - Build a rich text editor

There is not much code inside its module and component.

rich-text-editor.component.ts

@Component({
  selector: 'rich-text-editor',
  templateUrl: './rich-text-editor.component.html',
  styleUrls: ['./rich-text-editor.component.css'],
})
export class RichTextEditorComponent implements OnInit {
  constructor() {}
  ngOnInit() {}
}
Enter fullscreen mode Exit fullscreen mode

rich-text-editor.module.ts

@NgModule({
  imports: [CommonModule],
  exports: [RichTextEditorComponent],
  declarations: [RichTextEditorComponent],
})
export class MarkdownEditorModule {}
Enter fullscreen mode Exit fullscreen mode

No worry, we will add more code to the component. 😆

ngx-quill

To build a rich text editor from scratch could take me the same time to make the whole Jira clone application. That's why I am utilizing ngx-quill.

ngx-quill is an angular module for the Quill Rich Text Editor containing all components you need.

Installation

npm install ngx-quill
Enter fullscreen mode Exit fullscreen mode

For projects using Angular < v5.0.0, please run.

npm install ngx-quill@1.6.0
Enter fullscreen mode Exit fullscreen mode

Basic Usage

1. Import QuillModule into your AppModule

@NgModule({
  imports: [
    ...,

    QuillModule.forRoot()
  ],
  ...
})
class AppModule { ... }
Enter fullscreen mode Exit fullscreen mode

2. Import QuillModule into RichTextEditorModule

import { CommonModule } from '@angular/common'
import { NgModule } from '@angular/core'
import { RichTextEditorComponent } from './rich-text-editor.component'
import { QuillModule } from 'ngx-quill'

@NgModule({
  imports: [CommonModule, QuillModule],
  declarations: [RichTextEditorComponent],
  exports: [RichTextEditorComponent],
})
export class RichTextEditorModule {}
Enter fullscreen mode Exit fullscreen mode

3. Import quill themes CSS into styles.scss

@import '~quill/dist/quill.core.css';
@import '~quill/dist/quill.snow.css';
Enter fullscreen mode Exit fullscreen mode

Build our customize rich text editor component

I can now use in the RichTextEditorComponent. I will go ahead and place that HTML in my component template. I set a class name content-editor so that I can style it later.

<quill-editor class="content-editor" [placeholder]="''"> </quill-editor>
Enter fullscreen mode Exit fullscreen mode

See the result. Because quill is a compelling library, the rendered component has a textbox and most of the default toolbar button available for us.

Angular Jira Clone Part 07 - Build a rich text editor

My job now is pretty simple to customize the component with only the button that I need and some CSS styling.

Toolbar configuration

Below is the current configuration that I use for one toolbar row with some basic commands.

export const QuillConfiguration = {
  toolbar: [
    ['bold', 'italic', 'underline', 'strike'],
    ['blockquote', 'code-block'],
    [{ list: 'ordered' }, { list: 'bullet' }],
    [{ header: [1, 2, 3, 4, 5, 6, false] }],
    [{ color: [] }, { background: [] }],
    ['link'],
    ['clean'],
  ],
}
Enter fullscreen mode Exit fullscreen mode

And then I passed it down to modules input of the quill-editor

<quill-editor
  class="content-editor"
  [placeholder]="''"
  [modules]="quillConfiguration"
>
</quill-editor>
Enter fullscreen mode Exit fullscreen mode

That's the result with lesser command.

Angular Jira Clone Part 07 - Build a rich text editor

Noted that by default, ngx-quill will render a short textarea, and it will automatically expand to fill the height as you type. You might want to set a default min-height. I did set default 120px.

<quill-editor
  class="content-editor"
  [placeholder]="''"
  [modules]="quillConfiguration"
  [styles]="{'min-height': '120px'}"
>
</quill-editor>
Enter fullscreen mode Exit fullscreen mode

I guess it looks right now. The leftover part is to connect it with a form :)

Angular Jira Clone Part 07 - Build a rich text editor

Connect RichTextEditorComponent to a form

ngx-quill provided support for both ReactiveForms and TemplateForm. I shifted only to use ReactiveForms. That's why I will follow a similar approach as the Markdown component to take a FormControl as an Input.

export class RichTextEditorComponent implements OnInit {
  quillConfiguration = QuillConfiguration
  @Input() control: FormControl

  ngOnInit() {
    this.control = this.control ?? new FormControl()
  }
}
Enter fullscreen mode Exit fullscreen mode
<quill-editor
  [formControl]="control"
  [placeholder]="''"
  [modules]="quillConfiguration"
  [styles]="{'min-height': '120px'}"
  class="content-editor"
>
</quill-editor>
Enter fullscreen mode Exit fullscreen mode

See the result when I pair it inside a form. Work perfectly.

Angular Jira Clone Part 07 - Build a rich text editor

Homework

There is some small improvement that I leave it to you.

  • Set a border when focusing into the rich text editor
  • Implement ControlValueAccessor for the RichTextEditorComponent so that you can use both [ngModel] and formControl in a form :)

That's all for a rich text editor with Angular. Any questions, you can leave it in the comment box below or reach me on Twitter. Thanks for stopping by!

Top comments (2)

Collapse
 
bhaskar5959 profile image
Bhaskar5959

is quill-editor supports spellcheck property?

Collapse
 
amitkrishna profile image
Amit Krishna

Is it possible to have Image Upload feature by adding another button is it possible