jqueryhtmlangularjsangular-daterangepicker

Strange behaviour in angular-daterangepicker


I'm developing an Angularjs app, and using the angular-daterangepicker to fill in dates on a table.

When the App first loads, the startDate is set to the current day & the endDate for 4 days later. Then the startDate, endDate and all the dates between are displayed in a table which looks like this (and this all works fine): enter image description here

My problems arise when a user selects to change the date range (which should also refresh the table display) on applying the new date range in the picker.

If a user selects a date range which is before the 'default' range, then only the startDate and endDate get displayed in the table - so in this image, you can see i selected July 2nd to July 6th, but only these 2 dates are displayed in the table. enter image description here

If i then instead select a date range which is after the 'default' range, say for example July 23 to July 27 - then all dates from the original default range thru to July 27 get displayed (or well minus the original startDate), so it displays July 17 thru to July 27. enter image description here

I would like to think there's a much better way to iterate thru the dates between the startDate & endDate, rather than the for-loop I used... but i just couldn't find anything, as all material only seems to point to the start & end & ignores the dates between these.

You can also see ive gone overboard with resetting variables/objects to null/blank - but this doesn't seem to make any difference.

Im using Bootstrap 4.1, AngularJS 1.6.9, bootstrap-daterangepicker 3.0.3 & angular-daterangepicker 0.2.2

Any suggestions would be greatly appreciated,

My HTML code:

<div data-ng-controller="admRosController" data-ng-init="initialTable()">    
<form data-ng-submit="createRoster()" name="rosterForm" method="POST">
                <div class="form-row">
                  <div class="form-group col-md-4">
                    <label for="daterange1" class="control-label">Select Roster Dates:</label>
                    <div class="input-group">
                      <div class="input-group-prepend">
                        <div class="input-group-text"><i class="fa fa-calendar-check-o"></i></div>
                      </div>
                      <input date-range-picker type="text" class="form-control form-control-sm date-picker" id="daterange1" name="daterange1" data-ng-model="rosData.date" options="dateRangeOptions">
                    </div>
                  </div>
                </div>
                <div class="table-responsive">
                            <table class="table table-striped table-hover" data-ng-model="roster">
                                <thead class="thead-dark">
                                    <tr>
                        <th class="text-center">Date</th>
                                        <th class="text-center">Shift 1</th>
                                        <th class="text-center">Shift 2</th>
                                        <th class="text-center">Sleep Over</th>
                                    </tr>
                                </thead>
                                <tbody>
                        <tr class="text-center" data-ng-repeat="x in rosCalJ track by $index">
                        <td>{{x.date | date:'EEE, MMMM dd, yyyy'}}</td>
                                        <td><select class="form-control form-control-sm" data-ng-model="rosData.shift1[$index]" data-ng-options="x.id as x.name for x in obj"></select></td>
                                        <td><select class="form-control form-control-sm" data-ng-model="rosData.shift2[$index]" data-ng-options="x.id as x.name for x in obj"></select></td>
                                        <td><select class="form-control form-control-sm" data-ng-model="rosData.sleep[$index]" data-ng-options="x.id as x.name for x in obj"></select></td>
                                    </tr>
                    </tbody>
                            </table>
                            <!--<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#addModal">Add Staff</button>
                            <button type="button" class="btn btn-success" data-toggle="modal" data-target="#editModal">Edit Staff</button>
                            <button type="button" class="btn btn-secondary" data-toggle="modal" data-target="#deleteModal">Delete User</button>-->
                        </div>
                <div class="form-group has-feedback">
                  <label for="message">Roster Notes</label>
                  <textarea class="form-control" rows="3" id="notes" name="notes" data-ng-model="rosData.notes" placeholder=""></textarea>
                  <i class="fa fa-pencil form-control-feedback"></i>
                </div>
                <label>Shift Times:</label>
                <p><strong>Shift 1</strong> 8:30am - 4:30pm (8 hrs)<br>
                  <strong>Shift 2</strong> 9:00am - 3:00pm (6 hrs)</p>
                <br>
                <button type="submit" class="btn btn-primary">Save Roster</button>
                <button type="reset" value="Reset" class="btn btn-secondary">Clear</button>
              </form>

My Angular Controller:

var app = angular.module('myApp', ['ngRoute', 'ngStorage', 'daterangepicker'])

app.controller ("admRosController", function ($scope, $http, $location) {
        var startingDate = null;
        var endingDate = null;
        $scope.rosCal = [];
        $scope.rosData = [];

        loadingDate = function() {
            $scope.rosData.date = {
        startDate: moment(),
        endDate: moment().add(4, "days")
            };
        };

        $scope.initialTable = function() {
            loadingDate();
            startingDate = $scope.rosData.date.startDate;
            endingDate = $scope.rosData.date.endDate;
            $scope.displayTable();
        };

        $scope.dateRangeOptions = {
        locale : {
            format: 'MMMM D, YYYY'
        },
        eventHandlers : {
            'apply.daterangepicker' : function() {
                $scope.rosCal = null;  //clear the array
                                $scope.rosCalJ = null;
                                $scope.rosCal = [];
                                $scope.rosCalJ = [];
                                startingDate = null;
                                endingDate = null;
                                startingDate = $scope.rosData.date.startDate;
                                endingDate = $scope.rosData.date.endDate;
                                $scope.displayTable();
                        }
        }
    };

        $scope.displayTable = function() {
            var i = 0;
            var thisdates = null;
            //$scope.rosCal = [];
            //$scope.rosCalJ = [];
            $scope.obj = [];
            $http.get('php/rosstaff.php')
                .then(
                    function (response) {
                        $scope.obj = response.data;
                    },
                    function (response) {
                        // error handling routine
                    }
                );

                for (thisdates = startingDate; thisdates <= endingDate; thisdates = moment().add(i, "days"))
                {
                    $scope.rosCal.push({date: thisdates});
                    i++;
                }
                $scope.rosCal.push({date: endingDate})
                $scope.rosCalJ = JSON.parse(JSON.stringify($scope.rosCal));
            };

    });

UPDATE: Here's the code on Plunker... but there's an issue with it that either Jquery or Angular aren't working?? (sorry, im new to using Plunker)
Angularjs daterangepicker on Plunker


Solution

  • The issue here is not with angular daterangepicker. You are not pushing dates to rosCal array correctly. Here is the corrected plunker: https://plnkr.co/edit/n9ZwwT957yIbmtlxBN5v?p=preview.

    In the for loop where you push dates to rosCal array, this was how you updated the loop variable thisdates : thisdates = moment().add(i, "days"). moment() returns the current date. As such, after pushing the start date to the array, the value of thisdates gets set to (current date + 1) instead of (its own value + 1). I hope you understand what the mistake was.