It is very simple using the directive! Take this as an example: JSFiddle
If you have a directive requiring ngModelController, you can easily manipulate viewValue.
ngModelController has two properties that interest us: $ modelValue and $ viewValue. $ modelValue is the value you use in scope, and $ viewValue is the one that the user sees.
ngModelController also has a $ formatters property, which is an array of formatters that convert modelValue to viewValue. Therefore, if the modelValue variable changes on the controller side, it will go through the formatter to the end, and this will change the viewValue. If you want to create your own formatter, just add it to the array!
//This formatter will convert the modelValue to display as uppercase in the viewValue ngModelController.$formatters.push(function(modelValue) { if (modelValue) { return modelValue.toUpperCase(); } });
but the $ formatters property only works when the modelValue parameter changes, so if the user enters something into the input field, the viewValue variable changes, the easiest way to handle this is to attach to the onBlur event, in which we will change the viewValue using another function provided by the ngModel controller. $ setViewValue (value) will change viewValue. If you change the viewValue in the directive, the view will not be automatically updated, so you need to call the $ rendering function provided by ngModelController
element.on('blur', function() { ngModelController.$setViewValue(convertDoubleToTimeString(ngModelController.$modelValue)); ngModelController.$render(); });
For more information about this, you can read this .
EDIT:
In this example, I did not write a parser that converts viewValue (1:30) to modelValue (1,5). So add one. I also have updated JSFiddle
ngModelController.$parsers.unshift(function(viewValue) { if (viewValue && viewValue.indexOf(':') < 0) { return viewValue; } else { return convertTimeStringToDouble(viewValue) } });
The cancellation of parsers on the $ parsers array means that it will be executed first, this is not necessary, but why not, and ??
There are other ways to not change modelValue when changing viewValue, but this is the most correct option.
An alternative would be to simply set $ viewValue directly without going through $ setViewValue ().
//ngModelController.$setViewValue(ngModelController.$modelValue.toUpperCase()); ngModelController.$viewValue = ngModelController.$modelValue.toUpperCase();
In this last line, it will not go through the usual steps going through all the parsers and validators, so this is a less ideal solution.