Sometimes in your Angular UI, you want to give users more than just a text area.

You want to give them a full-blown WYSIWYG editor.

But how do you do that? In this guide, I'll answer that question.

And when you're done implementing the solution I present here, you'll have a WYSIWYG editor that looks something like this:

 

As you can see, that UI is designed for email entry. It's part of my efforts to integrate Gmail with the CRM app I'm working on.

Feel free to check out the source for that CRM app on GitHub if you need to see everything instead of just the snippets I share here.

And here's some good news: you won't need to develop that editor from scratch. Instead, you'll just rely on Quill.

Quill seems to be one of the more popular WYSIWYG options for client-side code that uses some variant of TypeScript. I've installed it locally and found that it works well.

So I think it's a good fit.

Let's get started.

Free Installation

You gotta get the ball rolling by installing some modules.

So go to your command prompt and navigate to the root of the source you're working on. Alternatively, use the Developer Command Prompt from within Microsoft Visual Studio (assuming you're using Microsoft Visual Studio).

Begin by installing Quill. Enter this at your command prompt:

npm install quill@1.3.6

You will note that I'm specifying the version there. That's what you'll want to do as well.

In this case, getting the latest doesn't necessarily equate to getting the greatest. If you grab the latest version, you might end up with some fairly cryptic error messages. You can read more about that here.

Of course, by the time you're reading this, that information might be obsolete. So feel free to experiment.

But what you've just installed is Quill. It's a client-side WYSIWYG editor that runs via JavaScript.

By itself, that ain't gonna get you much while you're working with Angular. 

That's why you need to install ngx-quill.

npm install ngx-quill

But you're still not done. Next, install @types/quill:

npm install @types/quill@1.3.10

Once again: pay attention to that version. Don't opt for the latest.

That package, incidentally, contains type definitions used by Quill.

Now that you're done installing the dependencies, it's time to do some configuring.

Configuratin'

Next, open styles.css. Add the following lines at the top:

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

That quill.core.css file lives up to its name. It includes the basic styling for the WYSIWYG editor.

The other two CSS files reflect the only themes currently supported by Quill: Snow and Bubble.

Pro-tip: Snow is probably what you're looking for. Bubble uses tooltips that enable users to add formatting to text. Snow uses the traditional toolbar at the top of the editor.

The Quill editor you see in the image towards the top of this article uses Snow.

Good news: you don't need to configure anything to use Snow because it's the default.

Modularity

Next, be sure to add the Quill module to whatever module you need it in. 

For the purposes of the CRM app I'm working on, I need it in user.module.ts.

...
imports: [
    ...
    QuillModule.forRoot(),
    ....
   ],
....

According to the documentation, you'll need to do that in the root module as well if you're lazy-loading your modules.

Think Inside the Box

Now it's time to create the inbox component. For the purposes of this app, you'll do that by entering the following at your command prompt:

ng g c features/user/email/compose-email

Feel free to change that to suit whatever requirements you need to fulfill.

Anyhoo, that command will generate (g) a new component (c). That new component will include four files in the /src/app/features/user/email/compose-email directory.

Begin by editing ComposeEmailComponent. Make it look like this:

@Component({
  selector: 'app-compose-email',
  templateUrl: './compose-email.component.html',
  styleUrls: ['./compose-email.component.css']
})
export class ComposeEmailComponent implements OnInit {

  form: FormGroup;
  formSubmitted: boolean = false;

  email: Email;

  editorStyle = {
    height: '300px',
    backgroundColor: '#ffffff'
  }

  constructor(private fb: FormBuilder, private emailService: EmailService) { }

  ngOnInit(): void {
    this.createFormGroup();
  }

  private createFormGroup() {
    this.form = this.fb.group({
      'html': ['', Validators.compose([Validators.required])]
    });
  }

  onSubmit() {
    console.log(this.form);
  }
}

Not a whole lot going on there but I'll go over it line by line anyway.

Let's start with the two properties at the top: form and formSubmitted.

The form property represents the HTML form that will include the WYSIWYG editor. So you're getting a bonus here: I'm not only showing you how to add a WYSIWYG editor to your Angular UI, I'm also showing you how to include it in a form that users can submit.

The formSubmitted property is a boolean that indicates whether or not the user submitted the form. The code uses that to hide the Send button on the UI so users don't double-submit.

The email property will (eventually) hold all the important info about the email that the user will send. 

The editorStyle property might be something you haven't seen before even if you've been working with Angular for a while. That's the standard way to style the Quill WYSIWYG editor in the Angular framework.

The constructor takes in two injectables: FormBuilder and EmailService.

FormBuilder is what the code will use to build the reactive form. That's SOP for Angular applications.

And the class will use EmailService to eventually send the email. That's not happening right now, though.

The  ngOnInit() method invokes only one other method: createFormGroup().  That lives up to its name by creating the FormGroup object associated with the HTML form.

That FormGroup object, as of now, only has one field. It's called "html."

The "html" field uses a single validator that requires users to enter something (anything) in the field. In other words, the app won't allow people to send emails with no text in the body.

As you probably guessed, that "html" field maps to the contents of the WYSIWYG editor.

The onSubmit() method gets called when the user clicks the Send button on the UI. All it does now is log the contents of the form so developers (i.e., you) can check to make sure the WYSIWYG editor is working.

A Tempest in a Template

Next, edit compose-email.component.html. Make it look like this:

<div fxLayout="column">
  <div>
    <h4>New Email Message</h4>
  </div>
  <div>
    <form [formGroup]="form" (ngSubmit)="onSubmit()">
      <div>
        <quill-editor [styles]="editorStyle" formControlName="html" placeholder="Enter email message"></quill-editor>
      </div>
      <div style="margin-top:20px">
        <button *ngIf="!formSubmitted" [disabled]="!form.valid" type="submit" mat-raised-button color="primary">Send</button>
        <mat-spinner *ngIf="formSubmitted" [diameter]="50"></mat-spinner>
      </div>
    </form>
  </div>
</div>

That's not too complicated either.

The fun stuff that brought you here happens in the <quill-editor> element. 

But first, note that the editor is part of a <form>. That formGroup binding property maps the HTML form to the form object in the TypeScript class. You saw that object in the previous section.

Next, take a look at <quill-editor>.  That styles binding property is set to the editorStyle property you also saw in the TypeScript class. That means the editor will display according to the styling specified in that property.

The formControlName attribute maps to the "html" field in the FormGroup object. So when the user submits the form, examine that field for the HTML contents of the WYSIWYG editor.

And that's all you need to do to include the default Quill editor in your UI. Not too bad, is it?

The next <div> section displays the Send button and submits the form if the user clicks it. It also displays a spinner during submission instead of the button. Again, that's to prevent double-submissions.

Now save everything and fire up your Angular app and any supporting microservices.

If you're doing everything the way I am with the CRM, you can see the WYSIWYG editor by pointing your browser to: http://localhost:4200/user/email/compose-email

Wrapping It Up

You've already seen the finished product in the opening section here, so there's no need to go through the testing part. 

I definitely recommend you take the next step by familiarizing yourself with Quill. Click on the external links I've shared here and read the documentation.

Also, add some markup in the WYSIWYG editor and click the Send button. Then, check the Developer Console to examine the contents of the "html" property in the FormGroup object. Make sure it's what you expect it to be.

Have fun!

Photo by Andrea Piacquadio from Pexels