このクールなテキストエディター、facebookのdraft.jsにつまずきました。 githubの例をフォローしようとしましたが、空のエディターではなくコンテンツを使用してエディターを作成したいと思います。
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()})
}
});
実行しますが、「Uncaught TypeError:contentState.getBlockMapは関数ではありません」というエラーが表示されます
EditorState.createWithContent の最初の引数は、文字列ではなくContentState
です。インポートする必要があります ContentState
var EditorState = Draft.EditorState;
var ContentState = Draft.ContentState;
ContentState.createFromText を使用し、結果を EditorState.createWithContent に渡します。
return {
editorState: EditorState.createWithContent(ContentState.createFromText('Hello'))
};
コンテンツ(HTML/Markdown)のインポートとエクスポートを支援するために、DraftJS用の一連のパッケージを作成しました。プロジェクトでこれらを使用します react-rte 。おそらく探しているのは: draft-js-import-html on npmです。
npm install draft-js-import-html
使用例:
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)
};
}
});
私が公開したモジュールは次のとおりです。
APIの変更がいくつかあります。明確にするために、これらの例では最新のAPIv0.10.0を使用しています。
さまざまな方法がありますが、基本的に、コンテンツリソースにプレーンテキスト、スタイル付きテキスト、またはHTMLマークアップを使用するかどうかに応じて、3つのオプションがあります。
プレーンテキストは明らかですが、スタイル付きテキストの場合は、シリアル化されたjavasriptオブジェクトまたはhtmlマークアップを使用する必要があります。
プレーンテキストの例から始めましょう。
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}
/>
)
}
}
スタイル付きコンテンツをインポートするために、Draft.jsは convertFromRaw および convertFromHTML ユーティリティ関数を提供します。
convertFromRaw関数は、生のjavascriptオブジェクトをパラメーターとして受け取ります。ここでは、JSON文字列化されたjavascriptオブジェクトをコンテンツソースとして使用しています。
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にはconvertToRaw関数が用意されているため、エディターの状態を長期保存用の生のJavaScriptオブジェクトに変換できます。
そして最後に、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}
/>
)
}
}
convertFromHTML
を使用して、createWithContent
でhtmlをインポートできます。
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)
}
Draftの convertFromHtmlの例 に示されているように。 0.9.1
バージョンは画像をインポートできませんが、0.10.0
できる。
0.10.0
createFromBlockArray
の変更:
const content = ContentState.createFromBlockArray(
blocksFromHTML.contentBlocks,
blocksFromHTML.entityMap
)
プレーンテキストでエディターを開始する必要がある場合
_EditorState.createWithContent
_ および _ContentState.createFromText
_ メソッドを使用します。作業例- https://jsfiddle.net/levsha/3m5780jc/
_constructor(props) {
super(props);
const initialContent = 'Some text';
const editorState = EditorState.createWithContent(ContentState.createFromText(initialContent));
this.state = {
editorState
};
}
_
htmlマークアップ文字列のコンテンツでエディターを開始する必要がある場合
convertFromHTML
および _ContentState.createFromBlockArray
_ を使用します。作業例- 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),
};
}
_
文字列の配列があり、デフォルトのdraft.jsブロックタイプのいくつかを使用してエディターを開始する場合
コンストラクタnew ContentBlock(...)
で ContentBlocks
sの配列を作成し、_ContentState.createFromBlockArray
_メソッドに渡すことができます。 _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))
};
}
_
ContentState
raw JS構造のコンテンツを使用してエディターを開始する必要がある場合
以前にコンテンツ状態を convertToRaw
で生のJS構造に保存した場合(詳細は この回答 を読んでください) convertFromRaw
メソッドでエディターを開始できます。作業例- https://jsfiddle.net/levsha/tutc419a/
_constructor(props) {
super(props);
this.state = {
editorState: EditorState.createWithContent(convertFromRaw(JSON.parse(editorStateAsJSON)))
};
}
_
HTML形式で設定する場合は、次のコードを追加するだけで、edtitorStateに初期値を設定できます。
this.state = {
editorState: EditorState.createWithContent(
ContentState.createFromBlockArray(
convertFromHTML('<p>My initial content.</p>')
)
),
}
これは、豊富な機能を備えた物事を行うためのクリーンな方法であることがわかりました。将来さらにプラグインを追加し、コンテンツを.md
など、コンポーネントの構造を大幅に変更することなく。
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>
);
}
}