web-dev-qa-db-fra.com

draftjs comment lancer un éditeur avec du contenu

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"

31
vdj4y

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'))
};
40
Brigand

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:

26
sstur

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}
      />
    )
  }
}
8
snnsnn

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.0createFromBlockArray devient:

const content = ContentState.createFromBlockArray(
  blocksFromHTML.contentBlocks,
  blocksFromHTML.entityMap
)
7
svnm

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)))
  };
}
1
Mikhail Shabrikov

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>')
    )
  ),
}
1
Rami Salim

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>
    );
  }
}
0
kaushik94