how to displayed local content react-draft-wysiwyg - reactjs

how do i display edited content with all styles?
const content = {
entityMap: {},
blocks: [
{
key: "637gr",
text: "Initialized from content state.",
type: "unstyled",
depth: 0,
inlineStyleRanges: [],
entityRanges: [],
data: {},
},
],
}
export default class EditorConvertToJSON extends Component {
constructor(props) {
super(props)
const contentState = convertFromRaw(content)
this.state = {
contentState,
}
}
onContentStateChange = (contentState) => {
this.setState({
contentState,
})
}
render() {
const { contentState } = this.state
console.log("==============")
console.log("contentState", contentState)
return (
<div>
<Editor
wrapperClassName="demo-wrapper"
editorClassName="demo-editor"
onContentStateChange={this.onContentStateChange}
// editorState={this.state.contentState}
/>
<Editor editorState={contentState} readOnly />
</div>
)
}
}
I get an error TypeError: editorState.getImmutable is not a function
where am I wrong?
may need to display this data in divs and other html tags?
I'm completely confused

I hope this helps you:
Do
npm i draftjs-to-html
const content = {
entityMap: {},
blocks: [
{
key: "637gr",
text: "Initialized from content state.",
type: "unstyled",
depth: 0,
inlineStyleRanges: [],
entityRanges: [],
data: {},
},
],
}
export default class EditorExample extends Component {
constructor(props) {
super(props)
this.state = {
contentState : null
}
}
onContentStateChange = contentState => {
console.log('as HTML:', draftToHtml(contentState));
this.setState({ contentState});
}
render() {
const { contentState } = this.state
return (
<Editor
initialContentState={content}
editorContent={contentState}
onContentStateChange={this.onContentStateChange}
wrapperClassName="demo-wrapper"
editorClassName="demo-editor"
/>
)
}
}

Here is the full example from official documentation of react-draft-wyswiyg you can find example if you scroll down to the bottom of documentation web page :). Here you need to use convertToRaw method of draft-js. With the help of draftjs-to-html, code will be similar to draftToHtml(convertToRaw(editorState.getCurrentContent()))
import React, { Component } from 'react';
import { EditorState, convertToRaw, ContentState } from 'draft-js';
import { Editor } from 'react-draft-wysiwyg';
import draftToHtml from 'draftjs-to-html';
import htmlToDraft from 'html-to-draftjs';
class EditorConvertToHTML extends Component {
constructor(props) {
super(props);
const html = '<p>Hey this <strong>editor</strong> rocks 😀</p>';
const contentBlock = htmlToDraft(html);
if (contentBlock) {
const contentState = ContentState.createFromBlockArray(contentBlock.contentBlocks);
const editorState = EditorState.createWithContent(contentState);
this.state = {
editorState,
};
}
}
onEditorStateChange: Function = (editorState) => {
this.setState({
editorState,
});
};
render() {
const { editorState } = this.state;
return (
<div>
<Editor
editorState={editorState}
wrapperClassName="demo-wrapper"
editorClassName="demo-editor"
onEditorStateChange={this.onEditorStateChange}
/>
<textarea
disabled
value={draftToHtml(convertToRaw(editorState.getCurrentContent()))}
/>
</div>
);
}
}

Related

Changing state between two child class components in React

I have two class components: Title and PlayButton. By default, the Title is programmed to change images when it is being hovered over but I would like it so that when the Playbutton is hovered over, the Title also changes its image (changes the state of the image). How would I go about this? I know I should use a parent component that handles the state of both its "children" (the Title and the PlayButton), but since I'm new to react, I'm not sure how.
Any assistance would be appreciated, thank you!
Code for Title:
import React from 'react'
import './Title.css'
import playHoverProvider from './playHoverProvider'
class Title extends React.Component {
constructor(props) {
super(props);
this.state = {
imgSrc: require('./oglogo'),
control: require('./oglogo')
};
this.handleMouseOver = this.handleMouseOver.bind(this);
this.handleMouseOut = this.handleMouseOut.bind(this);
}
handleMouseOver() {
this.setState({
imgSrc: require('./difflogo')
});
}
handleMouseOut() {
this.setState({
imgSrc: require('./oglogo')
});
}
render() {
return (
<div className='logo'>
<view>
<img onMouseOver={this.handleMouseOver} onMouseOut={this.handleMouseOut} src={this.state.imgSrc}
style={{width: 800,
flex: 1,
height: null,
}}
alt = 'Logo' />
</view>
</div>
);
}
}
Title.propTypes = {
}
Title.defaultProps = {
}
export default Title;
Code for PlayButton:
import { hover } from '#testing-library/user-event/dist/hover';
import React from 'react'
import './PlayButton.css';
class PlayButton extends React.Component {
constructor(props) {
super(props);
this.state = {
imgSrc: require('./playbutton.png'),
disabled: false
};
this.handleMouseOver = this.handleMouseOver.bind(this);
this.handleMouseOut = this.handleMouseOut.bind(this);
}
// On-click
handleClick = (event) => {
if (this.state.disabled) {
return;
}
this.setState({
disabled: true
});
}
handleMouseOver () {
this.setState({
imgSrc: require('./playbuttonblue.png')
});
}
handleMouseOut () {
this.setState({
imgSrc: require('./playbutton.png')
});
}
render() {
return (
<div className='playbutton'>
<a href='./Rule'>
<button className='buttonprop' onClick={this.handleClick} disabled={this.state.disabled}>
{this.state.disabled ? '' :
<img onMouseOver={this.handleMouseOver}
onMouseOut={this.handleMouseOut}
src={this.state.imgSrc} width = {100} height = {50} alt = 'Play'/>}
</button>
</a>
</div>
);
}
}
PlayButton.propTypes = {
}
PlayButton.defaultProps = {
}
export default PlayButton

react change slide in slider after clicking a button

I have a Sidebar that I've implemented this way:
import React from "react";
import './MySidebar.scss';
import {slide as Menu } from 'react-burger-menu'
export class MySidebar extends React.Component {
constructor(props) {
super(props);
}
changeSlide = (e) => {
console.log("Clicked " + e.currentTarget.id); //get text content of
}
render() {
return (
<Menu customCrossIcon={false}>
<button onClick={((e) => this.changeSlide(e))} className ="menu-item" id="Project1">Project 1</button>
<button onClick={((e) => this.changeSlide(e))} className ="menu-item" id="Project2">Project 2</button>
</Menu>
);
}
}
Then I have a component called ProjectSliderComponent that realizes the behaviour of a carousel. It is done this way:
import React from "react";
import Slider from "react-slick";
import './project-carousel.component.css';
import { ProjectComponent } from '../project/project.component';
import { LoggerService } from '../../services/logger-service';
import { appConfig } from '../../config';
export class ProjectSliderComponent extends React.Component {
state = {
activeSlide: 0,
timestamp: Date.now()
}
constructor(props) {
super(props);
this.logger = new LoggerService();
this.settings = {
dots: appConfig.dots,
arrows: false,
adaptiveHeight: true,
infinite: appConfig.infinite,
speed: appConfig.speed,
autoplay: appConfig.autoplay,
autoplaySpeed: appConfig.autoplaySpeed,
slidesToShow: 1,
slidesToScroll: 1,
mobileFirst: true,
className: 'heliosSlide',
beforeChange: (current, next) => {
this.setState({ activeSlide: next, timestamp: Date.now() });
}
};
}
render() {
let i = 0;
return (
<div>
<Slider ref = {c => (this.slider = c)} {...this.settings}>
{
this.props.projectListId.data.map(projectId =>
<ProjectComponent key={projectId} id={projectId} time={this.state.timestamp} originalIndex={ i++ } currentIndex = {this.state.activeSlide}></ProjectComponent>)
}
</Slider>
</div>
);
}
}
The ProjectComponent component simply specifies the layout. This is the App.js file, where I load the projectslidercomponent and my sidebar. I do this:
class App extends Component {
state = {
projectList: new ProjectListModel(),
isLoading: true
}
constructor(props) {
super(props);
this.logger = new LoggerService();
}
componentDidMount() {
let projectService = new ProjectService();
projectService.getProjectList()
.then(res => {
let projectList = new ProjectListModel();
projectList.data = res.data.data;
this.setState({ projectList: projectList,
isLoading: false });
})
.catch(error => {
this.logger.error(error);
});
}
render() {
return (
<div className="App">
<MySidebar>
</MySidebar>
<ProjectSliderComponent projectListId={this.state.projectList}></ProjectSliderComponent>
</div>
);
}
}
export default App;
What I need to do is to change the slide according to which button I clicked. What do I have to do? Is there something like passing the "instance" of the projectslidercomponent and call a method to change the slide? Or something else?
At the react-slick docs you can read about slickGoTo, which is a method of the Slider component.
Since you're already storing this.slider you can try to make it accessible in MySidebar and use it whenever changeSlide is called. Most likely you have to create a changeSlide method on top level and hand it as property to your components.
To sort this problem what you have to do is create a function in parent component which updates the state of the app component and once the state is updated it will re render app component and the new props are send to slider component which will tell which slider to show. Below is the code :-
In App.js
class App extends Component {
state = {
projectList: new ProjectListModel(),
isLoading: true,
menuId: 0
}
constructor(props) {
super(props);
this.logger = new LoggerService();
}
componentDidMount() {
let projectService = new ProjectService();
projectService.getProjectList()
.then(res => {
let projectList = new ProjectListModel();
projectList.data = res.data.data;
this.setState({ projectList: projectList,
isLoading: false });
})
.catch(error => {
this.logger.error(error);
});
}
ChangeSlide = (menuId) => {
this.setState({
menuId //Here you will receive which slide to show and according to that render slides in mySliderbar component
})
}
render() {
return (
<div className="App">
<MySidebar ChangeSlide={this.ChangeSlide} />
<ProjectSliderComponent menuId={this.state.menuId} projectListId={this.state.projectList}></ProjectSliderComponent>
</div>
);
}
}
export default App;
In mySlidebar
import React from "react";
import './MySidebar.scss';
import {slide as Menu } from 'react-burger-menu'
export class MySidebar extends React.Component {
constructor(props) {
super(props);
}
changeSlide = (e) => {
console.log("Clicked " + e.currentTarget.id); //get text content of
this.props.changeSlide(e.currentTarget.id)
}
render() {
return (
<Menu customCrossIcon={false}>
<button onClick={((e) => this.changeSlide(e))} className ="menu-item" id="Project1">Project 1</button>
<button onClick={((e) => this.changeSlide(e))} className ="menu-item" id="Project2">Project 2</button>
</Menu>
);
}
}
In slider component, you have to listen when the new props are coming and according to that change the slide see componentWillReceiveProps
import React from "react";
import Slider from "react-slick";
import './project-carousel.component.css';
import { ProjectComponent } from '../project/project.component';
import { LoggerService } from '../../services/logger-service';
import { appConfig } from '../../config';
export class ProjectSliderComponent extends React.Component {
state = {
activeSlide: 0,
timestamp: Date.now()
}
constructor(props) {
super(props);
this.logger = new LoggerService();
this.settings = {
dots: appConfig.dots,
arrows: false,
adaptiveHeight: true,
infinite: appConfig.infinite,
speed: appConfig.speed,
autoplay: appConfig.autoplay,
autoplaySpeed: appConfig.autoplaySpeed,
slidesToShow: 1,
slidesToScroll: 1,
mobileFirst: true,
className: 'heliosSlide',
beforeChange: (current, next) => {
this.setState({ activeSlide: next, timestamp: Date.now() });
}
};
}
componentWillReceiveProps(nextProps) {
if(nextprops.menuId != this.props.menuId){
this.slider.slickGoTo(nextprops.menuId, true)//use slider instance to
//call the function to go to a particular slide.
}
}
render() {
let i = 0;
const { menuId } = this.props
return (
<div>
<Slider initialSlide={menuId} ref = {c => (this.slider = c)} {...this.settings}>
{
this.props.projectListId.data.map(projectId =>
<ProjectComponent key={projectId} id={projectId} time={this.state.timestamp} originalIndex={ i++ } currentIndex = {this.state.activeSlide}></ProjectComponent>)
}
</Slider>
</div>
);
}
}

Error: Super expression must either be null or a function

Problem
So as the title said i've this issue in a todoapp. i checked if i had some typo like react instead of React and it seems to be alright.
Before post something i checked:
First post stackoverflow
Second post stackoverflow
but i cannot find a solution
Code
App.js
import React, {Component} from 'react';
import Form from './Components/Form';
import Footer from './Components/Footer';
import Header from './Components/Header';
class App extends React{
constructor(props) {
this.state = {
todoValue: "",
filterType: "All",
todos: [],
}
}
handleChange = (event) => {
this.setState({
todoValue: event.target.value,
})
}
handleClick = (event) => {
event.preventDefault();
if (this.state.todoValue !== "") {
const todo = {
id: Date.now(),
text: this.state.todoValue,
done: false,
}
this.setState({
todoValue: "",
todos: [todo, ...this.state.todos],
})
}
}
handleToggle = (id) => {
this.setState((prevState) => {
return {
todos: prevState.todos.map((item, i) => {
if (item.id === id) {
return {
...item,
done: !prevState.todos[i].done,
}
}
return item;
})
}
})
}
handleDelete = (id) => {
this.setState({
todos: this.state.todos.filter(item => item.id !== id)
})
}
deleteCompleted = () => {
this.setState({
todos: this.state.todos.filter(item => !item.done)
})
}
getVisibleTodos = () => {
const filterType = this.state.filterType;
let filterState = null;
switch (filterType) {
case "Completed":
return filterState = this.state.todos.filter(item => item.done);
case "Active":
return filterState = this.state.todos.filter(item => !item.done);
case "Originals":
return filterState = this.state.todos.filter(item => !item.done);
case "New":
return filterState = this.state.todos.filter(item => !item.done);
default:
return filterState = this.state.todos;
}
}
setActiveFilter = (text) => {
this.setState({
filterType: text,
})
}
render() {
return (
<div className="container">
<Header countTodo={this.state.todos.length}/>
<Form handleDelete={this.handleDelete}
handleToggle={this.handleToggle}
handleClick={this.handleClick}
handleChange={this.handleChange}
todoValue={this.state.todoValue}
todos={this.getVisibleTodos()}/>
<Footer setActiveFilter={this.setActiveFilter}
deleteCompleted={this.deleteCompleted}
filter={this.state.filterType}/>
</div>
)
}
}
export default App;
Header.js
import React from 'react';
class Header extends React.Component {
render() {
return (
<header className="header">
<h3>All To-Do {this.props.countTodo}</h3>
</header>
)
}
}
export default Header;
Form.js
import React, {Component} from'react';
import Todo from './Todo';
class Form extends React {
render() {
return (
<form className="form">
<input type="text"
className="form__input"
placeholder="Items"
onChange={this.props.handleChange}
value={this.props.todoValue}
/>
<button
className="form__button"
type="submit"
onClick={this.props.handleClick}>â•‹</button>
<Todo
todos={this.props.todos}
handleToggle={this.props.handleToggle}
handleDelete={this.props.handleDelete}
/>
</form>
)
}
}
export default Form;
and the last modul is Todo.js
import React, {Component} from 'react';
class Todo extends React{
render() {
return (
<ul className="todos-list">
{
this.props.todos.map((item) => {
return (
<li className="todo-item"
key={item.id} onClick={() => this.props.handleToggle(item.id)}>
<span
className={item.done ? "todo-item__name disabled" : "todo-item__name"}>
{item.text}
</span>
<span
className="todo-item__delete-button"
onClick={() => this.props.handleDelete(item.id)}>
×
</span>
</li>
)
})
}
</ul>
)
}
}
export default Todo;
You class should extend from Component that you're importing from react library.
It should be either
class App extends Component{}
or if you didn't import Component then
class App extends React.Component{}
You haven't extended your App component correctly
class App extends React{ // error here
constructor(props) {
this.state = {
todoValue: "",
filterType: "All",
todos: [],
}
}
Extend it from React.Component
class App extends React.Component {
constructor(props) {
super(props); // use super here
this.state = {
todoValue: "",
filterType: "All",
todos: [],
}
}

How to modify styles within the draftjs editor?

I'm tring to use draftjs and want to crate a custom block component.
First question is, I can't perfectly complete an example which is create in document (link here).
When I click the button named 'bold', the editor loses focus and my text doesn't get bolder.
Here is my code:
import React, { Component } from 'react';
import { Editor, EditorState, RichUtils } from 'draft-js';
import { Paper, Button } from '#material-ui/core';
class ProductComponent extends Component {
render() {
const { src } = this.props;
return (
<div>{src}</div>
)
}
}
export default class MyEditor extends React.Component {
constructor(props) {
super(props);
this.state = {
editorState: EditorState.createEmpty()
}
}
onChange = (editorState) => this.setState({ editorState });
onBoldClick = () => {
this.onChange(RichUtils.toggleInlineStyle(this.state.editorState, 'BOLD'));
}
myBlockStyleFn = (contentBlock) => {
const type = contentBlock.getType();
if (type === 'product') {
return {
component: ProductComponent,
editable: false,
props: {
src: 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3307626454,3432420457&fm=27&gp=0.jpg',
},
}
}
}
render() {
const {editorState} = this.state;
return (
<Paper elevation={0}>
<Button onClick={this.onBoldClick}>bold</Button>
<Editor
blockStyleFn={this.myBlockStyleFn}
editorState={editorState}
onChange={this.onChange}
/>
</Paper>
);
}
}

draftjs how to initiate an editor with content

Stumbled on this cool text editor, draft.js by Facebook.
I tried to follow the example in Github, but I want to create an editor with content instead of an empty editor.
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()})
}
});
When I run it, it throws an error with the following message "Uncaught TypeError: contentState.getBlockMap is not a function".
The first argument to EditorState.createWithContent is a ContentState, not a string. You need to import ContentState
var EditorState = Draft.EditorState;
var ContentState = Draft.ContentState;
Use ContentState.createFromText And pass the result to EditorState.createWithContent.
return {
editorState: EditorState.createWithContent(ContentState.createFromText('Hello'))
};
I've created a set of packages for DraftJS to help with importing and exporting content (HTML/Markdown). I use these in my project react-rte. The one you're probably looking for is: draft-js-import-html on npm.
npm install draft-js-import-html
An example of how you might use it:
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)
};
}
});
The modules I've published are:
draft-js-import-html
draft-js-export-html
draft-js-import-markdown
draft-js-export-markdown
There has been some API changes, for clarity these examples uses latest API which is v0.10.0.
There are many ways but basically you got three options depending on whether you want to use plain text, styled text or html markup for content resource.
What plain text is obvious but for styled text, you need to use either serialized javasript object or html markup.
Lets start with plain text example:
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}
/>
)
}
}
For importing styled content Draft.js provides convertFromRaw and convertFromHTML utility functions.
convertFromRaw function takes raw javascript object as parameter. Here, we are using a JSON stringified javascript object as content source:
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 provides convertToRaw function so that you can convert your editor's state to raw javascript object for long term storage.
And lastly, here how you do it with html markup:
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}
/>
)
}
}
You can use convertFromHTML to import html with 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)
}
As shown in Draft's convertFromHtml example. Note that the 0.9.1 version cannot import images, whereas 0.10.0 can.
In 0.10.0 createFromBlockArray changes to:
const content = ContentState.createFromBlockArray(
blocksFromHTML.contentBlocks,
blocksFromHTML.entityMap
)
When you need to initiate an editor with plain text.
Use EditorState.createWithContent and ContentState.createFromText methods. Working example - https://jsfiddle.net/levsha/3m5780jc/
constructor(props) {
super(props);
const initialContent = 'Some text';
const editorState = EditorState.createWithContent(ContentState.createFromText(initialContent));
this.state = {
editorState
};
}
When you need to initiate an editor with content from the html markup string.
Use convertFromHTML and ContentState.createFromBlockArray. Working example - 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),
};
}
When you have an array of string and you want to initiate an editor with some of the default draft.js block types.
You can create array of ContentBlockss with constructor new ContentBlock(...), and pass it to ContentState.createFromBlockArray method. Working example with 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))
};
}
When you need to initiate an editor with content from ContentState raw JS structure.
If you previously saved you content state to raw JS structure with convertToRaw (read this answer for details). You can initiate an editor with convertFromRaw method. Working example - https://jsfiddle.net/levsha/tutc419a/
constructor(props) {
super(props);
this.state = {
editorState: EditorState.createWithContent(convertFromRaw(JSON.parse(editorStateAsJSON)))
};
}
In simple, you can set raw HTML content to editor from the initial stage or using setState at any time as below.
editorState: EditorState.createWithContent(ContentState.createFromBlockArray(convertFromHTML('<b>Program</b>')))
Import the necessary components.
import { EditorState, ContentState, convertFromHTML } from 'draft-js'
I found this to be a clean way of doing things with rich functionality. You can add more plugins in the future, export your content as .md etc without changing the structure of your component much.
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>
);
}
}
You can set the initial value to your edtitorState just by add the folwwling code if you want to set it with HTML format
this.state = {
editorState: EditorState.createWithContent(
ContentState.createFromBlockArray(
convertFromHTML('<p>My initial content.</p>')
)
),
}
for Nextjs
import React, { Component } from 'react';
import { EditorState, convertToRaw, ContentState, convertFromHTML } from 'draft-
js';
import draftToHtml from 'draftjs-to-html';
import dynamic from 'next/dynamic';
import "react-draft-wysiwyg/dist/react-draft-wysiwyg.css";
const Editor = dynamic(
() => import('react-draft-wysiwyg').then(mod => mod.Editor),
{ ssr: false }
)
let htmlToDraft = null;
if (typeof window === 'object') {
htmlToDraft = require('html-to-draftjs').default;
}
export default class EditorConvertToHTML extends Component {
constructor(props) {
super(props);
this.state = {
editorState: EditorState.createEmpty(),
contentState: ""
}
}
componentDidMount() {
const html = '<p>Hey this <strong>editor</strong> rocks d😀</p>';
const contentBlock = htmlToDraft(html);
console.log(contentBlock)
if (contentBlock) {
const contentState =
ContentState.createFromBlockArray(contentBlock.contentBlocks);
const editorState = EditorState.createWithContent(contentState);
console.log(editorState)
this.setState(
{
editorState: EditorState.createWithContent(
ContentState.createFromBlockArray(
convertFromHTML(html)
)
)
}
)
}
}
onEditorStateChange = (editorState) => {
this.setState({
editorState,
});
};
render() {
const { editorState } = this.state;
console.log(this.state.editorState.getCurrentContent())
return (
<div>
<Editor
editorState={editorState}
wrapperClassName="demo-wrapper"
editorClassName="demo-editor"
onEditorStateChange={this.onEditorStateChange}
/>
<textarea
disabled
value=
{draftToHtml(convertToRaw(editorState.getCurrentContent()))}
/>
</div>
);
}
}
you can use insertText()
insertContent(){
const contentState=editorState.getCurrentState();
const selection=editorState.getSelection();
const newContentState=Modifer.insertText(contentState,selection,'hello');
const nextEditorState=EditorState.push(editorState,newContentState,'insert-character')
setEditorState(nextEditorState)
}

Resources