This is micro Angular v6+ contenteditable directive for compatibility with Angular forms. It just implements ControlValueAccessor for this purpose.
It implements MatFormFieldControl to support Angular Material
I found some useful CSS that can be used with this lib
/* mat-editor should be applied to the container of contenteditable (<mat-form-field>)*/
.mat-editor .mat-form-field-wrapper,
.mat-editor .mat-form-field-infix {
padding-top: 0;
padding-bottom: 0;
}
.mat-editor .mat-form-field-flex {
align-items: center;
}
/* https://github.com/angular/material2/issues/13322 */
.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-icon-button,
.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-icon-button {
display: inline-block !important;
}
There are 2 directives that can be used with CKEditor5.
matCkeditor
simply implements MatFormFieldControl
<ckeditor matCkeditor [editor]="ckEditor" [(ngModel)]="content"></ckeditor>
matCkeditorBalloon
should be used with @ckeditor/ckeditor5-build-balloon
and has an extra input to toggle toolbar of ckeditor.
<mat-form-field appearance="outline" class="mat-editor">
<ckeditor matCkeditorBalloon [toolbar]="toolbarStatus"
[editor]="ckEditor" (ready)="editorReady($event)" [config]="editorConfig"
[(ngModel)]="content">
</ckeditor>
<button matSuffix mat-icon-button type="button"
color="{{toolbarStatus && 'primary'}}" (click)="toolbarStatus = !toolbarStatus">
<mat-icon> tune </mat-icon>
</button>
</mat-form-field>
To remove the border of CKEditor
.mat-editor .ck-content {
border: none !important;
box-shadow: none !important;
}
To adjust form-field height
<!-- make mat-form-field fill parent height -->
<div fxLayout="column">
<mat-form-field appearance="outline" fxFlex formFieldSizer></mat-form-field>
</div>
You can just copy and paste this directive or install it from npm:
npm install mat-contenteditable --save
Import and add MatContenteditableModule
to your project:
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatContenteditableModule } from 'mat-contenteditable';
// ...
@NgModule({
// ...
imports: [
// Import this module to get available work angular with `contenteditable`
MatContenteditableModule,
// Import one or both of this modules
FormsModule,
ReactiveFormsModule
]
// ...
})
And then you can to use it in template-driven forms or reactive forms like this:
// In your component
import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
export class MyComponent implements OnInit {
templateDrivenForm = 'This is contenteditable text for template-driven form';
myControl = new FormControl;
ngOnInit() {
this.myControl.setValue(`This is contenteditable text for reactive form`);
}
}
<form #testForm="ngForm">
<p
contenteditable="true"
name="myFormName"
[(ngModel)]="templateDrivenForm"
></p>
</form>
<pre>
{{ testForm.value | json }}
</pre>
<hr>
<p contenteditable="true" [formControl]="myControl"></p>
<pre>
{{ myControl.value | json }}
</pre>
With contenteditable
directive you can pass optional @Input
value for propValueAccessor
:
<p
contenteditable="true"
propValueAccessor="textContent"
[formControl]="myControl"
></p>
In ContenteditableDirective
this value use like this:
this.elementRef.nativeElement[this.propValueAccessor]
By default it using innerHTML
.