Je suis tombé sur cet éditeur de texte cool, draft.js by facebook. J'essaie de suivre l'exemple dans github mais je veux créer un éditeur avec du contenu à la place un éditeur vide.
var EditorState = Draft.EditorState;
var RichEditor = React.createClass({
getInitialState(){
return {editorState: EditorState.createWithContent("Hello")}
//the example use this code to createEmpty editor
// return ({editorState: EditorState.createEmpty()})
}
});
exécutez-le, mais j'obtiens une erreur en disant que "Uncaught TypeError: contentState.getBlockMap n'est pas une fonction"
Le premier argument de EditorState.createWithContent est un ContentState
, pas une chaîne. Vous devez importer ContentState
var EditorState = Draft.EditorState;
var ContentState = Draft.ContentState;
Utilisez ContentState.createFromText Et transmettez le résultat à EditorState.createWithContent .
return {
editorState: EditorState.createWithContent(ContentState.createFromText('Hello'))
};
J'ai créé un ensemble de packages pour DraftJS pour vous aider à importer et exporter du contenu (HTML/Markdown). Je les utilise dans mon projet react-rte . Celui que vous recherchez probablement est: draft-js-import-html on npm.
npm install draft-js-import-html
Un exemple de la façon dont vous pourriez l'utiliser:
var stateFromHTML = require('draft-js-import-html').stateFromHTML;
var EditorState = Draft.EditorState;
var RichEditor = React.createClass({
getInitialState() {
let contentState = stateFromHTML('<p>Hello</p>');
return {
editorState: EditorState.createWithContent(contentState)
};
}
});
Les modules que j'ai publiés sont:
Il y a eu quelques changements d'API, pour plus de clarté, ces exemples utilisent la dernière API qui est v0.10.0 .
Il existe de nombreuses façons, mais vous avez essentiellement trois options selon que vous souhaitez utiliser du texte brut, du texte stylisé ou du balisage html pour la ressource de contenu.
Quel texte brut est évident, mais pour le texte stylisé, vous devez utiliser un objet javasript sérialisé ou un balisage html.
Commençons par un exemple en texte brut:
import {Editor, EditorState} from 'draft-js';
class MyEditor extends Component{
constructor(props) {
super(props);
const plainText = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.';
const content = ContentState.createFromText(plainText);
this.state = { editorState: EditorState.createWithContent(content)};
this.onChange = (editorState) => {
this.setState({editorState});
}
}
render(){
return(
<Editor
editorState={this.state.editorState}
onChange={this.onChange}
/>
)
}
}
Pour importer du contenu de style, Draft.js fournit des fonctions utilitaires convertFromRaw et convertFromHTML .
la fonction convertFromRaw prend un objet javascript brut comme paramètre. Ici, nous utilisons un objet javascript stratifié JSON comme source de contenu:
class MyEditor extends Component{
constructor(props) {
super(props);
const rawJsText = `{
"entityMap": {},
"blocks": [
{
"key": "e4brl",
"text": "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.",
"type": "unstyled",
"depth": 0,
"inlineStyleRanges": [
{
"offset": 0,
"length": 11,
"style": "BOLD"
},
{
"offset": 28,
"length": 29,
"style": "BOLD"
},
{
"offset": 12,
"length": 15,
"style": "ITALIC"
},
{
"offset": 28,
"length": 28,
"style": "ITALIC"
}
],
"entityRanges": [],
"data": {}
},
{
"key": "3bflg",
"text": "Aenean commodo ligula eget dolor.",
"type": "unstyled",
"depth": 0,
"inlineStyleRanges": [],
"entityRanges": [],
"data": {}
}
]
}`;
const content = convertFromRaw(JSON.parse(rawJsText));
this.state = { editorState: EditorState.createWithContent(content)};
this.onChange = (editorState) => {
this.setState({editorState});
}
}
render(){
return(
<Editor
editorState={this.state.editorState}
onChange={this.onChange}
/>
)
}
}
Draft.js fournit la fonction convertToRaw afin que vous puissiez convertir l'état de votre éditeur en objet javascript brut pour un stockage à long terme.
Et enfin, voici comment vous le faites avec le balisage html:
class MyEditor extends Component{
constructor(props) {
super(props);
const html = `<p>Lorem ipsum <b>dolor</b> sit amet, <i>consectetuer adipiscing elit.</i></p>
<p>Aenean commodo ligula eget dolor. <b><i>Aenean massa.</i></b></p>`;
const blocksFromHTML = convertFromHTML(html);
const content = ContentState.createFromBlockArray(
blocksFromHTML.contentBlocks,
blocksFromHTML.entityMap
);
this.state = { editorState: EditorState.createWithContent(content)};
this.onChange = (editorState) => {
this.setState({editorState});
}
}
render(){
return(
<Editor
editorState={this.state.editorState}
onChange={this.onChange}
/>
)
}
}
Vous pouvez utiliser convertFromHTML
pour importer du html avec createWithContent
import { convertFromHTML, ContentState } from 'draft-js'
const html = '<div><p>hello</p></div>'
const blocksFromHTML = convertFromHTML(html)
const content = ContentState.createFromBlockArray(blocksFromHTML)
this.state = {
editorState: EditorState.createWithContent(content)
}
Comme le montre le brouillon exemple convertFromHtml . Notez que le 0.9.1
la version ne peut pas importer d'images, alors que 0.10.0
pouvez.
Dans 0.10.0
createFromBlockArray
devient:
const content = ContentState.createFromBlockArray(
blocksFromHTML.contentBlocks,
blocksFromHTML.entityMap
)
Lorsque vous devez lancer un éditeur avec du texte brut.
Utilisez les méthodes EditorState.createWithContent
et ContentState.createFromText
. Exemple de travail - https://jsfiddle.net/levsha/3m5780jc/
constructor(props) {
super(props);
const initialContent = 'Some text';
const editorState = EditorState.createWithContent(ContentState.createFromText(initialContent));
this.state = {
editorState
};
}
Lorsque vous devez lancer un éditeur avec le contenu de la chaîne de balisage html.
Utilisez convertFromHTML
et ContentState.createFromBlockArray
. Exemple de travail - https://jsfiddle.net/levsha/8aj4hjwh/
constructor(props) {
super(props);
const sampleMarkup = `
<div>
<h2>Title</h2>
<i>some text</i>
</div>
`;
const blocksFromHTML = convertFromHTML(sampleMarkup);
const state = ContentState.createFromBlockArray(
blocksFromHTML.contentBlocks,
blocksFromHTML.entityMap
);
this.state = {
editorState: EditorState.createWithContent(state),
};
}
Lorsque vous avez un tableau de chaînes et que vous souhaitez lancer un éditeur avec certains des types de bloc draft.js par défaut.
Vous pouvez créer un tableau de ContentBlocks
s avec le constructeur new ContentBlock(...)
, et le passer à la méthode ContentState.createFromBlockArray
. Exemple de travail avec unordered-list-item
- https://jsfiddle.net/levsha/uy04se6r/
constructor(props) {
super(props);
const input = ['foo', 'bar', 'baz'];
const contentBlocksArray = input.map(Word => {
return new ContentBlock({
key: genKey(),
type: 'unordered-list-item',
characterList: new List(Repeat(CharacterMetadata.create(), Word.length)),
text: Word
});
});
this.state = {
editorState: EditorState.createWithContent(ContentState.createFromBlockArray(contentBlocksArray))
};
}
Lorsque vous devez lancer un éditeur avec du contenu à partir de la structure JS ContentState
raw
Si vous avez précédemment enregistré votre état de contenu dans une structure JS brute avec convertToRaw
(lisez cette réponse pour plus de détails). Vous pouvez lancer un éditeur avec la méthode convertFromRaw
. Exemple de travail - https://jsfiddle.net/levsha/tutc419a/
constructor(props) {
super(props);
this.state = {
editorState: EditorState.createWithContent(convertFromRaw(JSON.parse(editorStateAsJSON)))
};
}
Vous pouvez définir la valeur initiale de votre edtitorState simplement en ajoutant le code suivant si vous souhaitez le définir au format HTML
this.state = {
editorState: EditorState.createWithContent(
ContentState.createFromBlockArray(
convertFromHTML('<p>My initial content.</p>')
)
),
}
J'ai trouvé que c'était une façon propre de faire les choses avec des fonctionnalités riches. Vous pouvez ajouter d'autres plugins à l'avenir, exporter votre contenu en tant que .md
etc sans beaucoup changer la structure de votre composant.
import Draft from 'draft-js';
import DraftPasteProcessor from 'draft-js/lib/DraftPasteProcessor';
const { EditorState, ContentState } = Draft;
import Editor from 'draft-js-plugins-editor';
import createRichButtonsPlugin from 'draft-js-richbuttons-plugin';
const richButtonsPlugin = createRichButtonsPlugin();
class DescriptionForm extends React.Component {
state = {
editorState: this._getPlaceholder(),
}
_getPlaceholder() {
const placeholder = 'Write something here';
const contentHTML = DraftPasteProcessor.processHTML(placeholder);
const state = ContentState.createFromBlockArray(contentHTML);
return Draft.EditorState.createWithContent(state);
}
_onChange(editorState) {
this.setState({
editorState,
});
}
render () {
let { editorState } = this.state;
return (
<div>
<Editor
editorState={editorState}
onChange={this._onChange.bind(this)}
spellCheck={false}
plugins={[richButtonsPlugin, videoPlugin]}
/>
</div>
);
}
}