admin 管理员组

文章数量: 1086019

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=".6.3/umd/react.production.min.js"></script>
<script src=".6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

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./ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Share Improve this question edited Sep 21, 2020 at 22:03 Dhaval Jardosh 7,3095 gold badges34 silver badges74 bronze badges asked Sep 21, 2020 at 21:34 EdsenEdsen 773 silver badges7 bronze badges 1
  • nvm, got it, if we're trying to modify in between there is an issue. – Dhaval Jardosh Commented Sep 21, 2020 at 21:45
Add a ment  | 

4 Answers 4

Reset to default 3

Based on the original answer: https://stackoverflow./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./ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

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: HTMLInputElement.setSelectionRange()

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

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

本文标签: javascriptReact onChange text input is moving cursor to end of text in input fieldStack Overflow