Reputation: 7195
I am trying to create a directive that formats a decimal value to a time value h:mm
. If a user enters a time value the model should be updated with the decimal representation. If a user enters a decimal value his input should be replaced with the formatted value.
I am using the directive as follows:
<input type="text" hour-input ng-model="vm.hours"/>
Here is the relevant code:
app.directive('hourInput', hourInput);
function hourInput() {
var directive = {
link: link,
restrict: 'A',
require: 'ngModel'
};
return directive;
function link(scope, element, attrs, ngModelController) {
// model -> view
ngModelController.$formatters.push(function (value) {
return formatTime(value);
});
// view -> model
ngModelController.$parsers.push(function (value) {
var result;
if (!/^\d?[\d,\.]*$/.test(value)) {
result = parseTime(value);
} else {
result = parseFloat(value);
}
return result;
});
}
}
function parseTime(value) {
// code removed for brevity
return hours + minutes / 60;
}
function formatTime(value) {
// code removed for brevity
return result;
}
Here is the plunker. The interaction with the model is working. However the formatted time is not updated in the UI.
Upvotes: 1
Views: 120
Reputation: 751
ngModelController.$parsers
parses your value with every keystroke. Since you do not know when the user is ready with entering the value, you can't really parse the value on every update.
Assuming you want to allow the values
the parser is not the way you want to go. I think that when you attach the function on the blur or change event you get the desired behavior.
Something like
element.bind('blur', function () {
element.val(formatTime(element.val()));
});
Upvotes: 1