3

I have a bug when I set the value from the state and change the value in a input.

when you write in the input and you try to correct the text the cursor move to the end.

This is my element

<div className="campo">
  <p>Nombre</p>
  <div className="campo-input">
    <input
     type="text"
     name="name"
     value={this.state.name}
     onChange={this.handleInputChangeUpperCase}
     />
  </div>
</div>

This is my function

handleInputChangeUpperCase = (e) => {
    let { name, value } = e.target;
    this.setState({ [name]: value.toUpperCase() });
  };

Working Snippet:

class App extends React.Component {
  state = {
    name: "Ronaldo",
  };
  
  // This is the function
  handleInputChangeUpperCase = (e) => {
    let { name, value } = e.target;
    this.setState({
      [name]: value.toUpperCase(),
    });
  };
  render() {
  
  // This is the Element
    return (
      <div className="campo">
        <p> Nombre </p>
        <div className="campo-input">
          <input
            type="text"
            name="name"
            value={this.state.name}
            onChange={this.handleInputChangeUpperCase}
          />
          {this.state.name}
        </div>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

1
  • nvm, got it, if we're trying to modify in between there is an issue. Commented Sep 21, 2020 at 21:45

4 Answers 4

3

Based on the original answer: https://stackoverflow.com/a/49648061/7427111

class App extends React.Component {
  state = {
    name: "Ronaldo",
  };
  
  handleInputChangeUpperCase = (e) => {
  
    // Here is the addition
    const pointer = e.target.selectionStart;
    const element = e.target;
    window.requestAnimationFrame(() => {
      element.selectionStart = pointer;
      element.selectionEnd = pointer;
    });

    let { name, value } = e.target;
    this.setState({
      [name]: value.toUpperCase(),
    });
  };
  render() {
    return (
      <div className="campo">
        <p> Nombre </p>
        <div className="campo-input">
          <input
            type="text"
            name="name"
            value={this.state.name}
            onChange={this.handleInputChangeUpperCase}
          />
          {this.state.name}
        </div>
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Sign up to request clarification or add additional context in comments.

Comments

2

To control where the cursor is in an input field, use selectionStart, which indicates where your selected text begins. As long as you don't set selectionEnd, you'll just move the cursor to the desired position.

For instance, let's move to the position "1", just after the first character. For input "123", that should be "1|23"...

document.getElementById('text-area').selectionStart = 1;
document.getElementById('text-area').focus()
  <input id="text-area" type="text" value="123"/>

For your situation, if you want the cursor to move to the start of the string, set .selectionStart = 0. If you want it to go back to where it was originally, save the value with var tempstart = ...selectionStart, and then restore it after you do the data change, .selectionStart = tempstart.

Source: Developer.Mozilla.org: HTMLInputElement.setSelectionRange()

Comments

1

If you need just toUpperCase as formatting then you can use css instead. It seems the simplest solution is described here https://stackoverflow.com/a/3724990/12868043

Comments

0

That behaviour seems to be happening with .toUpperCase();

handleInputChangeUpperCase = e => {    
    this.setState({ [e.target.name]: e.target.value });
};

If you don't require the text to be upper case immediately on input, I would apply the method outside of the setState

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.