Build a rich text editor in Angular with ngx-quill
Trung Vo
Posted on November 4, 2020
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.
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
.
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 ngx-quill@1.6.0
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.
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.
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 :)
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.
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]
andformControl
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!
Posted on November 4, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.