Reputation: 4132
I want to use CKEditor with my Ember app. I am 100% a n00b with Ember, but I'm getting there.
I have tried my darndest to figure this out, but I've gotten nowhere :(
I have tried to use ember-ckeditor
. This ended up with the editor throwing a bunch of net::ERR_NAME_NOT_RESOLVED
errors for things such as config.js and other "assets" it expected to find in the assets folder.
I have tried ember-cli-ckeditor
. Same exact issues as above.
These two addons have pretty lame documentation. For example, I have no idea how provide a custom config file, CSS, etc. Or what if I want to use CkFinder?
The two above addons also throw some depreciated warnings when loading up the server, but I disgress....
I finally tried to manually include ckeditor v4.5.6 in the vendor
folder.
I then included in ember-cli-build.js
as such: app.import('vendor/ckeditor/ckeditor.js');
I'm not sure if I'm correct in doing this, and if so, how do I include use the editor plugin within my controller or component?
CKEDITOR.replace("content");
as per usual outside of Ember?
Please school me!
Upvotes: 1
Views: 892
Reputation: 5991
To use ckeditor without addons (creating your own component):
Install ckeditor using bower:
bower install ckeditor --save
Install broccoli-funnel, you will need it for ckeditor's assets:
npm install broccoli-funnel --save-dev
In your ember-cli-build.js:
At the top of file requere funnel
var Funnel = require('broccoli-funnel');
In app's options exclude ckeditor's assets from fingerprinting:
var app = new EmberApp(defaults, {
fingerprint: {
exclude: ['assets/ckeditor/']
}
});
Import ckeditor's js and assets:
app.import('bower_components/ckeditor/ckeditor.js');
var ckeditorAssets = new Funnel('bower_components/ckeditor', {
srcDir: '/',
destDir: '/assets/ckeditor'
});
/**
* If you need to use custom skin, put it into
* vendor/ckeditor/skins/<skin_name>
* Also, custom plugins may be added in this way
* (look ckeditor's info for details)
* If you don't need custom skins, you may remove
* ckeditorCustoms
*/
var ckeditorCustoms = new Funnel('vendor/ckeditor', {
srcDir: '/',
destDir: '/assets/ckeditor'
});
return app.toTree([ckeditorAssets, ckeditorCustoms]);
If your app is not in website's root, you may need to put this script in body section of index.html, before other scripts:
<script type="text/javascript">
window.CKEDITOR_BASEPATH = '/path-to/assets/ckeditor/';
</script>
Create a component. Warning: this is a code from my abandoned pet project, and I'm 99% sure that it will not work for you "as is" because of missing dependencies and because it was created for different html layout. But I think it may help anyway. If you wish to try and copy-paste it, here are dependencies:
npm install --save-dev ember-browserify
npm install --save-dev sanitize-html
Component's code:
/* globals CKEDITOR */
import Ember from 'ember';
import layout from '../templates/components/md-ckeditor'; //component's name!
import SanitizeHTML from 'npm:sanitize-html';
export default Ember.Component.extend({
layout: layout,
classNames: ['input-field'],
_editor: null,
bindAttributes: ['disabled', 'readonly', 'autofocus'],
validate: false,
errorsPath: 'errors',
init() {
this._super(...arguments);
const propertyPath = this.get('valueBinding._label');
if (Ember.isPresent(propertyPath)) {
Ember.Binding.from(`targetObject.${this.get('errorsPath')}.${propertyPath}`)
.to('errors')
.connect(this);
}
},
didInsertElement() {
var i18n = this.get('i18n');
if (Ember.isPresent(this.get('icon'))) {
this.$('> span').css('padding-left', '3rem');
}
this._setupLabel();
this._editor = CKEDITOR.inline(this.element.querySelector('.ckeditor'), {
skin: 'minimalist',
toolbar: [
['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord'],
['Undo', 'Redo'],
['Bold', 'Italic', 'Strike'],
['Link', 'Unlink'],
['NumberedList', 'BulletedList', 'Blockquote'],
['Source']
],
linkShowAdvancedTab: false,
linkShowTargetTab: false,
language: i18n.get('locale'),
removePlugins: 'elementspath'
});
this._editor.on('instanceReady', (e) => {
this._updateValidClass();
});
this._editor.on('change', (e) => {
this.set('value', e.editor.getData());
});
this._editor.on('focus', (e) => {
var label = this.$('> label, > i');
label.addClass('active');
});
this._editor.on('blur', (e) => {
var label = this.$('> label, > i');
var text = SanitizeHTML(e.editor.getData(), {
allowedTags: []
}).trim();
if (text !== '') {
label.addClass('active');
} else {
label.removeClass('active');
}
});
},
willDestroyElement()
{
this._editor.destroy();
this._editor = null;
},
id: Ember.computed('elementId', function () {
return `${this.get('elementId')}-input`;
}),
validClass: Ember.computed('value', 'errors', function () {
var errors = this.get('errors');
if (errors && errors.get && errors.get('firstObject')) {
return 'invalid';
} else if (!!this.get('value')) {
return 'valid';
} else {
return '';
}
}),
validClassChanged: Ember.observer('validClass', function () {
Ember.run.once(this, '_updateValidClass');
}),
_updateValidClass() {
if (this._editor && this._editor.container && this._editor.container.$) {
Ember.$(this._editor.container.$).removeClass('invalid valid').addClass(this.get('validClass'));
}
},
_setupLabel() {
const label = this.$('> label, > i');
if (Ember.isPresent(this.get('value'))) {
label.addClass('active');
}
}
});
Template:
{{textarea
id=id
value=value
name=name
required=required
readonly=readonly
disabled=disabled
maxlength=maxlength
class="materialize-textarea ckeditor"
classNameBindings="validate:validate: validClass"
}}
<label for="{{id}}">{{label}}</label>
<small class="red-text">
{{#if errors}} {{errors.firstObject}} {{else}} {{/if}}
</small>
Upvotes: 4
Reputation: 7169
Check next example
https://github.com/ebryn/ember-ckeditor/blob/master/addon/components/ember-ckeditor.js
Or next package ember-cli-ckeditor
https://www.npmjs.com/package/ember-cli-ckeditor
Upvotes: 0