patw0929 / react-intl-tel-input

Rewrite International Telephone Input in React.js. (Looking for maintainers, and PRs & contributors are also welcomed!)
https://patw0929.github.io/react-intl-tel-input/
MIT License
283 stars 222 forks source link

Wrong cursor position on component update #260

Open tomegz opened 5 years ago

tomegz commented 5 years ago

I'm using formatted number from onPhoneNumberChange to be value of the input. The cursor position is fine when formatted number is exactly the same as input, but when the formatted number is different than the value, then cursor is misplaced.

Live minimal example here: https://tomegz.github.io/react-intl-tel-input-cursor-example/

Code:

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      value: '',
      infoVisible: false,
    }
    this.onPhoneNumberChange = this.onPhoneNumberChange.bind(this)
  }

  onPhoneNumberChange(isValid, value, countryData, number) {
    this.setState({
      value: number,
      infoVisible: value !== number
    })
  }

  render() {
    const { value, infoVisible } = this.state
    return (
      <div className="container">
        <p>Type here:</p>
        <IntlTelInput
          css={['intl-tel-input', 'form-control']}
          value={value}
          onPhoneNumberChange={this.onPhoneNumberChange}
        />
        {infoVisible && <p style={{ position: 'absolute', color: 'red', top: '30px' }}>Cursor position just broke!</p>}
      </div>
    );
  }
}

I submitted #261 to fix this issue

hailuabk commented 5 years ago

I'm using formatted number from onPhoneNumberChange to be value of the input. The cursor position is fine when formatted number is exactly the same as input, but when the formatted number is different than the value, then cursor is misplaced.

Live minimal example here: https://tomegz.github.io/react-intl-tel-input-cursor-example/

Code:

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      value: '',
      infoVisible: false,
    }
    this.onPhoneNumberChange = this.onPhoneNumberChange.bind(this)
  }

  onPhoneNumberChange(isValid, value, countryData, number) {
    this.setState({
      value: number,
      infoVisible: value !== number
    })
  }

  render() {
    const { value, infoVisible } = this.state
    return (
      <div className="container">
        <p>Type here:</p>
        <IntlTelInput
          css={['intl-tel-input', 'form-control']}
          value={value}
          onPhoneNumberChange={this.onPhoneNumberChange}
        />
        {infoVisible && <p style={{ position: 'absolute', color: 'red', top: '30px' }}>Cursor position just broke!</p>}
      </div>
    );
  }
}

I submitted #261 to fix this issue

I got the same problem with you, how can I fix it?

m-nathani commented 4 years ago

This issue is still not fixed... please let us know if there is a solution for it ?

erezcarmel commented 4 years ago

I've found a temporary walkaround for this issue. I'm setting the input cursor position on every typing using onPhoneNumberChange. The setSelectionRange must be used under setTimeout because the input event fires before the browser is moving the caret (I'm using Chrome). Hope that helps.

const PhoneInput = () => {
    const [phone, setPhone] = useState('');

        const setCaretPosition = caretPos => {
                const elem = document.getElementsByClassName('phone-input')[0];

        if (elem) {
            elem.focus();
            setTimeout(() => {
                elem.setSelectionRange(caretPos, caretPos);
            }, 0);
        }
    };

    return <IntlTelInput
        containerClassName="intl-tel-input"
        inputClassName="phone-input"
        defaultCountry="us"
        autoPlaceholder={false}
        value={phone}
        onPhoneNumberChange={
            (status, value, countryData, number) => {
                if (/^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\./0-9]*$/.test(number) || number === '') {
                    setCaretPosition(number.length);
                    setPhone(number);
                }
            }
        }
    />
};
SIRIUS-webkit commented 2 years ago

I still have the problems can anyone help me ?