2

I's using AngularJS and AngularJS bootstrap in my page. I have a date picker directive that looks like this:

    <div class="form-group {{dateStatus.class}}">
        <p class="input-group">
            <input type="text" id="inpDate" class="form-control" 
                   datepicker-popup="dd-MMMM-yyyy" ng-model="task.date" 
                   is-open="datePickerStatus.isOpen" min-date="minDate" 
                   datepicker-options="dateOptions" ng-required="true" 
                   close-text="Close" placeholder="Due date" 
                   ng-change="checkDateValidity()"
            />
            <span class="input-group-btn">
                <button type="button" class="btn btn-default" 
                        ng-click="openDatePicker($event)"
                >
                    <i class="glyphicon glyphicon-calendar"></i>
                </button>
            </span>
        </p>
    </div>

To validate the date input, in my controller I have the following function:

        $scope.checkDateValidity = function(){
        var date,
            isValid,
            taskDate;
        taskDate = $scope.task.date;
        date = new Date(taskDate);
        isValid = !isNaN(date);
        if(isValid) {
            $scope.addButtonState.isOk = true;
            $scope.dateStatus.class = '';
        }
        else{
            $scope.addButtonState.isOk = false;
            $scope.dateStatus.class = 'has-error';
        }
    }

everything works fine for checking if the date inserted is valid, but the problem is that when the date input is left blank(or changed from a valid state to blank) I want it to be acceptable too, but since both empty input and invalid date are undefinedI don't know how to declare between the cases.

I also thought of reading the input text directly like this:

document.getElementById('inpDate').value

but the ng-change is fired when the value is changed and I'm left with the previous value which is useless now...

thanks for your time and response.

3 Answers 3

7

A much better way of validating is using a directive to add a Validation Rule.

.directive("validateDate", function() {
     return {
         require: 'ngModel',
         link: function(scope, elm, attrs, ctrl) {
             ctrl.$validators.validateDate = function(modelValue, viewValue) {
                 if(!isNaN(modelValue) || ctrl.$isEmpty(modelValue)){
                     return true;
                 }
                 return false;
             };
         }
     };
 })

then you just need to add validate-date to the input tag and the validation will mark the input as valid if it is !isNaN (when the date is a number OR is empty)

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

1 Comment

But the ng-change still triggered regardless of the result. Should we move all the change event logic to the validation directive instead?
2

You can easily validate #inpDate value by binding validator callback to both change and keyup events, then when your callback triggered you can check the validity of your input.

$timeout(function(){        
    angular
        .element(document.getElementById('inpDate'))
        .bind('keyup change', function(){
            var inputValue,
                customDate,
                isValid;

            inputValue = this.value;
            if(inputValue != ''){
                customDate = new Date(inputValue);
                isValid = !isNaN(customDate);

                if(isValid){
                    console.log('Valid');
                    // do something
                }
                else{
                    console.log('Invalid');
                    // do something else
                }
            }
            else{
                console.log('Empty');
                // do something else
            }
        });
}, 400);

Please make sure that your have injected $timeout in your controller.

2 Comments

it is not recommended to access form elements directly from the controller
@Kunal Yes, But I have just fixed a specific problem. The question's author can build a directive and use this method in that.
-1

If you want to validate like that, then you can use

if(document.getElementById('inpDate').value === "" ){
            $scope.addButtonState.isOk = true;
            $scope.dateStatus.class = '';
}

this at the beginning of the $scope.checkDateValidity function

2 Comments

The OP has already mentioned that, he has tried this method and it's not working.
Else validate $scope.task.date like that, I don't understand what is not working here

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.