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

fix(input): make md-maxlength validation happen on initialization #11150

Merged
merged 1 commit into from
Mar 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 17 additions & 15 deletions src/components/input/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -634,11 +634,25 @@ function mdMaxlengthDirective($animate, $mdUtil) {
};

function postLink(scope, element, attr, ctrls) {
var maxlength;
var maxlength = parseInt(attr.mdMaxlength);
if (isNaN(maxlength)) maxlength = -1;
var ngModelCtrl = ctrls[0];
var containerCtrl = ctrls[1];
var charCountEl, errorsSpacer;


ngModelCtrl.$validators['md-maxlength'] = function(modelValue, viewValue) {
if (!angular.isNumber(maxlength) || maxlength < 0) {
return true;
}

// We always update the char count, when the modelValue has changed.
// Using the $validators for triggering the update works very well.
renderCharCount();

return ( modelValue || element.val() || viewValue || '' ).length <= maxlength;
};

// Wait until the next tick to ensure that the input has setup the errors spacer where we will
// append our counter
$mdUtil.nextTick(function() {
Expand All @@ -663,23 +677,11 @@ function mdMaxlengthDirective($animate, $mdUtil) {
$animate.leave(charCountEl);
}
});

ngModelCtrl.$validators['md-maxlength'] = function(modelValue, viewValue) {
if (!angular.isNumber(maxlength) || maxlength < 0) {
return true;
}

// We always update the char count, when the modelValue has changed.
// Using the $validators for triggering the update works very well.
renderCharCount();

return ( modelValue || element.val() || viewValue || '' ).length <= maxlength;
};
});

function renderCharCount(value) {
// If we have not been appended to the body yet; do not render
if (!charCountEl.parent) {
// If we have not been initialized or appended to the body yet; do not render
if (!charCountEl || !charCountEl.parent) {
return value;
}

Expand Down
37 changes: 35 additions & 2 deletions src/components/input/input.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,40 @@ describe('md-input-container directive', function() {
return angular.element(el[0].querySelector('.md-char-counter'));
}

it('should error with a constant and incorrect initial value', function() {
var el = $compile(
'<form name="form">' +
' <md-input-container>' +
' <input md-maxlength="2" ng-model="foo" name="foo">' +
' </md-input-container>' +
'</form>')(pageScope);

pageScope.$apply('foo = "ABCDEFGHIJ"');

// Flush any pending $mdUtil.nextTick calls
$timeout.flush();

expect(pageScope.form.foo.$error['md-maxlength']).toBe(true);
expect(getCharCounter(el).text()).toBe('10 / 2');
});

it('should work with a constant and correct initial value', function() {
var el = $compile(
'<form name="form">' +
' <md-input-container>' +
' <input md-maxlength="5" ng-model="foo" name="foo">' +
' </md-input-container>' +
'</form>')(pageScope);

pageScope.$apply('foo = "abcde"');

// Flush any pending $mdUtil.nextTick calls
$timeout.flush();

expect(pageScope.form.foo.$error['md-maxlength']).toBeFalsy();
expect(getCharCounter(el).text()).toBe('5 / 5');
});

it('should work with a constant', function() {
var el = $compile(
'<form name="form">' +
Expand Down Expand Up @@ -341,11 +375,10 @@ describe('md-input-container directive', function() {
' </md-input-container>' +
'</form>')(pageScope);

pageScope.$apply();
pageScope.$apply('max = -1');

// Flush any pending $mdUtil.nextTick calls
$timeout.flush();

expect(pageScope.form.foo.$error['md-maxlength']).toBeFalsy();
expect(getCharCounter(el).length).toBe(0);

Expand Down