I would like to know what is the best way to keep the Display string value and the actual internal value of a directive consistent.
In the code below, I have a time input, where user can input a string representing the time ("00:00"), the directive calculate the actual value and set it accordingly every time user change the string value.
However, as the actual value is exposed and can be changed by other component, I need some way to make the string value consistent with the actual value.
$watch is one solution but I then need to disable the watch when in onChange() method. So, I wonder if there is a better way of doing this.
[EDIT]: The reason I am using ng-blur is due to the validation in case the string value is not a valid format, it is reverted back to the actual value.
Cheers,
Jsfiddle: https://jsfiddle.net/minhnq013/v5rax0vk/3/
angular.module('myapp', [])
.directive('timeInput', function () {
return {
restrict: 'E',
template: '<input type="text" ng-model="ctrl.strValue" ng-blur="ctrl.onChange()"/><span ng-bind="ctrl.value"></span>',
scope: {
'value': '='
},
controller: Controller,
controllerAs: 'ctrl',
bindToController: true
};
function Controller() {
var ctrl = this;
ctrl.value = ctrl.value || 0;
ctrl.strValue = "00:00";
/**
* Called when the UI determine user input value has change,
* Set the internal value to be same as user input text value.
**/
function onChange() {
var hour = ctrl.strValue.substr(0, 2);
var minute = ctrl.strValue.substr(3);
var dateObj = new Date(ctrl.value);
var regex = new RegExp("^\\d{2}:\\d{2}$");
// If format is not valid, revert to last value
if (!ctrl.strValue.match(regex)) {
ctrl.strValue = ("0"+dateObj.getUTCHours()).slice(-2) + ":" + ("0"+dateObj.getUTCMinutes()).slice(-2);
return;
}
dateObj.setUTCHours(hour);
dateObj.setUTCMinutes(minute);
ctrl.value = dateObj.getTime();
}
ctrl.onChange = onChange;
function filterText() {
}
}
});