diff --git a/src/components/IntlTelInputApp.js b/src/components/IntlTelInputApp.js index ad0e893f3..7a212e221 100644 --- a/src/components/IntlTelInputApp.js +++ b/src/components/IntlTelInputApp.js @@ -13,6 +13,35 @@ const mobileUserAgentRegexp = /Android.+Mobile|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i; class IntlTelInputApp extends Component { + + // Get the position of Cursor + static getCursorPosition(prevBeforeCursor, prev, next) { + if (prev === next) { + return prevBeforeCursor.length; + } + let cursorShift = 0; + + if (prev.length > next.length) { + for (let i = 0, j = 0; i < prevBeforeCursor.length && j < next.length; i += 1) { + if (prevBeforeCursor[i] !== next[j]) { + cursorShift -= 1; + } else { + j += 1; + } + } + } else { + for (let i = 0, j = 0; i < prevBeforeCursor.length && j < next.length; j += 1) { + if (prevBeforeCursor[i] !== next[j]) { + cursorShift += 1; + } else { + i += 1; + } + } + } + + return prevBeforeCursor.length + cursorShift; + } + constructor(props) { super(props); @@ -61,6 +90,7 @@ class IntlTelInputApp extends Component { title: '', countryCode: 'us', dialCode: '', + cursorPosition: (props.value || props.defaultValue).length, }; this.selectedCountryData = {}; @@ -1055,14 +1085,24 @@ class IntlTelInputApp extends Component { // Either notify phoneNumber changed if component is controlled // or udpate the state and notify change if component is uncontrolled handleInputChange(e) { + let cursorPosition = e.target.selectionStart; + const previousValue = e.target.value; + const previousStringBeforeCursor = previousValue === '' ? previousValue : previousValue.substring(0, cursorPosition); const value = this.props.format ? this.formatNumber(e.target.value) : e.target.value; + cursorPosition = this.constructor.getCursorPosition(previousStringBeforeCursor, previousValue, value); + if (this.props.value !== undefined) { - this.updateFlagFromNumber(value); - this.notifyPhoneNumberChange(value); + this.setState({ + cursorPosition, + }, () => { + this.updateFlagFromNumber(value); + this.notifyPhoneNumberChange(value); + }); } else { this.setState({ value, + cursorPosition, }, () => { this.updateFlagFromNumber(value); this.notifyPhoneNumberChange(value); @@ -1170,6 +1210,7 @@ class IntlTelInputApp extends Component { autoFocus={ this.props.autoFocus } autoComplete={ this.props.autoComplete } inputProps={ this.props.telInputProps } + cursorPosition={ this.state.cursorPosition } /> ); diff --git a/src/components/TelInput.js b/src/components/TelInput.js index 152cc9185..bfbfab783 100644 --- a/src/components/TelInput.js +++ b/src/components/TelInput.js @@ -2,11 +2,26 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; class TelInput extends Component { + constructor(props) { + super(props); + + this.refHandler = this.refHandler.bind(this); + } + + componentDidUpdate() { + this.tel.setSelectionRange(this.props.cursorPosition, this.props.cursorPosition); + } + + refHandler(element) { + this.tel = element; + this.props.refCallback(element); + } + render() { return (