Content editable with instant replace
Replaces "1" with bold text
by Arthur Lutkevichus
September 13, 2019
HTML
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/[email protected] /lodash.js"></script>
<script src="http://www.jimsproch.com/react/future/react-dom-server.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
CSS
#container div {
width: 300px;
height: 20px;
border: 1px solid black;
}
Babel + JSX
class Hello extends React.Component{
constructor(props){
super(props);
this.state = {
scriptString: ''
};
this.onChange = this.onChange.bind(this);
this.saveCaretPosition = this.saveCaretPosition.bind(this);
}
saveCaretPosition(context) {
const selection = window.getSelection();
if (!selection.anchorNode) {
return {
pos: 0,
restore: () => {}
};
}
const range = selection.getRangeAt(0);
range.setStart(context, 0);
let len = range.toString().length;
return {
pos: len,
restore: forcePosition => {
let lastNode = null;
const treeWalker = document.createTreeWalker(context, NodeFilter.SHOW_TEXT, elem => {
if (len > elem.textContent.length) {
len -= elem.textContent.length;
lastNode = elem;
return NodeFilter.FILTER_REJECT
}
return NodeFilter.FILTER_ACCEPT;
});
const c = treeWalker.nextNode();
const pos = {
node: c ? c : context,
position: c ? (_.isUndefined(forcePosition) ? len : Math.max(forcePosition, 0)) : 0
};
selection.removeAllRanges();
const range = new Range();
range.setStart(pos.node, pos.position);
selection.addRange(range);
}
}
}
onChange(event) {
const caret = this.saveCaretPosition(event.target);
console.log(event.target.innerHTML)
const value = ReactDOMServer.renderToString(event.target.innerHTML).replace(/<[^>]*>/g, "").replace(/1/g, <b>1</b>);
//const value = <b onClick={()=> console.log("click")}>1</b>;
console.log(value)
this.setState({
value
}, () => {
...