Create date-range selector with angularjs directives

Directives are most important components in angularjs application. Although Angularjs ships wide range of directives. But sometimes you will need to create your custom directives. So, Lets started a very important directive ‘Date-Range-Selector’ directives.

we will use bootstrap daterangepicker, momentjs

So, lets start custom directives

angular.module('app').
.directive('dateRange',
    function() {
        return {
            restrict: 'E',
            scope: {
                selectedDateRange: '=selectedDateRange',
                activeCalendar: "=activeCalendarModel",
                day: "@day",
                week: "@week",
                month: "@month",
                dateRange: "@dateRange",
                dateChangedCallback: '=',
                afterLoadCallback: '='
 
            },
            templateUrl: 'date_range.html',
            controller: 'DateRangeCtrl',
            link: function (scope, element, attrs) {
                //setup default values for the attributes if not defined
                if(attrs.day == undefined ){attrs.day = '1';}
                if(attrs.week == undefined ){attrs.week = '1';}
                if(attrs.month == undefined ){attrs.month = '1';}
                if(attrs.dateRange == undefined ){attrs.dateRange = '1';}
 
                if (!scope.activeCalendar) {
                    if(attrs.activeCalendar == undefined){ attrs.activeCalendar = 'day'; }
                    scope.activeCalendar = attrs.activeCalendar;
                }
 
                if (scope.afterLoadCallback) {
                    scope.afterLoadCallback();
                }
            }
        }
    }
    )

All parameter are self explanatory 🙂
we have set controller as ‘DateRangeCtrl’.Lets create DateRangeCtrl

angular
    .module('app.controllers')
    .controller('DateRangeCtrl',
    function ($scope, $rootScope, $http, $location, $cookies, $timeout) {
        $rootScope.dateSelectionCtrlScope = $scope;
 
        $scope.loadingChangeDateRange = false;
        $(".date-separator").daterangepicker({
                applyClass: 'btn-primary',
                startDate: moment().startOf('month'),
                endDate: moment().endOf('month'),
                opens: "right",
                parentEl: "#date-range-selection"
            }, function(start, end) {
                $scope.selected.dateRange.start = start.format('YYYY-MM-DD');
                $scope.selected.dateRange.end = end.format('YYYY-MM-DD');
                $scope.loadingChangeDateRange = true;
                $scope.changeDateRange();
            }
        );
 
        $(document).on('click', '.applyBtn' , function () {
            if ($scope.loadingChangeDateRange) {
                $scope.loadingChangeDateRange = false;
            } else {
                $scope.selected.dateRange.start = moment($('#start_date').html()).format('YYYY-MM-DD');
                $scope.selected.dateRange.end = moment($('#end_date').html()).format('YYYY-MM-DD');
                $scope.changeDateRange();
            }
        });
 
        $scope.selected = [];
 
 
        //****************    dateRange calendar ***************
        $scope.selected.dateRangeString = [];
        $scope.selected.dateRange = [];
 
        if ($scope.activeCalendar == 'dateRange') {
            $scope.selected.dateRangeString.start = moment($scope.selectedDateRange.start).format("MMM DD, YYYY");
            $scope.selected.dateRangeString.end = moment($scope.selectedDateRange.end).format("MMM DD, YYYY");
            $scope.selected.dateRange.start = moment($scope.selectedDateRange.start).format("YYYY-MM-DD");
            $scope.selected.dateRange.end = moment($scope.selectedDateRange.end).format("YYYY-MM-DD");
        } else {
            $scope.selected.dateRangeString.start = moment($scope.selectedDateRange.start).startOf('month').format("MMM DD, YYYY");
            $scope.selected.dateRangeString.end = moment($scope.selectedDateRange.start).endOf('month').format("MMM DD, YYYY");
            $scope.selected.dateRange.start = moment($scope.selectedDateRange.start).startOf('month').format("YYYY-MM-DD");
            $scope.selected.dateRange.end = moment($scope.selectedDateRange.start).endOf('month').format("YYYY-MM-DD");
        }
 
        $scope.changeDateRange = function changeDateRange(){
            $scope.selected.dateRangeString.start = moment($scope.selected.dateRange.start).format("MMM DD, YYYY");
            $scope.selected.dateRangeString.end = moment($scope.selected.dateRange.end).format("MMM DD, YYYY");
            $scope.selectedDateRange.start = moment($scope.selected.dateRange.start).format("YYYY-MM-DD");
            $scope.selectedDateRange.end = moment($scope.selected.dateRange.end).format("YYYY-MM-DD");
            $scope.selectedDateRange.random = Math.random();
            $scope.$apply();
            dateChanged();
        }
 
        //**************************************************
 
        $scope.activateCalendar = function activateCalendar(activeCalendar){
            $scope.activeCalendar = activeCalendar;
            switch ($scope.activeCalendar){
                case 'dateRange':
                    $(".date-separator").daterangepicker('show');
 
                    $timeout(function () {
                        $(".date-separator").click();
                    });
                    break;
            }
 
        }
 
        $scope.separatorClick = function separatorClick(){
            $(".date-separator").click();
        }
 
        $scope.getActiveCalendar = function() {
            return $scope.activeCalendar;
        }
 
        var dateChanged = function() {
            if ($scope.dateChangedCallback != null) {
                $scope.dateChangedCallback($scope.selectedDateRange);
            }
        }
 
    })
;

now time to setup template for DateRange directives

<span class="date-selection-wrapper">
    <div class="btn-group btnGroupWeek pull-right">
        <button type="button" class="btn tdBtn btn-default" id="dateRangeBtn" ng-click="activateCalendar('dateRange')" ng-if="dateRange!=0"  ng-class="{tdBtnActive : activeCalendar == 'dateRange'}" ><translate>Date Range</translate></button>
    </div>
    <div class="btn-group date-range-item pull-right" style="margin-left: 30px" id="date-range-selection" ng-show="activeCalendar == 'dateRange'">
        <button type="button" class="btn tdBtn btn-default" id="start_date" ng-click="separatorClick()">{{selected.dateRangeString.start}}</button>
        <button type="button" class="btn tdBtn btn-default date-separator">-</button>
        <button type="button" class="btn tdBtn btn-default" id="end_date" ng-click="separatorClick()">{{selected.dateRangeString.end}}</button>
    </div>
</span>

Now your directives ready to use your main template. You can use like this

<date-range selected-date-range="selectedDateRange" day="1" week="1" month="0" date-range="1" active-calendar="date-range" active-calendar-model="activeCalendarModel"></date-range>

Leave a Reply