Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send cursor to the end of input value in React

I am dynamically passing a value to my input field when clicking delete (in order to edit the last input entry).

I can see that in Chrome once the input value gets rendered the cursor shows up a the beginning of the word, while in Safari and Firefox goes at the end of the value but the last letter gets deleted.

How can I always see the cursor at the end without deleting the last letter(unless I hit backspace twice)?

  tagEvent(e) {
    const tag = this.text.value;
    const tagGroup = tag.split(" ");
    const tiles = this.props.tiles;
    const hasTiles = Object.keys(tiles).length > 0;

    if(e.keyCode === 32 || e.keyCode === 13){
      e.preventDefault();
      tagGroup.map(tag => this.props.addTile(tag));
      this.tagForm.reset();
    }

    if(e.keyCode === 8 && hasTiles && tag === '' ) {
      this.props.editLastTile();
      this.tagForm.reset();
    }
  }

  render() {
    return (
      <div className="input-wrapper">
        <form ref={(input) => this.tagForm = input}>
          <input ref={(input) => this.text = input}
                 type="text"
                 name="new-item"
                 placeholder="type and press space"
                 autoComplete="off"
                 defaultValue={this.props.value}
                 onKeyDown={(e) => this.tagEvent(e)} />
        </form>
      </div>
    )
  }

Here a Pen with the full code

Thanks a lot for the help!

like image 218
Fabio Vella Avatar asked Jul 08 '17 06:07

Fabio Vella


2 Answers

Another simple solution:

<input ref={ref => ref && ref.focus()}
    onFocus={(e)=>e.currentTarget.setSelectionRange(e.currentTarget.value.length, e.currentTarget.value.length)}
    />

ref triggers focus, and that triggers onFocus to calculate the end and set the cursor accordingly.

like image 52
Harley Lang Avatar answered Sep 28 '22 05:09

Harley Lang


For those of you coming here trying to use this with react hooks 🙌

A simple texfield component that toggles the type of the input to password/text, this is the typical case where you would like to allow users to see their password by clicking on a button to toggle the type and see the value.

function TextField() {
  const [type, setType] = useState('text');
  const inputRef = useRef(null);
  const onToggle = useCallback(() => {
    setType(current => type === 'text' ? 'password' : 'text');
    // Setting focus here
    inputRef.current.focus();
  }, []);
  useEffect(() => {
    // Moving cursor to the end
    inputRef.current.selectionStart = inputRef.current.value.length;
    inputRef.current.selectionEnd = inputRef.current.value.length;
  }, [type]);

  return (
    <div>
      <input
        ref={inputRef}
        type={type}
       />
       <button onClick={onToggle}>toggle type</button>
    </div>
  );
}
like image 36
Crysfel Avatar answered Sep 28 '22 04:09

Crysfel