react-native-rich-editor
react-native-rich-editor copied to clipboard
How to get selected text
How can I get the selected text in the editor? I checed the code, it call document.getSelection()
, how can I get it manually.
Having the ability to get both the selected text, surrounding html and character range would be very helpful.
For example:
<p>NORMAL TEXT. <b>BOLD TEXT.</b></p>
If we select "BOLD TEXT" in the editor, it would be awesome to have a method that could return the selected text and even more helpful if there was a method that could return <b>BOLD TEXT.</b>
.
React Native Quill editor has the ability to return the selection range. ItsonSelectionChange
method will return data like this:
{"oldRange": {"index": 19, "length": 6}, "range": {"index": 18, "length": 7}, "source": "user"}
Looking for something similar to get text selection.
Having the ability to get both the selected text, surrounding html and character range would be very helpful.
For example:
<p>NORMAL TEXT. <b>BOLD TEXT.</b></p>
If we select "BOLD TEXT" in the editor, it would be awesome to have a method that could return the selected text and even more helpful if there was a method that could return
<b>BOLD TEXT.</b>
.React Native Quill editor has the ability to return the selection range. Its
onSelectionChange
method will return data like this:{"oldRange": {"index": 19, "length": 6}, "range": {"index": 18, "length": 7}, "source": "user"}
Thanks for your comment, i'll try this
Hi Here is my workaround
import React, { useRef } from 'react';
import { StyleSheet, View } from 'react-native';
import { actions, RichEditor, RichToolbar } from 'react-native-pell-rich-editor';
const RichTextInput: React.FC = () => {
const richText = useRef<RichEditor | null>(null);
// Call this method to inject script and get selected text
const onInjectJavascript = () => {
const script = `(function() {
var value = window.getSelection().toString() || '';
window.ReactNativeWebView.postMessage(JSON.stringify({ data: {type: 'SELECTION_CHANGE', value } }));
void(0);
})();`;
richText.current?.injectJavascript(script);
};
// Callback function to get selected text
const handleOnMessage = (event: { type: string; id: string; data?: any }) => {
if (event?.data?.type === 'SELECTION_CHANGE') {
const selected = event?.data?.value;
console.log('Selected text', selected);
}
};
return (
<>
<View style={styles.toolbarContainer}>
<RichToolbar
style={styles.toolBar}
unselectedButtonStyle={styles.toolbarIcon}
selectedButtonStyle={styles.toolbarIcon}
editor={richText}
actions={[actions.setBold, actions.setItalic, actions.setUnderline, actions.insertLink]}
/>
</View>
<View style={styles.editorContainer}>
<RichEditor
placeholder={'Enter a message'}
ref={richText}
onMessage={handleOnMessage}
androidHardwareAccelerationDisabled={true}
/>
</View>
</>
);
};
const styles = StyleSheet.create({
});
export default RichTextInput;
injectJavascript
method does not exist in node_modules/react-native-pell-rich-editor/src/RichEditor.js
and you have to add in manually
Add these lines in RichEditor.js
injectJavascript(script) {
return this.webviewBridge.injectJavaScript(script);
}
To add injectJavascript
automatically you can use postinstall script in package json
package.json
...
"postinstall": "./update_modules.sh"
Create update_modules.sh
and add these lines
sed -i -e "s/render() {/injectJavascript(script) {\n\\t\\treturn this.webviewBridge.injectJavaScript(script);\n\\t}\n\n\\trender() {/g" node_modules/react-native-pell-rich-editor/src/RichEditor.js
sed -i -e "s/preCode: (/injectJavascript: (script: string) => void;\n\n\\tpreCode: (/g" node_modules/react-native-pell-rich-editor/index.d.ts
Hi Here is my workaround
import React, { useRef } from 'react'; import { StyleSheet, View } from 'react-native'; import { actions, RichEditor, RichToolbar } from 'react-native-pell-rich-editor'; const RichTextInput: React.FC = () => { const richText = useRef<RichEditor | null>(null); // Call this method to inject script and get selected text const onInjectJavascript = () => { const script = `(function() { var value = window.getSelection().toString() || ''; window.ReactNativeWebView.postMessage(JSON.stringify({ data: {type: 'SELECTION_CHANGE', value } })); void(0); })();`; richText.current?.injectJavascript(script); }; // Callback function to get selected text const handleOnMessage = (event: { type: string; id: string; data?: any }) => { if (event?.data?.type === 'SELECTION_CHANGE') { const selected = event?.data?.value; console.log('Selected text', selected); } }; return ( <> <View style={styles.toolbarContainer}> <RichToolbar style={styles.toolBar} unselectedButtonStyle={styles.toolbarIcon} selectedButtonStyle={styles.toolbarIcon} editor={richText} actions={[actions.setBold, actions.setItalic, actions.setUnderline, actions.insertLink]} /> </View> <View style={styles.editorContainer}> <RichEditor placeholder={'Enter a message'} ref={richText} onMessage={handleOnMessage} androidHardwareAccelerationDisabled={true} /> </View> </> ); }; const styles = StyleSheet.create({ }); export default RichTextInput;
injectJavascript
method does not exist innode_modules/react-native-pell-rich-editor/src/RichEditor.js
and you have to add in manually Add these lines inRichEditor.js
injectJavascript(script) { return this.webviewBridge.injectJavaScript(script); }
To add
injectJavascript
automatically you can use postinstall script in package jsonpackage.json
... "postinstall": "./update_modules.sh"
Create
update_modules.sh
and add these linessed -i -e "s/render() {/injectJavascript(script) {\n\\t\\treturn this.webviewBridge.injectJavaScript(script);\n\\t}\n\n\\trender() {/g" node_modules/react-native-pell-rich-editor/src/RichEditor.js sed -i -e "s/preCode: (/injectJavascript: (script: string) => void;\n\n\\tpreCode: (/g" node_modules/react-native-pell-rich-editor/index.d.ts
Hi @gevgasparyan , thanks for your solution! but I have some questions:
- Where should I call
onInjectJavascript
? - If I added
injectJavascript
in manually, do I still need to dopostinstall
?
For now, I just call onInjectJavascript
when I click link icon, but the event in handleOnMessage
is undefined
.
Wish for your reply, thanks!
Hi @sizhe-eb
- Do it when you want to get selected text e.g. when onInsertLink is called.
const insertLink = () => {
const script = `(function() {
var value = window.getSelection().toString() || '';
window.ReactNativeWebView.postMessage(JSON.stringify({ data: {type: 'SELECTION_CHANGE', value } }));
void(0);
})();`;
richText.current?.injectJavascript(script);
};
<RichToolbar
...
onInsertLink={insertLink}
/>
No if you added it manually there is no need to do postinstall
Can you please try to register toolbar like this. It may solve the undefined event issue
if (richText.current) {
richText.current.registerToolbar(() => {});
}
thank you @gevgasparyan
All the above solutions will only give selected text but will not return selected text with the html. I need both for edit hyper link. I have a hyperlink Google. Is there any way to get selected text with the html?
You don't need to access the webviewBridge
since it is a "private" ref used by the lib. You can execute the same command using the commandDOM
function.