Reputation: 18423
I want to implement a validation attribute with parameter. In particular attribute for validating maximum date in a custom format.
<input type="datetime" ng-model="someForm.someField" name="SomeField" max-date="2016.09.11" />
There are many examples of validating directives without parameters, so I've tried to base my code on them. I've added scope and restriction to attribute only usage of the directive.
fooApp.directive('maxDate', function () {
return {
restrict: 'A',
scope: {
max: '='
},
require: 'ngModel',
link: function ($scope, element, attrs, ngModel) {
ngModel.$validators.maxDate = function (value, max) {
//Here will be validator logic
};
}
}
});
The problem is - max is always the same as value. It's not value of max-date attribute, but the value of input field. What am I doing wrong?
Upvotes: 0
Views: 142
Reputation: 125
link: function ($scope, element, attrs, ngModel) {
ngModel.$validators.maxDate = function (value, max) {
if (!!value && (value.length ==10 ) )
{
if ( new Date(max) > new Date(attrs.maxDate))
{
console.log("Date is Higher");
}
}
};
}
Can you check this.
Upvotes: 1
Reputation: 18423
It's a little bit tricky, but works:
fooApp.directive('maxDate', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, elm, attr, ctrl) {
if (!ctrl) return;
var maximumDate = 0;
attr.$observe('maxDate', function (value) {
maximumDate = value;
ctrl.$validate();
});
ctrl.$validators.maxDate = function (modelValue, viewValue) {
console.log('viewValue: ' + viewValue);
console.log('maximumDate: ' + eval(maximumDate));
return ctrl.$isEmpty(viewValue);// || viewValue.length >= minlength;
};
}
}
});
viewValue
is a value from the input, maximumDate
is a value from the attribute.
I've based it on ngMinlength directive. Here's the code of original Angular directive:
var minlengthDirective = function() {
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, elm, attr, ctrl) {
if (!ctrl) return;
var minlength = 0;
attr.$observe('minlength', function(value) {
minlength = toInt(value) || 0;
ctrl.$validate();
});
ctrl.$validators.minlength = function(modelValue, viewValue) {
return ctrl.$isEmpty(viewValue) || viewValue.length >= minlength;
};
}
};
};
Of course my directive is only an example of getting directive value in a validating directive, not working max-date attribute, but implementation of the details is simple and inessential.
Upvotes: 0
Reputation: 1431
I tried solving this. Please see below.
Template
<input type="datetime" ng-model="someForm" name="SomeField" max-date=20160911 />
2016.09.11 is NaN and 2016/09/11 is dividing the number. Not sure why they both are not treated as strings. So, I have removed the delimiter and used substrings to create the date. See below.
js
return {
restrict: 'A',
scope: {
maxDate: '='
},
require: 'ngModel',
link: function (scope, element, attrs, ngModelCtrl) {
ngModelCtrl.$validators.maxDateValidator = function (modelValue, viewValue) {
var year = scope.maxDate.toString().substring(0,4);
var month = parseInt(scope.maxDate.toString().substring(4,6))-1;
var day = scope.maxDate.toString().substring(6);
var maximumDate = new Date(year, month, day)
var enteredDate = new Date(viewValue);
console.log(maximumDate.getTime()>=enteredDate.getTime());
return maximumDate.getTime()>=enteredDate.getTime();
};
}
}
As far as your question goes, the parameters are not actually what you thought. They are the view value and model value of the model. Please see the documentation here.
Upvotes: 1
Reputation: 4793
It looks like you've typed the wrong binding in your scope. It looks for a binding called "max". You could either add your max as an attribute that would be evaluated and use the attrs. to fetch the value, or you can bind to itself using something like:
scope: {
maxDate : '='
}
As far as I can tell from your example, this should work. You could also bind using an isolated scope; e.g. date: '=maxDate'
Upvotes: 0