Wanna see something cool? Check out Angular Spotify 🎧

Angular Jira Clone Part 07 - Build a rich text editor

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

  1. https://stackblitz.com/edit/angular-markdown-editor-jira
  2. text-editor.component.html

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() {}
}

rich-text-editor.module.ts

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

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

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

npm install [email protected]

Basic Usage

1. Import QuillModule into your AppModule

@NgModule({
  imports: [
    ...,

    QuillModule.forRoot()
  ],
  ...
})
class AppModule { ... }

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 {}

3. Import quill themes CSS into styles.scss

@import '~quill/dist/quill.core.css';
@import '~quill/dist/quill.snow.css';

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>

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'],
  ],
}

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

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

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>

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()
  }
}
<quill-editor
  [formControl]="control"
  [placeholder]="''"
  [modules]="quillConfiguration"
  [styles]="{'min-height': '120px'}"
  class="content-editor"
>
</quill-editor>

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!

Published 23 Oct 2020

Read more

 — How to iterate over objects in TypeScript
 — How to copy an object from the Chrome inspector console as code
 — Use async functions instead of callbacks for asynchronous code
 — The different between type and interface in TypeScript
 — Angular Jira Clone Part 06 - Build a markdown text editor

Follow @trungvose on Twitter for more!