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.

ngModelController $parsers function not called consistently #12544

@visnup

Description

@visnup

When enforcing input values to conform to certain rules using an ngModelController $parser function, the $parser function isn't called on repeated "invalid" keystrokes, which allows invalid characters to get added.

In the example below, the directive is meant to remove all non-digit characters. it mostly works, but if you type the same non-digit character twice in a row (e.g. 'xx'), a single 'x' will show up in the input. if you type 'x' a third time, it will remove the 'x'.

I've also included a failing test case.

all code is running at http://codepen.io/visnup/pen/YXgLVq?editors=101

directive usage

<div ng-app="digits">
  <input ng-model="number" placeholder="digits only" digits-only />
</div>

directive

angular
  .module('digits', [])
  .directive('digitsOnly', function() {
    return {
      require: 'ngModel',
      link: function link(scope, element, attrs, ngModel) {
        ngModel.$parsers.push(function(value) {
          var numbers = value.replace(/\D/g, '');
          element.val(numbers);
          return numbers;
        });
      }
    };
  });

failing test case

describe('digits', function() {
  beforeEach(angular.mock.module('digits'));

  let scope, input;
  beforeEach(inject(function($compile, $rootScope) {
    scope = $rootScope;
    input = $compile('<input ng-model="number" digits-only />')(scope);
  }));

  // works
  it('should block non-digits', function() {
    input.val('111x');
    input.triggerHandler('input');
    expect(input.val()).to.equal('111');
  });

  // doesn't work
  it('should not flash incorrect input', function() {
    input.val('111x');
    input.triggerHandler('input');
    input.val('111x');
    input.triggerHandler('input');
    expect(input.val()).to.equal('111');
  });
});

This has been brought up before in #10700.

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