Reputation: 351
Hi I have a problem in Draft-JS . I want to change the text like when user type ":)" it will change to emoji, But in this example I just want to change some word using "**" for testing. Somehow this.setState new editorstate in handleInput doesnt change the state.
import React, {Component} from 'react';
import {Editor, EditorState,getDefaultKeyBinding,moveFocusToEnd, KeyBindingUtil,getContentStateFragment, SelectionState, Modifier, CompositeDecorator} from 'draft-js';
const storage = {
"Abm7" : "Abminorseventh"
}
export default class MyEditor extends Component {
constructor(props) {
super(props);
this.state = { editorState: EditorState.createEmpty(), lastOffset:0 };
this.focus = () => this.refs.editor.focus();
this.logState = () => console.log(this.state.editorState.toJS());
}
onChange(editorState) {
this.setState({editorState});
}
handleBeforeInput(e) {
if(e === ' ') {
const { editorState } = this.state;
const content = editorState.getCurrentContent();
const selection = editorState.getSelection();
const end = selection.getEndOffset();
const block = content.getBlockForKey(selection.getAnchorKey());
const word = block.getText();
const result = word.slice(this.state.lastOffset, selection.getEndOffset());
const newSelection = new SelectionState({
anchorKey: block.getKey(),
anchorOffset: 0,
focusKey: block.getKey(),
focusOffset: 2
})
const contentReplaced = Modifier.replaceText(
content,
newSelection,
"**")
const editorStateModified = EditorState.push(
editorState,
contentReplaced,
'replace-text'
);
this.setState({lastOffset: selection.getEndOffset(), editorState:editorStateModified})
return true;
}else {
return false;
}
}
prompt(e) {
e.preventDefault();
const {editorState} = this.state;
const content = editorState.getCurrentContent();
const selection = editorState.getSelection();
const block = editorState.getCurrentContent().getBlockForKey(selection.getAnchorKey());
let text = block.getText().slice(selection.getStartOffset(), selection.getEndOffset());
const contentReplaced = Modifier.replaceText(
content,
selection,
storage[text])
const editorStateModified = EditorState.push(
editorState,
contentReplaced,
'replace-text'
);
console.log(editorStateModified.getCurrentContent())
this.setState({editorState:editorStateModified})
}
render() {
const styles = {
root: {
fontFamily: '\'Helvetica\', sans-serif',
padding: 20,
width: 600,
},
editor: {
border: '1px solid #ccc',
cursor: 'text',
minHeight: 80,
padding: 10,
},
button: {
marginTop: 10,
textAlign: 'center',
},
buttons: {
marginBottom: 10,
},
};
return (
<div style={styles.root}>
<div style={styles.buttons}>
<button
onMouseDown={(e)=>{this.prompt(e)}}
style={{marginRight: 10}}>
Change word
</button>
</div>
<div style={styles.editor} onClick={this.focus}>
<Editor
editorState={this.state.editorState}
onChange={(e)=>{this.onChange(e)}}
handleBeforeInput={(e)=>{this.handleBeforeInput(e)}}
placeholder="Enter some text..."
ref="editor"
/>
</div>
<input
onClick={this.logState}
style={styles.button}
type="button"
value="Log State"
/>
</div>
);
}
}
Upvotes: 2
Views: 3472
Reputation: 81
The function handleBeforeInput
should return "handled"
, if you want for you changes to be applied. And it should be returned to Editor
component, so you need to pass the function to the Editor
component as it is, like this:
<Editor
...
handleBeforeInput={this.handleBeforeInput}
...
/>
Reference: https://draftjs.org/docs/api-reference-editor#handlebeforeinput
Upvotes: 1