I have a contectEditable
div and button, and want when I select a text in the div like this (
and then press the button, to replace the selected text with a span html element with the selected text as content. For example, I have this React component
import {useState} from 'react';
const EdiatbelContent = () => {
const onClickhandler () => {};
const [html, setHtml] = useState("<p>Hello World!</p>");
return <>
<div contentEditable="true" dangerouslySetInnerHTML={{ __html: html }}></div>
<button onClick={onClickHandler}>Bold</button>
</>
}
export default EditableContent;
I want when I press the button, to replace the selected text (if any is selected), say the word Hello
in the example above, with the span html element <span className="text-bold">Hello</span>
so that the html state variable becomes
<p><span className="text-bold">Hello</span> World!</p>
How can I achieve this?
CodePudding user response:
If I have got the question correctly, you can use the Selection API to access the user's selection and use its properties to achieve what you want. Here is the bit of code that could get you started:
const onClickHandler = () => {
// get user's selection
const selection = window.getSelection();
// get the start and end index of selection
// remember user can select backwards
let startIndex = selection.anchorOffset;
let endIndex = selection.focusOffset;
if (startIndex > endIndex) {
startIndex = selection.focusOffset;
endIndex = selection.anchorOffset;
}
// now get the text before and after the selection
const beforeSelection = html.substring(0, startIndex);
const afterSelection = html.substring(endIndex, html.length);
// and set the html as you see fit
setHtml(`${beforeSelection}<span className="text-bold">${selection.toString()}</span>${afterSelection}`)
};
This of course is the most basic form, you need to take a lot of edge cases into consideration.
CodePudding user response:
onClickhandler = () =>{
setHtml('<p><span className="text-bold">Hello</span> World!</p>')
}