2

I am building a directive that adds some logic to the input['date'] element. This is what I have right now:

app.directive('calendarInput', function() {
    'use strict';
    return {
        template : '<input type="date"' +
                            'ng-model="calendarInput"' +
                            'min="{{min}}"' +
                            'max="{{max}}" />'
        replace: true,
        scope: {
            startdate : '@',
            enddate : '@',
            calendarInput: '='
        },
        restrict: 'A',
        link: function (scope, element, attrs) {
            scope.$watch('startdate', function (val) {
                if (val) {
                    var date = new Date(val);
                    scope.min = date.toIsoString().split('T')[0];
                }
            });
            scope.$watch('enddate', function (val) {
                if (val) {
                    var date = new Date(val);
                    scope.max = date.toIsoString().split('T')[0];
                }
            });
        }
    };
});

The idea is to reuse this directive. Sometimes there will be a startdate only, sometimes a enddate only. Like so:

<div calendar-input="item.birthday" enddate="'1990-01-01'"></div>

Unfortunately this always results in an invalid form with the class ng-invalid-min. It's because I don't supply the startdate parameter.

How can I make min or max values optional?

Edit: I am using Angular 1.3.9

2
  • which version of angular js you are using? Commented Jan 20, 2015 at 9:17
  • @Sanjiv it is Angular 1.3.9 Commented Jan 20, 2015 at 9:36

2 Answers 2

1

Figured out a way to compile max and min attributes on demand.

app.directive('calendarInput', function($compile) {
    'use strict';
    return {
        template : '<input type="date" class="datepicker" ng-model="omdCalendarInput" />',
        replace: true,
        scope: {
            startdate : '@',
            enddate : '@',
            calendarInput: '='
        },
        restrict: 'CA',
        link: function (scope, element, attrs) {

            var dateInput = element.find('input') // <----

            scope.$watch('startdate', function (val) {
                if (val) {
                    var date = new Date(val);
                    scope.min = date.toIsoString().split('T')[0];
                    if (!dateInput.attr('min')) { // <----
                        dateInput.attr('min', '{{min}}'); // <----
                        $compile(dateInput)(scope); // <----
                    }
                }
            });
            scope.$watch('enddate', function (val) {
                if (val) {
                    var date = new Date(val);
                    scope.max = date.toIsoString().split('T')[0];
                    if (!dateInput.attr('max')) { // <----
                        dateInput.attr('max', '{{max}}'); // <----
                        $compile(dateInput)(scope); // <----
                    }
                }
            });
        }
    };
});

Relevant Link


EDIT: Improved the code above. Also I'm marking this as the correct answer, since nobody else has a solution.

Sign up to request clarification or add additional context in comments.

Comments

0

This is great, just what I needed. Thank you.

Nit-pick - might want to change:

scope.min = date.toIsoString().split('T')[0];

to

scope.min = $format('date')(date, 'yyyy-MM-dd');

to make it more angularish.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.