J'ai essayé d'utiliser composantWillMount et composantDidMount pour initialiser CKEditor dans le contexte de React, mais cela ne semble pas fonctionner, peu importe la combinaison que j'essaie. Quelqu'un at-il trouvé une solution à cela en plus du changement d'éditeur?
J'ai publié un paquet sur Npm pour utiliser CKEditor avec React. Il ne faut qu'une ligne de code à intégrer à votre projet.
Lien Github - https://github.com/codeslayer1/react-ckeditor .
Comment utiliser?
npm install react-ckeditor-component --save
.<CKEditor activeClass="editor" content={this.state.content} onChange={this.updateContent} />
Le paquet utilise la version par défaut de CKEditor, mais vous pouvez également utiliser une version personnalisée avec l’un des plugins de votre choix. Il comprend également un exemple d'application. J'espère que vous le trouverez utile.
Sage décrit une solution géniale dans sa réponse. Cela m'a sauvé la vie, car je viens tout juste de commencer à utiliser React et j'en avais besoin pour que cela fonctionne. Cependant, j'ai changé la mise en œuvre, en intégrant également les suggestions de Jared (en utilisant componentDidMount
). En outre, mon besoin était d'avoir un rappel de changement, comme suit:
Utilisation du composant:
<CKEditor value={this.props.value} onChange={this.onChange}/>
Ajouté ceci à index.html
:
<script src="//cdn.ckeditor.com/4.6.1/basic/ckeditor.js"></script>
En utilisant le code de composant suivant:
import React, {Component} from "react";
export default class CKEditor extends Component {
constructor(props) {
super(props);
this.componentDidMount = this.componentDidMount.bind(this);
}
render() {
return (
<textarea name="editor" cols="100" rows="6" defaultValue={this.props.value}></textarea>
)
}
componentDidMount() {
let configuration = {
toolbar: "Basic"
};
CKEDITOR.replace("editor", configuration);
CKEDITOR.instances.editor.on('change', function () {
let data = CKEDITOR.instances.editor.getData();
this.props.onChange(data);
}.bind(this));
}
}
Encore une fois, tous les crédits à Sage!
Voici une version améliorée de la version de base ci-dessus, qui prend en charge plusieurs instances de CKEditor sur la même page:
import React, {Component} from "react";
export default class CKEditor extends Component {
constructor(props) {
super(props);
this.elementName = "editor_" + this.props.id;
this.componentDidMount = this.componentDidMount.bind(this);
}
render() {
return (
<textarea name={this.elementName} defaultValue={this.props.value}></textarea>
)
}
componentDidMount() {
let configuration = {
toolbar: "Basic"
};
CKEDITOR.replace(this.elementName, configuration);
CKEDITOR.instances[this.elementName].on("change", function () {
let data = CKEDITOR.instances[this.elementName].getData();
this.props.onChange(data);
}.bind(this));
}
}
Veuillez noter que cela nécessite également un identifiant unique:
<CKEditor id={...} value={this.props.value} onChange={this.onChange}/>
Ceci est pour un composant React qui affiche un P paragraphe de texte. Si l'utilisateur souhaite modifier le texte du paragraphe, il peut cliquer dessus pour attacher une instance de CKEditor. Lorsque l'utilisateur a terminé de modifier le texte dans l'instance de l'éditeur, l'événement "flou" se déclenche, ce qui transfère les données de CKEditor à une propriété state et détruit l'instance de CKEditor.
import React, {PropTypes, Component} from 'react';
export default class ConditionalWYSIWYG extends Component {
constructor(props) {
super(props);
this.state = {
field_name:this.props.field_name,
field_value:this.props.field_value,
showWYSIWYG:false
};
this.beginEdit = this.beginEdit.bind(this);
this.initEditor = this.initEditor.bind(this);
}
render() {
if ( this.state.showWYSIWYG ) {
var field = this.state.field_name;
this.initEditor(field);
return (
<textarea name='editor' cols="100" rows="6" defaultValue={unescape(this.state.field_value)}></textarea>
)
} else {
return (
<p className='description_field' onClick={this.beginEdit}>{unescape(this.state.field_value)}</p>
)
}
}
beginEdit() {
this.setState({showWYSIWYG:true})
}
initEditor(field) {
var self = this;
function toggle() {
CKEDITOR.replace("editor", { toolbar: "Basic", width: 870, height: 150 });
CKEDITOR.instances.editor.on('blur', function() {
let data = CKEDITOR.instances.editor.getData();
self.setState({
field_value:escape(data),
showWYSIWYG:false
});
self.value = data;
CKEDITOR.instances.editor.destroy();
});
}
window.setTimeout(toggle, 100);
}
}
Le self.value = data
me permet de récupérer le texte du composant parent via une simple référence
window.setTimeout();
donne le temps de réaction pour faire ce qu’il fait. Sans ce délai, j'obtiendrais une erreur Cannot read property 'getEditor' of undefined
dans la console.
J'espère que cela t'aides
Il suffit de référencer le ckeditor.js
dans index.html
et de l’utiliser avec window.CKEDITOR
. N'utilisez pas CKEDITOR
directement comme le document dans le composant React.
Il suffit de lire la première ligne de ckeditor.js, vous trouverez ce qu'il en est de définir CKEDITOR.
Merci à Sage, Sander & co. Je voulais juste contribuer à une version pour le mode "intégré" de CKEditor.
Tout d'abord, désactivez le comportement "auto-inline" de CKEditor avec ...
CKEDITOR.disableAutoInline = true
Ensuite, pour le composant réel ...
import React, {Component} from 'react';
export default class CKEditor extends Component {
constructor(props) {
super(props);
this.elementName = "editor_" + this.props.id;
this.componentDidMount = this.componentDidMount.bind(this);
this.onInput = this.onInput.bind(this);
}
onInput(data) {
console.log('onInput: ' + data);
}
render() {
return (
<div
contentEditable={true}
suppressContentEditableWarning
className="rte"
id={this.elementName}>
{this.props.value}</div>
)
}
componentDidMount() {
let configuration = {
toolbar: "Basic"
};
CKEDITOR.inline(this.elementName, configuration);
CKEDITOR.instances[this.elementName].on("change", function() {
let data = CKEDITOR.instances[this.elementName].getData();
this.onInput(data);
}.bind(this));
}
}
L'utilisation serait quelque chose comme ceci:
<CKEditor id="102" value="something" onInput={this.onInput} />