<!DOCTYPE html>
<html ng-app="form-example1">

  <head>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
    <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
  </head>

  <body>
    <div ng-controller="DemoCtrl">
      <form id="myForm" name="vm.myForm" class="container" style="padding:5px;">
        <div>
          <span class="small">ng-pattern can be used to explicitly define the format of the entered input, which shows up on the $error object ({{vm.myForm.email.$error}})</span>
          <div class="input-group" ng-class="{ 'has-error': (vm.myForm.email.$invalid && (vm.myForm.email.$dirty || vm.isSubmitted)) }">
            <div class="input-group-addon fixed-length-label fixed-length-label-light">Input Email</div>
            <input type="text" id="email" name="email" placeholder="Please input an email in format user@email.com" class="input primary form-control form-control-inline" ng-model="vm.record.email" ng-pattern="/^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i" />
          </div>
        </div>
        <div>
          <div class="ng-hide error-message input-group" ng-show="(vm.myForm.email.$invalid && (vm.myForm.email.$dirty || vm.isSubmitted))">
            <small class="error" ng-show="vm.myForm.email.$error.pattern">Entered input email is not of form user@email.com</small>
          </div>
        </div>
        <br/>
        <div>
          <div>
            <span class="small">When using UI Bootstrap's datepicker, validation is already added in automatically</span>
            <br/>
            <span class="small">This means that the ng-pattern ({{vm.myForm.inputDate.$error}}) won't necessarily be utilized</span>
          </div>
          <div class="input-group" ng-class="{ 'has-error': (vm.myForm.inputDate.$invalid && (vm.myForm.inputDate.$dirty || vm.isSubmitted)) }">
            <div class="input-group-addon fixed-length-label fixed-length-label-light">Input Date</div>
            
          <input type="text" class="input primary form-control form-control-inline" 
            id="inputDate" name="inputDate"
              ng-model="vm.record.inputDate" is-open="popup1.opened" datepicker-options="dateOptions" 
              uib-datepicker-popup="MM/dd/yyyy" ng-required="true" close-text="Close" 
              alt-input-formats="altInputFormats" />
          <span class="input-group-btn">
            <button type="button" class="btn btn-default" ng-click="open1()"><i class="glyphicon glyphicon-calendar"></i></button>
          </span>
          </div>
        </div>
        <div>
          <div class="ng-hide error-message input-group" ng-show="(vm.myForm.inputDate.$invalid && (vm.myForm.inputDate.$dirty || vm.isSubmitted))">
            <small class="error" ng-show="vm.myForm.inputDate.$invalid">Entered input Date is not of form MM/dd/yyyy</small>
          </div>
        </div>
        <br/>
        <div>
          <div>
            <span class="small">For a raw input, you can still use the ng-pattern though ({{vm.myForm.rawDate.$error}})</span>
          </div>
          <div class="input-group" ng-class="{ 'has-error': (vm.myForm.rawDate.$invalid && (vm.myForm.rawDate.$dirty || vm.isSubmitted)) }">
            <div class="input-group-addon fixed-length-label fixed-length-label-light">Input Date</div>
            
          <input type="text" class="input primary form-control form-control-inline" 
            id="rawDate" name="rawDate" ng-model="vm.rawDate" required ng-pattern="/^(0[1-9]|1[0-2])\/(0[1-9]|1\d|2\d|3[01])\/(19|20)\d{2}$/" />
          </div>
        </div>
        <div>
          <div class="ng-hide error-message input-group" ng-show="(vm.myForm.rawDate.$invalid && (vm.myForm.rawDate.$dirty || vm.isSubmitted))">
            <small class="error" ng-show="vm.myForm.rawDate.$invalid">Entered raw Date is not of form MM/dd/yyyy</small>
          </div>
        </div>
      </form>
    </div>
  </body>

</html>
angular.module('form-example1', ['ngAnimate', 'ngSanitize', 'ui.bootstrap']);
angular.module('form-example1').controller('DemoCtrl', function ($scope) {
  $scope.today = function() {
    $scope.dt = new Date();
  };
  $scope.today();

  $scope.clear = function() {
    $scope.dt = null;
  };

  $scope.inlineOptions = {
    customClass: getDayClass,
    minDate: new Date(),
    showWeeks: true
  };

  $scope.dateOptions = {
    dateDisabled: disabled,
    formatYear: 'yy',
    maxDate: new Date(2020, 5, 22),
    minDate: new Date(),
    startingDay: 1
  };

  // Disable weekend selection
  function disabled(data) {
    var date = data.date,
      mode = data.mode;
    return mode === 'day' && (date.getDay() === 0 || date.getDay() === 6);
  }

  $scope.toggleMin = function() {
    $scope.inlineOptions.minDate = $scope.inlineOptions.minDate ? null : new Date();
    $scope.dateOptions.minDate = $scope.inlineOptions.minDate;
  };

  $scope.toggleMin();

  $scope.open1 = function() {
    $scope.popup1.opened = true;
  };

  $scope.open2 = function() {
    $scope.popup2.opened = true;
  };

  $scope.setDate = function(year, month, day) {
    $scope.dt = new Date(year, month, day);
  };

  $scope.formats = ['dd-MMMM-yyyy', 'yyyy/MM/dd', 'dd.MM.yyyy', 'shortDate'];
  $scope.format = $scope.formats[0];
  $scope.altInputFormats = ['M!/d!/yyyy'];

  $scope.popup1 = {
    opened: false
  };

  $scope.popup2 = {
    opened: false
  };

  var tomorrow = new Date();
  tomorrow.setDate(tomorrow.getDate() + 1);
  var afterTomorrow = new Date();
  afterTomorrow.setDate(tomorrow.getDate() + 1);
  $scope.events = [
    {
      date: tomorrow,
      status: 'full'
    },
    {
      date: afterTomorrow,
      status: 'partially'
    }
  ];

  function getDayClass(data) {
    var date = data.date,
      mode = data.mode;
    if (mode === 'day') {
      var dayToCheck = new Date(date).setHours(0,0,0,0);

      for (var i = 0; i < $scope.events.length; i++) {
        var currentDay = new Date($scope.events[i].date).setHours(0,0,0,0);

        if (dayToCheck === currentDay) {
          return $scope.events[i].status;
        }
      }
    }

    return '';
  }
});
/* Styles go here */

.error-message{
  color:#a94442;
  font-style: italic;
}