I'm trying to be real fancy with angular inputs by using both ng-pattern and ng-model parsing together. The regex I put in ng-pattern works fine on regex101.com, and even logging it in my app it works great. When using it in ng-pattern however, its saying my input is invalid though when it should not be. I'm wondering when ng-pattern does its thing in relation to when ngModel.$parsers/ngModel.$formatters are doing their thing, because i could see that causing it to fail. Here's some code:
Here's the ngModel parsing directive:
UI.directive('formatSeconds', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
var padZero = function (num, size) {
return ('00' + num).substr(-size);
};
var formatSeconds = function (seconds) {
var min = Math.floor(seconds / 60);
var sec = Math.floor(seconds % 60);
var ms = Math.round(((seconds % 60) - sec) * 1000);
return min + ':' + padZero(sec, 2) + ':' + padZero(ms, 3);
};
var parseTime = function (time) {
time = time.split(':');
var min = parseInt(time[0] || 0);
var sec = parseInt(time[1] || 0);
var ms = parseInt(time[2] || 0);
return min * 60 + sec + (ms / 1000);
};
ngModel.$parsers.push(parseTime);
ngModel.$formatters.push(formatSeconds);
}
};
});
Here's my regex in my controller:
$scope.timeRegex = /^([0-9]+)?\:([0-5][0-9])\:?([0-9]{3})?$/;
And here's the relevant part of my view:
<tbody ng-form name="syncForm">
<tr class="timing-entry" ng-repeat="entry in scenario.syncManifest">
<td>
<input type="text" ng-attr-name="{{'time' + $index}}" required ng-model="entry.time" format-seconds ng-pattern="timeRegex" />
</td>
</tr>
</tbody>
The time in entry
is in seconds, so the formatter puts it in 0:00:000 format. Then I hoped the ng-pattern would kick in and say yes! valid! But I'm wondering if it is running when the time property is still in 0.000 format before parsing.
Angular validation is performed upon the
ng-model
value, that is to say:$parsers
will run and the inputted value will be transformed into how you want it stored in theng-model
. In this case, thats a number representing the number of seconds. Then theng-pattern
will work on that value - if it passes validation,ng-model
will be set.ng-pattern
will go to work on that rawng-model
value. I believe the$formatters
will run and the formatted$viewValue
will be sent to the view regardless of the validation result.Either way - in your example,
ng-pattern
will be working on the integer value of seconds, not the formatted value displayed in the control.