catandmouse
catandmouse

Reputation: 11809

How to directly insert text anywhere in an input field when a button is clicked in React?

Let's say I have an input field:

<input type="text" value={this.state.title} />

Now it has a value of e.g. "Good morning!". What I'd like to do is to be able to insert some pre-defined text into the input field when a particular button is clicked anywhere in the input field. E.g. When I click "[First Name]" / "[LastName]" buttons, the value of the input field can become, e.g. "Good morning [First Name]".

I am able to add at the end of the text currently by getting the focused input, assigning that to state, and then using that to know which key in the state to change:

addCodeText(value) {
    const { currFocusedInput } = this.state;

    this.setState({
      [currFocusedInput]: `${
        this.state[currFocusedInput]
      } [${value}]`,
    });
  }

However, as I mentioned, this only adds to the end of the text. I'd like to be able to directly insert into the input tag / element instead of changing the state so that I can choose where to insert (anyway, the input element is a controlled input).

What I meant is that I can put the cursor in the input field in front of "Good Morning" and the resulting value when I click the button would be e.g. "[First Name], Good morning!". In my current example, it always appends at the end of whatever is the value of the string.

How do I go about doing this?

Upvotes: 5

Views: 7271

Answers (2)

Michael Money
Michael Money

Reputation: 2449

@catandmouse There's another way to do it. You don't need to use Hooks. It can be done using component's local state via setState method. You can play with below example.

First you got string "A word" inside <input> field. After clicking the button, you will get "A word with big sense".

class FieldUpdate extends React.Component {
    constructor() {
        super();
        this.state = {
            title: 'A word',
        };
    }

    onChange(e) {
        this.setState({
            title: e.target.value
        });
    }

    updateText(text) {
        this.setState({
            title: `${this.state.title} ${text}`
        });
    }

    render() {
        return (
            <div>
                <input type="text" value={this.state.title} onChange={(e) => this.onChange(e)} />
                <button onClick={() => this.updateText('with big sense')}>Update text</button>
            </div>);
    }
}

React.render(<FieldUpdate />, document.getElementById('app'));
<head><script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/0.14.0/react-dom.min.js"></script>
</head>
<body>
<div id="app"></app>
</body>

Upvotes: 1

jones
jones

Reputation: 625

Use a ref. Something like the following using React Hooks?

   function App(){
     const ref = useRef('');

     const [val,setVal] = useState('Good morning');

     function onClick() {
        ref.current.value = `${val} you!`;
     }

     return( 
         <div>
            <Button onClick={onClick}>Click</Button>
            <Input ref={ref} />
         </div>
     );
   }

Upvotes: 1

Related Questions