Search code examples
reactjstypescriptantd

How to keep cursor after typing input value not end of the input


Initially If I type 'cde' on the input field, it will be converted to 'CDE'.
then If I type 'A' in front of the 'CDE', it will be converted to 'ACDE'.
but cursor will be moved to the end of the input field.
however, I want to keep the cursor position end of the 'A'.
How can I do that?

I am using antd Form.Item and Input component.

Here is codesandbox line:
https://codesandbox.io/s/divine-dream-2xrzst?file=/src/App.tsx

import React from "react";
import { Form, Input } from "antd";

const MyInputComponent: React.FC = () => {
  return (
    <Form.Item name="input" label="Input">
      <Input onInput={toUpperCase} />
    </Form.Item>
  );
};

export default MyInputComponent;

const toUpperCase = (
  event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>
) => {
  const value = (event.target as HTMLInputElement).value;

  if (typeof value !== "string") return;

  (event.target as HTMLInputElement).value = value.toUpperCase();
};


Solution

  • WHile using the onInput method you can utilise selectionStart, selectionEnd & setSelectionRange() to get the current cursor position and keep it there after the text has changed to uppercase.

    import "./styles.css";
    import React from "react";
    import { Form, Input } from "antd";
    
    const toUpperCase = (
      event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>
    ) => {
      const start = event.currentTarget.selectionStart;
      const end = event.currentTarget.selectionEnd;
      const value = (event.target as HTMLInputElement).value;
    
      if (typeof value !== "string") return;
    
      (event.target as HTMLInputElement).value = value.toUpperCase();
      event.currentTarget.setSelectionRange(start, end);
    };
    
    export default function App() {
      return (
        <Form.Item name="input" label="Input">
          <Input onInput={toUpperCase} />
        </Form.Item>
      );
    }