I have some custom validation code, which includes a $formatter. (I store currency in pence for correctness, but display in pounds.pence.)
If the user types \'10\'
A little improved: Do not reformat if the value is not valid (in my case invalid text just got cleared on blur, which is bad for usability, I think).
Also, like Dark Falcon said: Formatters should be iterated backwards.
Finally do not iterate over arrays with for-in, at least not without checking hasOwnProperty() (for me the code crashed because it treated Array.find() as a formatter).
// Reformat text on blur
elements.bind('blur', function() {
if(!ngModel.$valid) {
return;
}
var viewValue = ngModel.$modelValue;
var formatters = ngModel.$formatters;
for (var i = formatters.length - 1; i >= 0; --i) {
viewValue = formatters[i](viewValue);
}
ngModel.$viewValue = viewValue;
ngModel.$render();
});
Try using ctrl.$render on blur.
elm.bind('blur', function() { ctrl.$render() });
See it in http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController.
Your controller's $modelValue is being updated properly, however, but since the blur event is happening outside of angular, it seems your $viewValue is not. How about this?
elm.bind('blur', function() {
ctrl.$viewValue = (ctrl.$modelValue / 100).toFixed(2);
ctrl.$render();
});
An alternative implementation is to trigger angular's formatters. Angular 1.5 implementation watches $modelValue for changes, and then triggers $formatters. To do this manually, one can do this
function triggerFormattersAndRender(ngModel, scope) {
/* Triggers angulars formatters, which watches for $modelValue changes */
var originalModelValue = ngModel.$modelValue;
if (originalModelValue === null) return;
ngModel.$modelValue = null;
scope.$digest();
ngModel.$modelValue = originalModelValue;
scope.$digest();
}
And then in the directive
function link(scope, elem, attrs, ngModel) {
elem.bind('blur', function() {
triggerFormattersAndRender(ngModel, scope);
});
// when we get focus, display full precision
elem.bind('focus', function() {
if (ngModel.$modelValue) {
ngModel.$setViewValue(ngModel.$modelValue.toString());
ngModel.$render();
}
})
}
10.00 === 10
true
a=10.00
console.log(a)
10
.00 don't means anything on javascript, because of this your 10.00 are becoming 10
I suggest to make the value a String so you can create the format that you want