calendar.js

angular.module('homepage').
directive('calendar', function () {
    return {
    	controller: 'calendarController',
        restrict: 'E',
        replace: true,
        scope: {
            /**
             * @type {Object} date Object containing attribute 'date'
             */
            chosendate: '=date',
            /**
             * Object containing attributes:
             * @type {Boolean} isShowDate Show textual date
             * @type {Boolean} isShowBefore Show textual date before icon
             */
            options: '='
        },
        templateUrl: 'components/common-components/calendar/calendar.html'
    };
}).
controller('calendarController', ['$scope', '$timeout', function($scope, $timeout) {
	var options = {
		isWeekStartOnMonday: false
	};

	$scope.chosendate.date = $scope.chosendate.date instanceof Date ? $scope.chosendate.date : new Date();
	$scope.tempDate = $scope.chosendate.date;
	$scope.selectionDay = $scope.tempDate.getDate();
	$scope.isCalendarVisible = false;

	function daysInMonth(month,year) {
	    return new Date(year, month + 1, 0).getDate();
	}

	function getSelectionDate() {
		return $scope.tempDate;
	}

	function setSelectionDate(date) {
		$scope.tempDate = date;
		$scope.selectionDay = $scope.tempDate.getDate();
	}

	function setDate(date) {
		$scope.isCalendarVisible = false;
		$scope.chosendate.date = date;
	}

	function getWeekTitle(isWeekStartOnMonday) {
		if(isWeekStartOnMonday) {
			return ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'];
		}
		else {
			return ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
		}
	}

	function getCalendarItems(date) {
		if(!date) {
			date = new Date();
		}
		var year = date.getFullYear();
		var month = date.getMonth();
		var dayOfWeek = new Date(year, month, 1).getDay();
        if (options.isWeekStartOnMonday) {
            dayOfWeek =  dayOfWeek === 0 ? 7 : dayOfWeek;
        }
        else {
            dayOfWeek =  dayOfWeek === 0 ? dayOfWeek : dayOfWeek + 1;
        }
		var totalDays = daysInMonth(month, year);

		var items = [];
		var weeks = [];
		var week  = [];
		var weekindex = 0;
		var paddingStr = '';

		// add padding before items
		for(var i = 0; i < dayOfWeek - 1; i++) {
			items.push(paddingStr);
			week.push(paddingStr);
		}

		for(var j = 1; j <= totalDays; j++) {
			week.push(j);
			items.push(j);
			if(items.length%7 === 0) {
				weeks[weekindex] = week;
				week = [];
				weekindex++;
			}
		}

		// add padding after items
		var listsize = items.length;
		listsize = listsize > 28 ? 35 - listsize : listsize;
		for(var k = 0; k < listsize; k++) {
			items.push(paddingStr);
			week.push(paddingStr);
		}
		weeks[weekindex] = week;
		week = [];

		return weeks;
	}

	$scope.toggleCalendar = function () {
		$scope.isCalendarVisible = !$scope.isCalendarVisible;
	};

	$scope.setDateMonth = function($event, index) {
		$event.stopPropagation();

		var date = getSelectionDate();
		date.setMonth(date.getMonth() + index);
		setSelectionDate(date);
		$scope.weeks = getCalendarItems(date);
	};

	$scope.dateClicked = function($event, day) {
		$event.stopPropagation();

		// Set indicator that date is selected by user not the default
		$scope.chosendate.isDateSet = true;

		// build date
		var date = getSelectionDate();
		date.setDate(day);

		// update date string
		setDate(date);
	};

	$scope.weekTitle = getWeekTitle(options.isWeekStartOnMonday)
	$scope.weeks = 	getCalendarItems();
}]);