I'm trying to wrap an <input>
in a directive so that I can handle date validation and convert it from a string to an actual Date
object and maintain the Date
version in the original scope. This interaction is working as expected. But the ng-pattern
on the <input>
element isn't acting right. It is never invalidating the <input>
, regardless of what is entered.
HTML
<pl-date date="date"></pl-date>
JS
.directive("plDate", function (dateFilter) {
return {
restrict: 'E',
replace: true,
template: '<input id="birthDateDir" name="birthDate" type="text" ng-pattern="{{getDatePattern()}}" ng-model="dateInput">',
scope: {
date: '='
},
link: function (scope) {
scope.dateInput = dateFilter(scope.date, 'MM/dd/yyyy');
scope.$watch('date', function (newVal) {
if (newVal !== scope.tmp) {
if (!newVal) {
scope.dateInput = null;
} else {
scope.dateInput = dateFilter(scope.date, 'MM/dd/yyyy');
}
}
});
scope.getDatePattern = function () {
var exp = '/';
// Removed for brevity
exp += '/';
return exp;
};
scope.$watch('dateInput', function (newVal) {
if (newVal !== null) {
scope.date = new Date(newVal);
scope.tmp = scope.date;
}
});
}
};
JSFiddle here: https://jsfiddle.net/e5qu5rgy/1/
Any help at all is greatly appreciated!
So it looks like the problem can be fixed by changing the link
function for the directive to be a controller
function instead, as follows
.directive("plDate", function (dateFilter) {
return {
restrict: 'E',
replace: true,
template: '<input id="birthDateDir" name="birthDate" class="formField" type="text" ng-pattern="{{getDatePattern()}}" ng-model="dateInput">',
scope: {
date: '='
},
controller: function ($scope, $element, $attrs) {
$scope.dateInput = dateFilter($scope.date, 'MM/dd/yyyy');
$scope.$watch('date', function (newVal) {
if (newVal !== $scope.tmp) {
if (!newVal) {
$scope.dateInput = null;
} else if (newVal.toString() !== "Invalid Date") {
$scope.dateInput = dateFilter($scope.date, 'MM/dd/yyyy');
}
}
});
$scope.getDatePattern = function() {
var exp = '/';
// Months with 31 days
exp += '^(0?[13578]|1[02])[\/.](0?[1-9]|[12][0-9]|3[01])[\/.](18|19|20)[0-9]{2}$';
//Months with 30 days
exp += '|^(0?[469]|11)[\/.](0?[1-9]|[12][0-9]|30)[\/.](18|19|20)[0-9]{2}$';
// February in a normal year
exp += '|^(0?2)[\/.](0?[1-9]|1[0-9]|2[0-8])[\/.](18|19|20)[0-9]{2}$';
// February in a leap year
exp += '|^(0?2)[\/.]29[\/.](((18|19|20)(04|08|[2468][048]|[13579][26]))|2000)$';
exp += '/';
return exp;
};
$scope.$watch('dateInput', function (newVal) {
if (newVal !== null) {
$scope.date = new Date(newVal);
$scope.tmp = $scope.date;
}
});
}
};
});
Before going into production, the controller
needs to be changed over to use an array for its arguments to protect against minification.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.