<!DOCTYPE html>
<html ng-app="drpc">

  <head>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet" data-semver="3.1.1" data-require="bootstrap-css@3.1.1" />
    <link data-require="font-awesome@*" data-semver="4.0.3" rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" />
    <script src="http://code.angularjs.org/1.2.13/angular.js" data-semver="1.2.13" data-require="angular.js@*"></script>
    <script src="http://code.jquery.com/jquery-2.0.3.min.js" data-semver="2.0.3" data-require="jquery@*"></script>
    <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js" data-semver="3.1.1" data-require="bootstrap@*"></script>
    <script data-require="moment.js@*" data-semver="2.5.1" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.5.1/moment.js"></script>
    <link rel="stylesheet" href="style.css" />
    <link rel="stylesheet" href="checkbox.css" />
    <script src="drpc.js"></script>
    <meta charset="utf-8" />
    <title>AngularJS DRPC app</title>
  </head>

  <body>
    <div ng-controller="calendars">
      <div ng-repeat="cal in calendars | reverse" class="calendar cal{{$index}}">
        <div class="calendar-date">
          <table class="table-condensed">
            <thead>
              <tr>
                <th ng-class="{prev:$first}" ng-click="prev()">
                  <i ng-if="$first" class="fa fa-arrow-left icon-arrow-left glyphicon glyphicon-arrow-left"></i>
                </th>
                <th colspan="5" class="month">{{ cal.month | toFormat: "MMM, YYYY" }}</th>
                <th ng-class="{next:$last}" ng-click="next()">
                  <i ng-if="$last" class="fa fa-arrow-right icon-arrow-right glyphicon glyphicon-arrow-right"></i>
                </th>
              </tr>
              <tr>
                <th>Su</th>
                <th>Mo</th>
                <th>Tu</th>
                <th>We</th>
                <th>Th</th>
                <th>Fr</th>
                <th>Sa</th>
              </tr>
            </thead>
            <tbody>
              <tr ng-repeat="(rIndex, row) in cal.cal">
                <td ng-class="{selDate: isSelected(col), 
								   selCompDate: isCompSelected(col), 
								   available: col.isValid(),
								   inRange: isinRange(col),
								   inCompRange: isinCompRange(col)}" ng-repeat="(cIndex, col) in row" ng-click="select(col)" ng-mouseover="hover(col)"> 
						{{ cal.cal[rIndex][cIndex] | toFormat: 'DD' }}
					</td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
      <div  class="container">
        	<form action="">

	<!-- range: -->
	<div class="row">
		<label for="daterange">Date Range:</label>
		<select ng-model="firstRange" class="form-control" ng-options="r.name for r in ranges" name="daterange" id="daterange">
		</select>
	</div>

	<div class="row">
		<label for="start">From:</label>
		<label for="end">To:</label>
	</div>
	<div class="row">
		<button type="text" class="form-control disabled" ng-click="restart(0)" id="start">{{ startDate | toFormat: 'DD MMM, YYYY' }}</button>

		<button type="text" class="form-control disabled" ng-click="restart(1)" id="end">{{ endDate | toFormat: 'DD MMM, YYYY' }}</button>
	</div>
	
	<!-- compare -->
	<div class="row">
		<span class="checkbox-bright">
			<input ng-model="compare" type="checkbox" id="brightCB">
			<label for="brightCB">Compare to:</label>
		</span>
		<select ng-model="firstCompare" class="form-control" ng-options="cr.name for cr in compareRanges" name="comparerange" id="comparerange" ng-disabled="!compare">
		</select>
	</div>

	<div class="row">
		<label for="start-compare">From:</label>
		<label for="end-compare">To:</label>
	</div>
	<div class="row">
		<button type="text" class="form-control disabled" ng-click="restart(2)" id="start-compare">
			{{ startCompare | toFormat: 'DD MMM, YYYY' }}
		</button>

		<button type="text" class="form-control disabled" ng-click="restart(3)" id="end-compare">
			{{ endCompare | toFormat: 'DD MMM, YYYY' }}
		</button>
	</div>

	</form>
      </div>
    </div>
    <script src="drpc.js"></script>
  </body>

</html>
/**
* drpc Module
*
* DRPC stands for date-range picker & compare
* module builds and controls html for a rangepicker
* and allows for comparison of two or more dates
*/
angular.module('drpc', [])
 
    .filter('toFormat', function() {
        return function(dt, tmp) {
            if (dt.isValid()) {
                return dt.format(tmp ? tmp : 'DD');
            } else {
                return "";
            }
             
        }
    })
 
    .filter('reverse', function() {
        return function(items) {
            return items.slice().reverse();
        }
    })
 
    .controller('calendars', function($scope) {
        $scope.months = 3;
        $scope.calendars = [
            {cal: [], month: 0},
            {cal: [], month: 0},
            {cal: [], month: 0}
        ];
 
        $scope.startDate = moment().startOf('day').subtract('month', 1);
        $scope.endDate = moment().startOf('day');
 
 
        $scope.startCompare = moment(null);
        $scope.endCompare = moment(null);
 
 
        $scope.selectFirst = true;
        $scope.compare = false;
 
 
 
        $scope.ranges = [
            {'name': 'Last Month', 'date': moment().startOf('day').subtract('month', 1) },
            {'name': 'Last Week', 'date': moment().startOf('day').subtract('day', 7) },
            {'name': 'Yesterday', 'date': moment().startOf('day').subtract('day', 1)},
            {'name': 'Custom', 'date': null }
        ];
        $scope.firstRange = $scope.ranges[1];
 
        $scope.$watch('firstRange', function(newStart) {
            //
            if (newStart.date) {
                $scope.endDate = moment().startOf('day');
                $scope.startDate = newStart.date;
            }
             
        });
 
 
        $scope.compareRanges = [
            {'name': 'Previous Period', 'date': 'previous' },
            {'name': 'Last Month', 'date': 'month' },
            {'name': 'Last Year', 'date': 'year'},
            {'name': 'Custom', 'date': null }
        ];
 
 
        $scope.$watch('firstCompare', function(newValue) {
            if (newValue && $scope.compare) {
                $scope.endCompare = $scope.startDate.clone().subtract('day', 1);
 
                if (newValue.date == 'previous') {
                    var range = $scope.endDate - $scope.startDate;
                    $scope.startCompare = moment( $scope.endCompare - range );
                } else if (newValue.date == 'month') {
                    $scope.startCompare = $scope.startDate.clone().subtract('month', 1);
                } else if (newValue.date == 'year') {
                    $scope.startCompare = $scope.startDate.clone().subtract('year', 1);
                    $scope.endCompare = $scope.endDate.clone().subtract('year', 1);
                }
 
            }
        });
 
 
        $scope.restart = function(pos) {
            if (pos < 2) {
                $scope.compare = false;
                $scope.startCompare = moment(null);
                $scope.endCompare = moment(null);
            } else {
                $scope.compare = true;
            }
 
 
            if (pos % 2 === 0) {
                $scope.selectFirst = true;
            } else {
                $scope.selectFirst = false;
            }
 
 
        }
 
 
 
        $scope.$watch('compare', function(newValue) {
            if (newValue) {
                $scope.firstCompare = $scope.compareRanges[0];
            }
        })
 
 
        $scope.isSelected = function(m) {
            return m.isSame($scope.startDate) || m.isSame($scope.endDate) ||
                (m.isAfter($scope.startDate) && m.isBefore($scope.endDate));
        }
 
        $scope.isCompSelected = function(m) {
            return m.isSame($scope.startCompare) || m.isSame($scope.endCompare) ||
                (m.isAfter($scope.startCompare) && m.isBefore($scope.endCompare));
        }
 
        $scope.toggleSelect = function() {
            $scope.selectFirst = ($scope.selectFirst ? false: true);
        }
 
 
 
        // hover functionality
        $scope.hoverDate = moment(null);
        $scope.hoverCompDate = moment(null);
 
        $scope.isinRange = function(m) {
            return ( (m.isAfter($scope.startDate) && m.isBefore($scope.hoverDate)) ||
                     (m.isAfter($scope.hoverDate) && m.isBefore($scope.startDate)) )
        }
 
        $scope.isinCompRange = function(m) {
            return ( (m.isAfter($scope.startCompare) && m.isBefore($scope.hoverCompDate)) ||
                     (m.isAfter($scope.hoverCompDate) && m.isBefore($scope.startCompare)) )
        }
 
        $scope.hover = function(m) {
            if (!$scope.selectFirst) {
                if (!$scope.compare) {
                    $scope.hoverDate = m;
                } else {
                    $scope.hoverCompDate = m;
                }              
            }
 
        }
 
         
        $scope.select = function(m) {
            if (m.isValid()) {         
                 
                if (!$scope.compare) {
                    // mark custom
                    $scope.firstRange = $scope.ranges[3];
 
 
                    // set values
                    var start = $scope.startDate;
                    var end = $scope.endDate;
                } else {
                    // mark custom
                    $scope.firstCompare = $scope.compareRanges[3];
 
                    // set values
                    var start = $scope.startCompare;
                    var end = $scope.endCompare;
                }
 
 
                // calculate
                if ($scope.selectFirst) {
                    end = moment(null);
                    start = m;
 
                } else {
                    if (m.isBefore(start)) {
                        end = start;
                        start = m;
                    } else {
                        end = m;
                    }
                     
                }
 
                // assign them back
                if (!$scope.compare) {
                    $scope.startDate = start;
                    $scope.endDate = end;
                } else {
                    $scope.startCompare = start;
                    $scope.endCompare = end;
                }
 
 
                $scope.toggleSelect();
                 
            }
        }
 
        $scope.prev = function() {
            for (var c = 0; c < $scope.calendars.length; c++) {
                $scope.calendars[c].month.subtract('month', 1);
                // re-build calendars
                $scope.buildCalendar($scope.calendars[c]);
            }
        }
 
        $scope.next = function() {
            for (var c = 0; c < $scope.calendars.length; c++) {
                $scope.calendars[c].month.add('month', 1);
                // re-build calendars
                $scope.buildCalendar($scope.calendars[c]);
            }          
        }
 
        // builds the calendars
        $scope.buildCalendar = function(date) {
            var firstDay = moment([date.month.year(), date.month.month(), 1]);
            var lastMonth = moment(firstDay).subtract('month', 1).month();
            var lastYear = moment(firstDay).subtract('month', 1).year();
 
            var nextMonth = moment(firstDay).add('month', 1).month();
 
            var daysInLastMonth = moment([lastYear, lastMonth]).daysInMonth();
            var dayOfWeek = firstDay.day();
 
            //initialize a 6 rows x 7 columns array for the calendar
            for (var i = 0; i < 6; i++) {
                date.cal[i] = [];
            }
 
            var locale = 0; // if we want to change the startday of the week...
 
            //populate the calendar with date objects
            var startDay = daysInLastMonth - dayOfWeek + locale + 1;
            if (startDay > daysInLastMonth)
                startDay -= 7;
 
            if (dayOfWeek == locale)
                startDay = daysInLastMonth - 6;
 
            var curDate = moment([lastYear, lastMonth, startDay, 0, 0]);
            for (i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = moment(curDate).add('hour', 24)) {
                if (i > 0 && col % 7 === 0) {
                    col = 0;
                    row++;
                }
 
                if  (curDate.month() == lastMonth ||
                     curDate.month() == nextMonth ) {
                    var value = moment(null);
                } else {
                    var value = curDate.clone();
                }
 
                date.cal[row][col] = value;
            }
 
        };
 
         
        // initialize for the first time
        for (var c = 0; c < $scope.calendars.length; c++) {
 
            // calculate current month
            $scope.calendars[c].month = moment().subtract('month', c);
 
            // build calendars
            $scope.buildCalendar($scope.calendars[c]);
        }
 
 
 
 
 
    });
	* {	box-sizing: border-box; }
	body { font: 14px/1.5 sans-serif; color: #222; margin: 5em;	}
	
	.calendar {
		margin-right: 20px;
		float: left;
	}

	.calendar th {
		text-align: center;
	}

	.calendar .selDate {
		background-color: darkblue;
		color: white;
	}

	.calendar .selCompDate, .inCompRange {
		background-color: orange;
		color: white;
	}

	.calendar .selDate.selCompDate, .inRange {
		background-color: lightblue;
	}

	.calendar td.available {
		cursor: pointer;
	}

	.calendar td.available:hover {
		background-color: blue;
	}


	.disabled {
		cursor: not-allowed;
		background-color: #eee;
		opacity: 1;
	}




	/* ----- */


	.container { 
		width: 40%; 
		float: left;
	}

	label {
		width: 40%; 
		margin: 5px;
		float: left;
	}

	.form-control {
		width: 40%; 
		margin: 5px;
		float: left;
	}

DRPC stands for Date Range-Picker &amp; Compare. It's build with angularJS and 
moment.js, and is inspired by Google Analytic's similar Date Range-Picker. 
.checkbox-dark input,
.checkbox-bright input,
.checkbox-star input {
  display: none;
}
.checkbox-dark label,
.checkbox-bright label,
.checkbox-star label {
  display: inline-block;
  cursor: pointer;
  position: relative;
  padding-left: 25px;
}
.checkbox-dark label:before,
.checkbox-bright label:before,
.checkbox-star label:before {
  font-family: FontAwesome;
  content: "\f0c8";
  position: absolute;
  left: 0;
  bottom: 0;
  -webkit-text-stroke: 0.45px;
  font-weight: normal;
}
.checkbox-dark input:checked + label:before,
.checkbox-bright input:checked + label:before,
.checkbox-star input:checked + label:before {
  -webkit-text-stroke: 0.45px;
  font-family: FontAwesome;
  content: "\f14a";
  font-weight: normal;
}
.checkbox-bright label:before {
  color: #0957e4;
  content: "\f096";
}
.checkbox-bright input:checked + label:before {
  color: #0957e4;
  content: "\f046";
}
.checkbox-star label:before {
  color: #f17828;
  content: "\f006";
}
.checkbox-star input:checked + label:before {
  color: #f17828;
  content: "\f005";
}