Reputation: 445
This question is specificcally dedicated to react-quill.
What I want to do : replace some text in a react-quill componement by an other while typing. For example: #s1
will be replace by something like productname(1eq, 100mg, 10ml)
. Be aware, I don't want to use JQuery.
So far I did it like this (code below), but once the modification is made, I lose the focus and don't know how to get it back. More over the console does throw an error of type "The given range isn't in document." So basically, it works, but the user has to click in the component to continue typing and if I have more than one react-quill component in the page it will scroll to the firt react-quill object (which is not conveniant when working on the last one).
class Procedure extends Component {
constructor(props){
super(props);
this.state={
content='';
}
}
replaceTagByText(value){
return value.replace(/#(\w+)\s/, myNewValue );
}
handleProcedureContentChange = (value) => {
let newValue = replaceTagByText(value);
this.setState({content:newValue});
};
render() {
return (
<div>
<div style={styles.title}>My title</div>
<ReactQuill
key={"procedure_RTE_" + this.props.experimentId}
value={this.state.content}
modules={modules}
formats={formats}
onChange={this.handleProcedureContentChange}
/>
</div>
);
}
}
Please note that the code is over simplified, I use redux to serve my data, but the general idea is here.
The question is : how to properly replace a text in a react-quill while typing, without loosing focus and keep the cursor at the correct place.
Upvotes: 4
Views: 9302
Reputation: 445
If finally find a solution. The idea is to keep track of the editor and just set the right setSelection. The updated code is bellow.
class Procedure extends Component {
constructor(props){
super(props);
this.state={
content='';
}
}
replaceTagByText(value){
return value.replace(/#(\w+)\s/, myNewValue );
}
//Modification of the code is there
handleProcedureContentChange = (value) => {
let newValueObject = replaceTagByText(value);
this.setState({content:newValueObject.value});
quillRef = this.refs.myQuillRef.getEditor();
//I need that settimeout to do it after the update of my redux logic
setTimeout(() => {
quillRef.focus();
quillRef.setSelection(newValueObject.indexAfterInsertion, 0, myQuillRef);
}, 500);
};
render() {
let myRef = (el) => this.myQuillRef = el;
return (
<div>
<div style={styles.title}>My title</div>
<ReactQuill
key={"procedure_RTE_" + this.props.experimentId}
ref={myRef}
value={this.state.content}
modules={modules}
formats={formats}
onChange={()this.handleProcedureContentChange}
/>
</div>
);
}
}
Upvotes: 2