4

I cannot allow future date in my form built in angularjs

Here is my HTML:

<div ngCloak ng-app="laurelMoney" ng-controller="myCtrl">
  <form name="userForm">
    <div class="form-group">
      <input type='date' id="trandate" class="form-control" ng-model="trandate" required ng-class="{ 'has-error' : userForm.trandate.$error }" />
      <p ng-show="userForm.trandate.$error" class="help-block">Transaction can't be in future</p>
    </div>

    <a href="#" class="btn btn-primary btn-sm btn-block" ng-click="submitForm()" type="submit">Add Transaction</a>
  </form>

And my javascript isÑ

angular.module('laurelMoney', [])
  .controller('myCtrl', function($scope) {
    var today = new Date();
    var dd = today.getDate();
    var mm = today.getMonth() + 1;
    var yyyy = today.getFullYear();
    if (dd < 10) {
      dd = '0' + dd
    }
    if (mm < 10) {
      mm = '0' + mm
    }
    today = yyyy + '-' + mm + '-' + dd;
    document.getElementById("trandate").setAttribute("max", today);
    $scope.submitForm = function() {

      if ($scope.userForm.$valid) {
        alert('our form is amazing');
      } else {
        console.log("Error");
      }

    };
  });

This is working fine when the calendar pops up. Future dates are all disabled. but i am able to manually change it to a future date in the date input box.

System is allowing submit for future dates also. How to go about this??

Plunker

Thanks.

0

1 Answer 1

5

Well, from what I could understand from your question you're simply trying to throw a error message or disallow user to select a future date, is it right? So, here you go:

Notes:

  1. Your Angular version in plunker is completely outdated, so it may not work as you expected;
  2. ngCloak should be ng-cloak;
  3. You should add name attribute in your input to validate it;
  4. Also, you could use ngSubmit to submit form, instead of ng-click.
  5. As pointed out in comments, you can disable button if the form is invalid, rather than make this check in controller;
  6. Finally, to set a date as max date (in your case today), you just have to do the following: $scope.max = new Date() and call it in your view;

Here's an complete example:

(function() {
  'use strict';

  angular
    .module('laurelMoney', [])
    .controller('myCtrl', myCtrl);

  myCtrl.$inject = ['$scope'];

  function myCtrl($scope) {
    $scope.max = new Date();
  }
})();
<!DOCTYPE html>
<html>

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
</head>

<body ng-app="laurelMoney">
  <div ng-cloak ng-controller="myCtrl">
    <form name="userForm" novalidate ng-submit="submitForm()">
      <div class="form-group" ng-class="{ 'has-error' : userForm.trandate.$error }">
        <input type="date" name="trandate" class="form-control" required max="{{max}}" ng-model="trandate">
        <p ng-if="userForm.trandate.$touched && userForm.trandate.$error.required" class="help-block">Transaction is required</p>
        <p ng-if="userForm.trandate.$error.date" class="help-block">Transaction should be a valid date</p>
        <p ng-if="userForm.trandate.$error.max" class="help-block">Transaction can't be in future</p>
      </div>
      <button type="submit" class="btn btn-primary btn-sm btn-block" ng-disabled="userForm.$invalid">Add Transaction</button>
    </form>
    <pre ng-bind="userForm.trandate.$error | json"></pre>
  </div>
</body>

</html>

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

4 Comments

this is a good code sample, though isn't your ng-class unnecessary? pretty sure you would get .ng-invalid.ng-invalid-max applied to the input[date] when it is invalid.
Well, yes, it was just a copy from the OP's plunker.
ah, right. Also, OP, you should probably have ng-submit='userForm.$valid && submitForm()' rather than checking form validity in the controller. Just keeps things all in one place. Additionally, instead of having a error logged to the console (which you're doing), you can prevent validation messages from being shown by doing <div ng-if='userForm.$invalid && userForm.$submitted'> if that's what you're trying to do.
@DanPantry, good catch, I corrected the ngClass part and also used ng-disabled to change the state of button.

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.