I wrote an Angular directive to capture percentage values in fractions (100% = 1.0) in model, but whole numbers in view. It works great in most of the scenarios, but I am not sure how to trigger the initial validation.
For example, when the user is presented with the form, the default value is zero. When the min and max are set to 1 and 100, the validation doesn't happen.
Can someone let me know how to make it work in an elegant way?
Plunker link: http://plnkr.co/edit/ioraHEK63SuGMncTuHBw?p=info
export function PercentageInputFormatter() {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, vm) {
if (vm) {
var minNumber: number = 'min' in attrs ? parseFloat(attrs.min) : Number.MIN_VALUE;
var maxNumber: number= 'max' in attrs ? parseFloat(attrs.max) : Number.MAX_VALUE;
var allowFraction: boolean = 'fraction' in attrs ? attrs.fraction === 'true' : false;
vm.$parsers.push(function (value) {
return validatePercentage(value);
});
vm.$formatters.push(function (value) {
return XpressConvertionUtils.toPercentageDisplay(value, allowFraction ? 2 : 0);
});
function validatePercentage(value) {
if (value) {
var valid = !isNaN(parseFloat(value)) && isFinite(value) && parseFloat(value) >= minNumber && parseFloat(value) <= maxNumber;
if (!allowFraction)
valid = valid && value.indexOf('.') == -1;
vm.$setValidity('percentage', valid);
}
return valid ? value / 100 : undefined;
}
}
}
};
}
myApp.directive('dpInputFormatterPercentage', PercentageInputFormatter);