AngularJS: курсор перемещается в последнюю позицию при преобразовании модели - PullRequest
0 голосов
/ 26 сентября 2018

Я использую директиву zipcode, которая принимает 9-значный почтовый индекс США и форматирует его.

app.directive('formatZipCode', function () {
    return {
        require: 'ngModel',
        link: function (scope, element, attr, ngModelCtrl) {
            function fromUser(text) {
                if (text) {
                    var transformedInput = text.replace(/[^0-9]/g, '');
                    if (transformedInput.length > 9) {
                        transformedInput = transformedInput.slice(0, 9);
                    }
                    if (transformedInput.length > 5) {
                        transformedInput = transformedInput.slice(0, 5) + "-" + transformedInput.slice(5);
                    }

                    if (transformedInput !== text) {
                        ngModelCtrl.$setViewValue(transformedInput);
                        ngModelCtrl.$render();
                    }
                    return transformedInput;
                }
                return undefined;
            }


            ngModelCtrl.$parsers.push(fromUser);
        }
    };
});

, когда я удаляю любое число из zipcode, позиция курсора возвращается к последней позиции. При удалении третьего номера курсор перемещается на последний номер

Как сохранить позицию курсора?

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

Я решил это, используя позицию каретки.Запомните позицию каретки и после форматирования введите назначенную позицию каретки снова.

app.directive('formatZipCode', function () {
    return {
        require: 'ngModel',
        link: function (scope, element, attr, ngModelCtrl) {
            function fromUser(text) {
                if (text) {
                    var transformedInput = text.replace(/[^0-9]/g, '');
                    if (transformedInput.length > 9) {
                        transformedInput = transformedInput.slice(0, 9);
                    }
                    var caretPosition = element[0].selectionStart || undefined;
                    if (transformedInput.length > 5) {                     
                        var realposition = caretPosition == 6 ? caretPosition + 1 : caretPosition;
                        transformedInput = transformedInput.slice(0, 5) + "-" + transformedInput.slice(5);
                    }

                    if (transformedInput !== text) {                      
                        ngModelCtrl.$setViewValue(transformedInput);
                        ngModelCtrl.$render();
                        if (typeof caretPosition === 'number') {
                            element[0].selectionStart = element[0].selectionEnd = realposition || caretPosition;
                        }
                        else {
                            element[0].selectionStart = element[0].selectionEnd = 0;
                        }
                    }
                    return transformedInput;
                }
                return undefined;
            }

            ngModelCtrl.$parsers.push(fromUser);
        }
    };
});
0 голосов
/ 26 сентября 2018

Ваш лучший вариант - использовать ng-model-options, чтобы измениться при обновлении ввода (и, таким образом, запустить ваш форматтер).

Это тот случай, когда вы жертвуете живым переформатированием в пользу удобства использования формы.

Либо используйте

<input type="text" ng-model="zipcode" ng-model-options="{ updateOn: 'blur' }" format-zip-code /> 

для обновления, когда пользователь покидает поле, либо

<input type="text" ng-model="zipcode" ng-model-options="{ debounce: 1000 }" format-zip-code />

для обновления после 1s.Этот параметр будет по-прежнему отображать курсор, перемещающийся в конец ввода после обновления, но не сразу.

...