I have a site where we are using multiple forms on the same page. I have used Draftjs with react to create rich html text inputs, which I have customized to use only the controls I actually need:
class RichEditor extends React.Component {
constructor(props) {
super(props);
this.state = {editorState: EditorState.createEmpty()};
this.focus = () => this.refs.editor.focus();
this.onChange = (editorState) => {
this.setState({editorState});
}
this.handleKeyCommand = (command) => this._handleKeyCommand(command);
this.onTab = (e) => this._onTab(e);
this.toggleBlockType = (type) => this._toggleBlockType(type);
this.toggleInlineStyle = (style) => this._toggleInlineStyle(style);
}
_handleKeyCommand(command) {
const {editorState} = this.state;
const newState = RichUtils.handleKeyCommand(editorState, command);
if (newState) {
this.onChange(newState);
return true;
}
return false;
}
_onTab(e) {
const maxDepth = 4;
this.onChange(RichUtils.onTab(e, this.state.editorState, maxDepth));
}
_toggleBlockType(blockType) {
this.onChange(
RichUtils.toggleBlockType(
this.state.editorState,
blockType
)
);
}
_toggleInlineStyle(inlineStyle) {
this.onChange(
RichUtils.toggleInlineStyle(
this.state.editorState,
inlineStyle
)
);
}
render() {
const { editorState } = this.state;
let className = 'RichEditor-editor';
var contentState = editorState.getCurrentContent();
if (!contentState.hasText()) {
if (contentState.getBlockMap().first().getType() !== 'unstyled') {
className += ' RichEditor-hidePlaceholder';
}
}
return (
<div className="RichEditor-root">
<BlockStyleControls
editorState={editorState}
onToggle={this.toggleBlockType}
/>
<InlineStyleControls
editorState={editorState}
onToggle={this.toggleInlineStyle}
/>
<div className={className} onClick={this.focus}>
<Editor
blockStyleFn={getBlockStyle}
customStyleMap={styleMap}
editorState={editorState}
handleKeyCommand={this.handleKeyCommand}
onChange={this.onChange}
onTab={this.onTab}
placeholder=""
ref="editor"
spellCheck={true}
/>
</div>
</div>
);
}
}
module.exports = RichEditor
My parent component looks like this:
class WrapperComponent extends React.Component {
constructor(props) {
super(props);
this.onChange = (editorState2) => {
this.setState({editorState2});
console.log("onChange");
console.log(editorState2);
}
this.state = {
editorState1: EditorState.createEmpty(),
editorState2: EditorState.createEmpty(),
html: null
}
}
update() {
console.log("update");
console.log(this.state.editorState2);
console.log(convertToRaw(this.state.editorState2.getCurrentContent()));
//this.setState({ draftEditor2: e.value });
this.setState({ html: stateToHTML(this.state.editorState2.getCurrentContent()) });
}
render () {
const Editable = () => (
<div className="editor">
<div className="editor-inner">
<h3>Redigerar: Anbudsbrev</h3>
<h4>Rubrik</h4>
<input type="text" name="title" />
<h4>Text 1</h4>
<RichEditor editorState={this.state.editorState1} updateStateToParent={this.onChange} name="text01" ref="editor" />
<h4>Citat</h4>
<input type="text" name="quote01" />
<h4>Text 2</h4>
<RichEditor updateStateToParent={this.onChange} name="text02" ref="editor" />
<EditorFooter {...this.props} submitForm={this.submitForm} />
<button onClick={this.update.bind(this)}>Update</button>
<div>{this.state.html}</div>
</div>
</div>
);
const Readable = () => (
<div>
<h1 className="header66">{this.props.title}</h1>
<div className="text66">{this.props.text01}</div>
<div className="quote100">{this.props.quote01}</div>
<div className="text66">{this.props.text02}</div>
</div>
);
return (
<div>
{ this.props.isInEditMode ? <Editable /> : <Readable /> }
</div>
);
}
};
WrapperComponent.defaultProps = {
height: 100,
title: "Lorem ipsum dolor sit amet",
text01: "Mauris sollicitudin purus accumsan libero fringilla, vitae vulputate lorem aliquam. Nunc ipsum nisl, consectetur ac ultrices ac, pretium vitae lectus. Cras vestibulum, arcu non condimentum hendrerit, dolor ante molestie ante, eget dapibus felis quam a ante. Nunc fringilla risus eget nunc tincidunt sodales.",
quote01: "Aliquam erat volutpat.",
text02: "Praesent non erat quis sem mollis sodales. Integer convallis metus in ligula vehicula, quis vulputate lectus accumsan. Aliquam luctus posuere mollis. Aliquam luctus dignissim quam, ut aliquet ligula pellentesque ac. Nulla sodales lacus sem, eu pharetra arcu aliquet ac. Sed in venenatis libero."
};
WrapperComponent.propTypes = {
content: PropTypes.object,
itemId: PropTypes.string
}
module.exports = WrapperComponent
But I seem to be misunderstanding something fundamental. I can't get the value from either of the editors.
If I send updateStateToParent
to my RichEditor
I can see some stuff happening, but I can't grab the state from the RichEditor
and add it to the state of the WrapperComponent
.
I think I am approaching this in the wrong way, but I can't get my head around how to solve it.