Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

$parsers function not triggering every 4th keystroke... #10700

@ghost

Description

Hello,

I have a text input that has a custom directive that prevents non numeric values while enforcing maxLength and maintaining cursor position.

In the directive, I have added a $parser that applies these constraints to the input before it is saved to the model. However, for some reason, the $parser does not trigger on every 4th keystroke.

If I manually type the number "1" into the field, the $parser will trigger for each keystroke except the 4th one. This means that every 4th keystroke, a letter or extra character can be added. The very next keystroke will again trigger the $parser as expected, which removes any previously entered invalid values, but if another keystroke is not entered, then the invalid values will remain.

UPDATE
Just verified that this is only an issue if I press the same key 4 times (ex: "1,1,1,1" or "b,b,b,b"). If I press different keys (ex: "a,b,c,d" or "1,2,3,4", then the $parser fires for every keystroke, as expected).

<input only-digits="3" type="text" title="Phone Prefix" ng-pattern="/^(?:5(?!55)|([2-46-9]))\d{2}$/" name="phonePrefix" class="form-control" ng-attr-placeholder="{{PlaceHolderText.PhonePrefix}}" ng-model="PhonePrefix" required>
(function ()
{
    'use strict';

    angular.module("mph.directives").directive('onlyDigits', function ()
    {
        return {
            restrict: 'A',
            require: '?ngModel',
            scope: {
                onlyDigits: "="
            },
            link: function ($scope, element, attrs, ngModel)
            {
                if (!ngModel) { return; }

                var _stripAlpha = function (newValue)
                {
                    if (newValue == null) { return null; }

                    var _el = element[0];
                    var _maxLength = $scope.onlyDigits;
                    var _strippedValue = newValue.replace(/[^\d]+/g, '');
                    var _cursorPosition = _el.selectionStart;

                    if (_strippedValue != newValue)
                    {
                        //recalculates cursor position to where it should be after all non-numeric characters are stripped away
                        _cursorPosition = (_el.selectionStart - (newValue.length - _strippedValue.length));
                    }

                    if (_strippedValue.length > _maxLength)
                    {
                        //strips out any extra digits and re-calculates cursor position
                        var _digits = _strippedValue.split("");
                        var _diff = _digits.length - _maxLength;

                        _cursorPosition -= _diff;

                        _digits.splice(_cursorPosition, _diff);
                        _strippedValue = _digits.join("");
                    }

                    //updates input field to reflect corrected value
                    element.val(_strippedValue);

                    //update cursor position based on final calculation
                    _el.selectionStart = _el.selectionEnd = _cursorPosition;

                    //return corrected value to next $parser in the chain (if exists)
                    return _strippedValue;
                };

                ngModel.$parsers.unshift(_stripAlpha);
            }
        };
    });
}());

Any ideas on why this is happening?

Thanks!

Josh

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions