0

I have a feature that works like this:

  1. User enter 4 digits
  2. A space is inserted
  3. User can enter more digits

On Androids (Samsung Galaxy S4, version 3.4) native browser however, this happens:

  1. User enters 6 digits
  2. A space is inserted after the 4th digit
  3. The caret jumps to after the 5th digit, like this: 1234 5|6

Any ideas?

JSFiddle

<div ng-app="test">
    <input type="text" cardnr ng-model="model" maxlength="9"/>
</div>

angular.module('test', []);
angular.module('test').directive('cardnr', function () {
'use strict';
return {
    require: '?ngModel',
    link: function (scope, element, attrs, ngModelCtrl) {
        if (!ngModelCtrl) {
            return;
        }

        ngModelCtrl.$parsers.push(function handlePastedValues(val) {

            if (val === undefined) {
                return;
            }

            if (val.length > 9) {
                val = val.substring(0, 9);
            }

            if (val.charAt(4) !== ' ') {
                val = val.substring(0, 8);
            }

            if (val.length > 5 && val.charAt(4) !== ' ') {
                val = val.substr(0, 4) + ' ' + val.substr(4);
                ngModelCtrl.$setViewValue(val);
                ngModelCtrl.$render();
            }

            return val;
        });

        ngModelCtrl.$parsers.push(function removeIllegalCharacters(val) {

            if (val === undefined) {
                return;
            }

            var clean = val.replace(/[^0-9 ]+/g, '');
            if (val !== clean) {
                ngModelCtrl.$setViewValue(clean);
                ngModelCtrl.$render();
            }
            return clean;
        });

        ngModelCtrl.$parsers.push(function insertSpaceAfterFourCharacters(val) {
            if (val === undefined) {
                return;
            }

            if (val.length == 4) {
                ngModelCtrl.$setViewValue(val + ' ');
                ngModelCtrl.$render();
            }
            return val;
        });

        element.bind('keydown', function (event) {
            var BACKSPACE = 8,
                DELETE = 46,
                SPACE = 32;

            if (event.keyCode === BACKSPACE || event.keyCode === DELETE) {

                if (ngModelCtrl.$viewValue.length === 5) {
                    ngModelCtrl.$setViewValue(ngModelCtrl.$viewValue.substring(0, 3));
                    ngModelCtrl.$render();
                    event.preventDefault();
                }

            }

            if (event.keyCode === SPACE) {
                event.preventDefault();
            }

        });
    }
};
});
Soroush Hakami
  • 5,226
  • 15
  • 66
  • 99

1 Answers1

0

Solved this by programmatically setting the caret position to the end of the input, using this solution: https://stackoverflow.com/a/12518737/463833

Community
  • 1
  • 1
Soroush Hakami
  • 5,226
  • 15
  • 66
  • 99