0

I am trying to implement validations for my date time picker. I have a 'From' date picker and a 'To' datepicker in an Angular partial view. I want the 'From' date picker to display error message if a past date is selected and the 'To' date picker should display error message if the selected date is before the 'From' date. The error messages are supposed to appear on selection of the date.

My HTML is :

<div>
    <form id="edit-profile" novalidate name="editReservationForm" autocomplete="off" class="form-horizontal">
        <fieldset>
            <div class="control-group">
                <label class="control-label" for="reservation.reservedFrom">Reserved From<sup>*</sup></label>
                <div class="controls input-group date" data-provide="datepicker">
                    <input type="text" class="span4" style="width:150px" name="reservedFrom" placeholder="Reserved From" ng-model="reservation.reservedFrom"
                           validator="required" required-error-message="Date is required" valid-method="watch" id="startDate" />
                    <div class="input-group-addon">
                        <span class="glyphicon glyphicon-th"></span>
                    </div>

                </div> <!-- /controls -->
            </div> <!-- /control-group -->

            <div class="control-group">
                <label class="control-label" for="reservation.reservedTill">Reserved Till<sup>*</sup></label>
                <div class="controls input-group date" data-provide="datepicker">
                    <input type="text" style="width:150px" class="span4" name="reservedTill" placeholder="Reserved Till" ng-model="reservation.reservedTill"
                           validator="required" required-error-message="Date is required" valid-method="checkErr" id="endDate" ng-change='checkErr()' />
                    <div class="input-group-addon">
                        <span class="glyphicon glyphicon-th"></span>
                    </div>
                    <span>{{errMessage}}</span>

                </div> <!-- /controls -->
            </div> <!-- /control-group -->
        </fieldset>
    </form>

</div>

Controller :

myApp.controller('editReservationController', ['$scope', '$filter', 'reservationResolved', 'pocResolved', 'accountResolved', 'reservationServices', '$location', '$state',
    function ($scope, $filter, reservationResolved, pocResolved, accountResolved, reservationServices, $location, $state) {
        $scope.reservation = new Object();
        $scope.accounts = accountResolved.data;
        $scope.pocs = pocResolved.data;
        $scope.reservation.employee = reservationResolved.data;



        $scope.updateReservation = function () {
            if ($scope.editReservationForm.$valid) {

                //TODO: fix it properly
                $scope.reservation.reservedTill = '';
                $scope.reservation.reservedFrom = '';

                $scope.reservation.reservedFrom = $('#startDate').val();
                $scope.reservation.reservedTill = $('#endDate').val();

               reservationServices.updateReservation($scope.reservation).then(function (result) {
                        $scope.data = result.data;
                        if (!result.data.error) {
                            $state.transitionTo('employeeTalentPool', {
                                id: $state.params.id
                            });
                        }
                    });

            }

        };



        $scope.cancel = function () {
            $location.path("/reservations");
        };
        $scope.checkErr = function () {
            var startDate = new Date($scope.reservation.reservedFrom),
            endDate = new date($scope.reservation.reservedTill);
            $scope.errMessage = '';


            if (startDate < new Date()) {
                $scope.errMessage = 'Start Date should be greater than or equal today';
                return false;
            }
            if (new Date(endDate) < new Date()) {
                $scope.errMessage = 'End Date should be greater than or equal today';
                return false;
            }
            if (endDate < startDate) {
                $scope.errorMsg = "End must be after start";
                return false;
            }
            return true;
        };
    }]);

I am totally new to Angular and I'm trying to understand it by doing projects. Can anyone have a check and provide a solution?

Thanks in advance...

Phoenix
  • 285
  • 9
  • 28
  • can you create a plunker out of this code and point use where exactly you are facing issue. – ngCoder Oct 19 '16 at 04:58
  • Okay, i will try to create a plunker. The validation is not happening on selection of a date. Thats the issue I am facing – Phoenix Oct 19 '16 at 05:02
  • sorry but I don't know how to create controller and call modules in plunker. – Phoenix Oct 19 '16 at 05:12
  • I can maybe show you screenshots of the page? – Phoenix Oct 19 '16 at 05:12
  • Instead of using ng-model, will it be fine if I make a controller (put ng-controller for the main
    )? I got this example from a 3rd party side with ng-model, so used it. Maybe my code is completely wrong.
    – Phoenix Oct 19 '16 at 05:25

1 Answers1

1

A different approach without displaying any error message and satisfying selection criteria as mentioned in problem statement

Here is the plunker of working solution bit slightly different from your implementation,I've used bootstrap datepicker for this example which is almost similar to datetimepicker. Hope this will give you an understanding.

In the controller we can control when and what from and to dates should be disabled on their corresponding selection.Using minDate provided by datepicker we can change the min date of To date field to From date's.

By doing this we can eliminate the display of error message and which will also satisfy your selection criteria of From & To dates.

angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('DatepickerPopupDemoCtrl', function($scope) {

    $scope.datePicker = {};
    $scope.start = new Date();
    $scope.end = new Date();

    $scope.datePicker.minStartDate = new Date();
    // $scope.datePicker.maxStartDate = $scope.end; 
    $scope.datePicker.minEndDate = $scope.start;
    //   $scope.datePicker.maxEndDate = $scope.end; //fixed date same as $scope.maxStartDate init value

    // watcher to watch the "From" date and set the min date for 'To' datepicker 
    $scope.$watch('start', function(v) {
        $scope.datePicker.minEndDate = v;
        $scope.dateOptions2.minDate = v;
    });


    $scope.dateOptions1 = {
        //dateDisabled: disabled,
        formatYear: 'yyyy',
        //  maxDate: $scope.datePicker.maxStartDate,
        minDate: $scope.datePicker.minStartDate,
        startingDay: 1
    };

    $scope.dateOptions2 = {
        //dateDisabled: disabled,
        formatYear: 'yyyy',
        //  maxDate: $scope.datePicker.maxEndDate,
        minDate: $scope.datePicker.minEndDate,
        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.open1 = function() {
        $scope.popup1.opened = true;
    };

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

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

    $scope.popup1 = {
        opened: false
    };

    $scope.popup2 = {
        opened: false
    };

});

In your HTML you can display like below

<div ng-controller="DatepickerPopupDemoCtrl">
    <h5>From Date</h5>
        <p class="input-group">
          <input type="text" 
                  class="form-control" 
                  uib-datepicker-popup="{{format}}" 
                  ng-model="start" 
                  is-open="popup1.opened" 
                  datepicker-options="dateOptions1" 
                  close-text="Close" 
                  readonly="true" />
          <span class="input-group-btn">
            <button type="button" class="btn btn-default" ng-click="open1()">
              <i class="glyphicon glyphicon-calendar"></i>
            </button>
          </span>
        </p>

        <hr>
      <h5>To Date</h5>
        <p class="input-group">
          <input type="text" 
                  class="form-control" 
                  uib-datepicker-popup="{{format}}" 
                  ng-model="end" 
                  is-open="popup2.opened" 
                  datepicker-options="dateOptions2" 
                  close-text="Close" 
                  readonly="true"/>
          <span class="input-group-btn">
            <button type="button" class="btn btn-default" ng-click="open2()">
              <i class="glyphicon glyphicon-calendar"></i>
            </button>
          </span>
        </p>

  </div>
ngCoder
  • 2,095
  • 1
  • 13
  • 22
  • If you check in my code you will see the ng-model. I am using that to post data to the API. So can I use 'reservation.reservedFrom' instead of 'start'/'end'? – Phoenix Oct 19 '16 at 05:44
  • 1
    yes you can use any object in `ng-model`,in your case as you already have `$scope.reservation ={} `object you can use `$scope.reservation.reservedFrom `and `$scope.reservation.reservedTo `instead of start and end. – ngCoder Oct 19 '16 at 06:09
  • @Phoenix did it help ? – ngCoder Oct 19 '16 at 08:55
  • Sorry I cdnt check it yet. Will do it soon and ping you :) – Phoenix Oct 19 '16 at 09:03
  • Tnx again :) Sorry for the delay – Phoenix Oct 19 '16 at 19:11
  • A quick question. var utcDate = new Date(); Im fetching current date like this. I want it in the format mm/dd/yy. how can I change it from YY/dd/mm format? – Phoenix Oct 19 '16 at 19:14
  • 1
    `uib-datepicker-popup="{{format}}" ` this line in HTML specifies the format the date should be displayed.So in your Js add you can do like this `$scope.format = 'YY/dd/mm';` Note this date format should be valid ones you can refer in angular docs for that. – ngCoder Oct 20 '16 at 04:42
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/126176/discussion-between-phoenix-and-angular-10). – Phoenix Oct 20 '16 at 04:45
  • I have retained my old date picker to know how to fix the issues. I have posted a question with all the details. Please have a check on that if you have time... https://stackoverflow.com/questions/40146903/date-picker-clears-the-selected-value-from-date-picker-text-box-if-a-date-is-not – Phoenix Oct 20 '16 at 06:26
  • I have posted another question. Please have a check if it comes in your area of expertise... :) http://stackoverflow.com/questions/40211417/how-to-put-serial-number-for-rows-in-data-table-according-to-pagination – Phoenix Oct 24 '16 at 10:08