Reputation: 891
I am trying to integrate CKEditor into my angular project. I have followed other similar solutions but only the textarea appears. Here is what I have done so far.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>A Simple Page with CKEditor</title>
<!-- Make sure the path to CKEditor is correct. -->
<script src="../Email/ckeditor/ckeditor.js"></script>
</head>
<body>
<form>
<textarea name="editor1" id="editor1" rows="10" cols="80">
This is my textarea to be replaced with CKEditor.
</textarea>
<script>
// Replace the <textarea id="editor1"> with a CKEditor
// instance, using default configuration.
CKEDITOR.replace( 'editor1' );
</script>
</form>
</body>
</html>
import {Component} from '@angular/core';
@Component({
selector: 'test',
templateUrl:'test.html'
})
export class TestComponent {
}
Upvotes: 5
Views: 26915
Reputation: 3348
If you want to integrate the CKEditor 5 editor with the Angular 2+ framework, there's a ready-to-use official integration, which provides simple and conscious API:
<ckeditor
[editor]="Editor"
[data]="editorData"
[config]="config"
[disabled]="isDisabled"
(ready)="onReady($event)"
(change)="onChange($event)"
(focus)="onFocus($event)"
(blur)="onBlur($event)">
</ckeditor>
import '@ckeditor/ckeditor5-build-classic/build/translations/de';
import * as ClassicEditorBuild from '@ckeditor/ckeditor5-build-classic';
@Component( {
selector: 'editor',
templateUrl: './editor.component.html',
styleUrls: [ './editor.component.css' ]
} )
export class SimpleUsageComponent {
public Editor = ClassicEditorBuild;
public editorData = '<p>Ckeditor5 & Angular</p>';
public config = {
language: 'de'
};
public isDisabled = false;
onReady( editor ): void {}
onChange( event ): void {}
onFocus( event ): void {}
onBlur( event ): void {}
}
import { CKEditorModule } from '@ckeditor/ckeditor5-angular';
@NgModule({
declarations: [
// ...
],
imports: [
CKEditorModule,
// ...
],
// ...
})
export class AppModule { }
Upvotes: 2
Reputation: 3019
I am not allowed to use cdn in my project and I also need to add plugins to my project. To be able to do that using npm. This is my solution to this problem
Install ng2-ckeditor with ckeditor using npm.
npm install --save ckeditor
and
npm install --save ng2-ckeditor
Update the angular-cli.json to be able to add plugins to the instance of CKEditor. In the assets section of angular-cli.json add:
"assets": [
"assets",
"favicon.ico",
{
"glob": "**/*",
"input": "../node_modules/ckeditor/",
"output": "assets/js/ckeditor/",
"allowOutsideOutDir": true
}
]
add also ckeditor.js from the downloaded npm to the script-tag in angular-cli.json:
"scripts": [
"../node_modules/ckeditor/ckeditor.js"
]
Download the plugins that you need to use to the folder /assets/js/ckeditor/plugins/ of your project. Be sure that the plugin.js file exists in each subfolder of your plugins folder.
Create your own config file assets/js/ckeditor/ckeditor-config.js for ckeditor with the following content:
(function(){
CKEDITOR.basePath = '/assets/js/ckeditor/'
CKEDITOR.plugins.addExternal('wordcount', 'plugins/wordcount/');
CKEDITOR.plugins.addExternal('notification', 'plugins/notification/');
CKEDITOR.editorConfig = function( config ) {
config.extraPlugins = 'wordcount,notification';
}
})();
Create an internal service to be able to configure your ckeditor with your own input. Here I'm using the service to adjust the height and set the maximum limit of my characters from my ckeditor component. I'm also telling the plugin to display only character counter.
import { Injectable } from '@angular/core';
@Injectable()
export class CkeditorConfigService {
constructor() { }
public getConfig(height: number, maxCharCount: number){
return {
customConfig: '/assets/js/ckeditor/ckeditor-config.js',
height: height,
wordcount: {
showParagraphs: false,
showWordCount: false,
showCharCount: true,
maxCharCount: maxCharCount
}
};
}
}
As ckeditor is a form section, you need to add FormsModule to your app.module.ts, as well as the ng2-ckeditor module.
imports: [
...
FormsModule,
CKEditorModule,
...
]
From your component add the internal service.
@Component({
selector: 'test-ckeditor-app',
templateUrl: './editor.component.html',
providers: [
CkeditorConfigService
]
})
export class EditorComponent implements OnInit {
ckeditorContent: string = '<p>Some html</p>';
private myCkeditorConfig: any;
constructor(private ckService: CkeditorConfigService) {}
ngOnInit() {
this.myCkeditorConfig = this.ckService.getConfig(150, 400);
}
}
And finally in your html file add the following:
<ckeditor
[(ngModel)]="ckeditorContent"
[config]="myCkeditorConfig">
</ckeditor>
Please find my project sample on github:
https://github.com/dirbacke/ckeditor4
Note! When you compile and run, you will get the MIME-type console warning. That is because the css files specified in the warning have comments.
Upvotes: 2
Reputation: 3609
You can use component that wraps the CKEditor library:
https://github.com/chymz/ng2-ckeditor
This makes it very easy and provides two-way binding:
<ckeditor [(ngModel)]="content" [config]="config"></ckeditor>
Edit:
Another option is to use this module which I've refactored from ng2-ckeditor
and simplified. This way you don't have to install and manage another dependency.
1. Create file ckeditor.module.ts
2. Paste Content
import { Component, Input, OnInit, OnDestroy, ViewChild, ElementRef, forwardRef, NgZone, NgModule } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';
declare const CKEDITOR;
@Component({
selector: 'app-ckeditor',
template: `
<textarea #editor>
{{value}}
</textarea>
`,
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CkEditorComponent),
multi: true
}]
})
export class CkEditorComponent implements OnInit, OnDestroy, ControlValueAccessor {
@ViewChild('editor') editor: ElementRef;
wait = false;
instance: any;
config = {
uiColor: '#F0F3F4',
height: '100%'
};
private _value = '';
get value(): any { return this._value; }
@Input() set value(v) {
if (v !== this._value) {
this._value = v;
this.onChange(v);
}
}
constructor(private zone: NgZone) { }
ngOnInit() {
this.instance = CKEDITOR.replace(this.editor.nativeElement, this.config);
this.instance.setData(this._value);
// CKEditor change event
this.instance.on('change', () => {
let value = this.instance.getData();
this.updateValue(value);
});
}
/**
* Value update process
*/
updateValue(value: any) {
this.zone.run(() => {
this.value = value;
this.onChange(value);
this.onTouched();
});
}
/**
* Implements ControlValueAccessor
*/
writeValue(value: any) {
console.log('writeValue');
this._value = value;
if (this.instance) {
this.instance.setData(value);
}
}
onChange(_: any) { }
onTouched() { }
registerOnChange(fn: any) { this.onChange = fn; }
registerOnTouched(fn: any) { this.onTouched = fn; }
ngOnDestroy() {
if (this.instance) {
setTimeout(() => {
this.instance.removeAllListeners();
CKEDITOR.instances[this.instance.name].destroy();
this.instance.destroy();
this.instance = null;
});
}
}
}
@NgModule({
imports: [],
declarations: [CkEditorComponent],
providers: [],
exports: [CkEditorComponent]
})
export class CkEditorModule { }
3. Use like this
import { CkEditorModule } from '../../';
<app-ckeditor formControlName="postContent"></app-ckeditor>
4. I dynamically load the script when I need it using this function
public addCkEditor(permissions) {
if (this.usesCKEditor(permissions) && !window['CKEDITOR']) {
const url = '//cdn.ckeditor.com/4.7.3/full/ckeditor.js';
const script = document.createElement('script');
script.onload = () => {
this.ckeditorLoaded.next(true);
};
script.type = 'text/javascript';
script.src = url;
document.body.appendChild(script);
}
}
Upvotes: 7
Reputation: 4900
As of Angular 4 angular-cli is the standard tool to build and manage Angular projects.
These are the steps to start and test CKEditor in an Angular 4 application.
Assuming angular-cli
is installed.
$ ng new ckeditorSample --skip-test
$ cd ckeditorSample
ng2-ckeditor is the CKEditor intergration package to Angular 2 and beyond.
$ npm install --save ng2-ckeditor
$ npm update
Modify src/app/app.component.ts
to include the SampleEditor
component.
import { Component } from '@angular/core';
@Component({
selector: 'sampleEditor',
template: `
<ckeditor
[(ngModel)]="ckeditorContent"
[config]="{uiColor: '#a4a4a4'}"
(change)="onChange($event)"
(ready)="onReady($event)"
(focus)="onFocus($event)"
(blur)="onBlur($event)"
debounce="500">
</ckeditor>
`,
})
export class SampleEditor {
private ckeditorContent: string;
constructor() {
this.ckeditorContent = `<p>Greetings from CKEditor...</p>`;
}
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
}
Modify src/app/app.component.html
to invoke SampleEditor
component.
<div>
<sampleEditor></sampleEditor>
</div>
Modify src/app/app.module.ts
to include the CKEditorModule
and SampleEditor
component.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { CKEditorModule } from 'ng2-ckeditor';
import { AppComponent, SampleEditor } from './app.component';
@NgModule({
declarations: [
AppComponent,
SampleEditor
],
imports: [
BrowserModule,
FormsModule,
CKEditorModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Modify src/index.html
to include the latest script.
As of the time writing this: https://cdn.ckeditor.com/4.7.0/standard-all/ckeditor.js
Check for the latest here: http://cdn.ckeditor.com/
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>CkeditorSample</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<script src="https://cdn.ckeditor.com/4.7.0/standard-all/ckeditor.js"></script>
</head>
<body>
<app-root></app-root>
</body>
</html>
npm start &
firefox http://localhost:4200
Open the browser on http://localhost:4200 CKEditor should be there.
Upvotes: 22