Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change the cursor position in a textarea with React

I have a textarea in React that I want to turn into a "notepad". Which means I want the "tab" key to indent instead of unfocus. I looked at this answer, but I can't get it to work with React. Here is my code:

handleKeyDown(event) {     if (event.keyCode === 9) { // tab was pressed         event.preventDefault();         var val = this.state.scriptString,             start = event.target.selectionStart,             end = event.target.selectionEnd;          this.setState({"scriptString": val.substring(0, start) + '\t' + val.substring(end)});         // This line doesn't work. The caret position is always at the end of the line         this.refs.input.selectionStart = this.refs.input.selectionEnd = start + 1;     } } onScriptChange(event) {    this.setState({scriptString: event.target.value}); } render() {     return (         <textarea rows="30" cols="100"                    ref="input"                   onKeyDown={this.handleKeyDown.bind(this)}                   onChange={this.onScriptChange.bind(this)}                    value={this.state.scriptString}/>     ) } 

When I run this code, even if I press the "tab" key in the middle of the string, my cursor always appears at the end of the string instead. Anyone knows how to correctly set the cursor position?

like image 251
Discombobulous Avatar asked Jul 14 '16 23:07

Discombobulous


People also ask

How do I change the cursor position in textarea?

To set the cursor at the end of a textarea: Use the setSelectionRange() method to set the current text selection position to the end of the textarea. Call the focus() method on the textarea element. The focus method will move the cursor to the end of the element's value.

How do I get my cursor position in Reactjs?

To get the mouse position in React: Set the onMouseMove prop on an element or add an event listener on the window object. Provide an event handler function. Access relevant properties on the event object.

How do you insert text into the textarea at the current cursor position in react?

When you click a button you move the focused element so there is no cursor in the text anymore. So you would have to track the last location of the cursor and then just set the value of the text area to be the current value + the extra text at the location of the last know cursor position.

How do I get my cursor position in react native?

In order to get the position of the cursor the only thing you need is onSelectionChange https://reactnative.dev/docs/textinput#onselectionchange. The function will return the start and the end values.


2 Answers

You have to change the cursor position after the state has been updated(setState() does not immediately mutate this.state)

In order to do that, you have to wrap this.refs.input.selectionStart = this.refs.input.selectionEnd = start + 1; in a function and pass it as the second argument to setState (callback).

handleKeyDown(event) {       if (event.keyCode === 9) { // tab was pressed           event.preventDefault();           var val = this.state.scriptString,           start = event.target.selectionStart,           end = event.target.selectionEnd;           this.setState(               {                   "scriptString": val.substring(0, start) + '\t' + val.substring(end)               },               () => {                   this.refs.input.selectionStart = this.refs.input.selectionEnd = start + 1               });       }  } 

jsfiddle

like image 95
QoP Avatar answered Sep 19 '22 14:09

QoP


For anyone looking for a quick React Hooks (16.8+) cursor position example:

import React, { useRef } from 'react';  export default () => {   const textareaRef = useRef();    const cursorPosition = 0;    return <textarea     ref={textareaRef}     onBlur={() => textareaRef.current.setSelectionRange(cursorPosition, cursorPosition)}   />  } 

In this example, setSelectionRange is used to set the cursor position to the value of cursorPosition when the input is no longer focused.

For more information about useRef, you can refer to React's official doc's Hook Part.

like image 38
Chris Dolphin Avatar answered Sep 20 '22 14:09

Chris Dolphin