Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 57 additions & 81 deletions angular-date-picker.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,27 @@
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define([ 'module', 'angular' ], function (module, angular) {
module.exports = factory(angular);
});
} else if (typeof module === 'object') {
module.exports = factory(require('angular'));
} else {
if (!root.mp) {
root.mp = {};
}

root.mp.datePicker = factory(root.angular);
}
}(this, function (angular) {
'use strict';

return angular.module('mp.datePicker', []).directive('datePicker', [ '$window', '$locale', function ($window, $locale) {
'use strict';

/*
Branch Commit: Removed reimport of angular module causing errors
*/

angular.module('mp.datePicker', []).directive('datePicker', ['$window', '$locale', function($window, $locale) {
// Introduce custom elements for IE8
$window.document.createElement('date-picker');

var tmpl = ''
+ '<div class="angular-date-picker">'
+ ' <div class="_month">'
+ ' <button type="button" class="_previous" ng-click="changeMonthBy(-1)">&laquo;</button>'
+ ' <span>{{ months[month] }}</span> {{ year }}'
+ ' <button type="button" class="_next" ng-click="changeMonthBy(1)">&raquo;</button>'
+ ' </div>'
+ ' <div class="_days" ng-click="pickDay($event)">'
+ ' <div class="_day-of-week" ng-repeat="dayOfWeek in daysOfWeek" title="{{ dayOfWeek.fullName }}">{{ dayOfWeek.formattedDay || dayOfWeek.firstLetter }}</div>'
+ ' <div class="_day -padding" ng-repeat="day in leadingDays" data-month-offset="-1" ng-class="{ \'-disabled\': day.disabled }">{{ day.day }}</div>'
+ ' <div class="_day" ng-repeat="day in days" ng-class="{ \'-disabled\': day.disabled, \'-selected\': (day.day === selectedDay), \'-today\': (day.day === today) }">{{ day.day }}</div>'
+ ' <div class="_day -padding" ng-repeat="day in trailingDays" data-month-offset="1" ng-class="{ \'-disabled\': day.disabled }">{{ day.day }}</div>'
+ ' </div>'
+ '</div>'
;
var tmpl = '' +
'<div class="angular-date-picker">' +
' <div class="_month">' +
' <button type="button" class="_previous" ng-click="changeMonthBy(-1)">&laquo;</button>' +
' <span title="{{ months[month].fullName }}">{{ months[month].shortName }}</span> {{ year }}' +
' <button type="button" class="_next" ng-click="changeMonthBy(1)">&raquo;</button>' +
' </div>' +
' <div class="_days" ng-click="pickDay($event)">' +
' <div class="_day-of-week" ng-repeat="dayOfWeek in daysOfWeek" title="{{ dayOfWeek.fullName }}">{{ dayOfWeek.firstLetter }}</div>' +
' <div class="_day -padding" ng-repeat="day in leadingDays" data-month-offset="-1">{{ day }}</div>' +
' <div class="_day" ng-repeat="day in days" ng-class="{ \'-selected\': (day === selectedDay), \'-today\': (day === today) }">{{ day }}</div>' +
' <div class="_day -padding" ng-repeat="day in trailingDays" data-month-offset="1">{{ day }}</div>' +
' </div>' +
'</div>';

return {
restrict: 'AE',
Expand All @@ -43,31 +31,35 @@
scope: {
onDateSelected: '&',
formatDate: '=', // @todo breaking change: change to & to allow use of date filter directly
parseDate: '=', // @todo change to &
allowDate: '=',
formatDayOfWeek: '='
parseDate: '=' // @todo change to &
},

link: function ($scope, $element, $attributes, ngModel) {
link: function($scope, $element, $attributes, ngModel) {
var selectedDate = null,
days = [], // Slices of this are used for ngRepeat
months = $locale.DATETIME_FORMATS.STANDALONEMONTH.slice(0),
months = [],
daysOfWeek = [],
firstDayOfWeek = typeof $locale.DATETIME_FORMATS.FIRSTDAYOFWEEK === 'number'
? ($locale.DATETIME_FORMATS.FIRSTDAYOFWEEK + 1) % 7
: 0;
firstDayOfWeek = typeof $locale.DATETIME_FORMATS.FIRSTDAYOFWEEK === 'number' ?
($locale.DATETIME_FORMATS.FIRSTDAYOFWEEK + 1) % 7 :
0;

for (var i = 1; i <= 31; i++) {
days.push(i);
}

for (var i = 0; i < 12; i++) {
months.push({
fullName: $locale.DATETIME_FORMATS.MONTH[i],
shortName: $locale.DATETIME_FORMATS.SHORTMONTH[i]
});
}

for (var i = 0; i < 7; i++) {
var day = $locale.DATETIME_FORMATS.DAY[(i + firstDayOfWeek) % 7];

daysOfWeek.push({
fullName: day,
firstLetter: day.substr(0, 1),
formattedDay: $scope.formatDayOfWeek(day)
firstLetter: day.substr(0, 1)
});
}

Expand All @@ -80,55 +72,40 @@

var now = new Date();

$scope.today = now.getFullYear() === $scope.year && now.getMonth() === $scope.month
? now.getDate()
: null;
$scope.today = now.getFullYear() === $scope.year && now.getMonth() === $scope.month ?
now.getDate() :
null;

$scope.selectedDay = selectedDate
&& selectedDate.getFullYear() === $scope.year
&& selectedDate.getMonth() === $scope.month
? selectedDate.getDate()
: null;
$scope.selectedDay = selectedDate &&
selectedDate.getFullYear() === $scope.year &&
selectedDate.getMonth() === $scope.month ?
selectedDate.getDate() :
null;

var firstDayOfMonth = new Date($scope.year, $scope.month, 1),
lastDayOfMonth = new Date($scope.year, $scope.month + 1, 0),
lastDayOfPreviousMonth = new Date($scope.year, $scope.month, 0),
daysInMonth = lastDayOfMonth.getDate(),
daysInLastMonth = lastDayOfPreviousMonth.getDate(),
dayOfWeek = firstDayOfMonth.getDay(),
leadingDays = (dayOfWeek - firstDayOfWeek + 7) % 7 || 7, // Ensure there are always leading days to give context
checkIfDateIsAllowed = $scope.allowDate !== undefined && typeof $scope.allowDate === 'function';
leadingDays = (dayOfWeek - firstDayOfWeek + 7) % 7 || 7; // Ensure there are always leading days to give context

$scope.leadingDays = days.slice(- leadingDays - (31 - daysInLastMonth), daysInLastMonth);
$scope.leadingDays = days.slice(-leadingDays - (31 - daysInLastMonth), daysInLastMonth);
$scope.days = days.slice(0, daysInMonth);
// Ensure a total of 6 rows to maintain height consistency
$scope.trailingDays = days.slice(0, 6 * 7 - (leadingDays + daysInMonth));

// Add disabled property to days
$scope.leadingDays = getDaysWithDisabledProperty($scope.leadingDays, -1);
$scope.days = getDaysWithDisabledProperty($scope.days, 0);
$scope.trailingDays = getDaysWithDisabledProperty($scope.trailingDays, 1);

function getDaysWithDisabledProperty(days, monthOffset) {
return days.map(function(day) {
if (!checkIfDateIsAllowed) {
return {day: day, disabled: false};
}
return {day: day, disabled: !$scope.allowDate(new Date($scope.year, $scope.month + monthOffset, day))};
});
}
}

// Default to current year and month
setYearAndMonth(new Date());

if (ngModel) {
ngModel.$render = function () {
selectedDate = ngModel.$viewValue
? $scope.parseDate
? $scope.parseDate(ngModel.$viewValue)
: new Date(ngModel.$viewValue)
: null;
ngModel.$render = function() {
selectedDate = ngModel.$viewValue ?
$scope.parseDate ?
$scope.parseDate(ngModel.$viewValue) :
new Date(ngModel.$viewValue) :
null;

if (selectedDate && !isNaN(selectedDate)) {
setYearAndMonth(selectedDate);
Expand All @@ -139,12 +116,12 @@
};
}

$scope.changeMonthBy = function (amount) {
$scope.changeMonthBy = function(amount) {
var date = new Date($scope.year, $scope.month + amount, 1);
setYearAndMonth(date);
};

$scope.pickDay = function (evt) {
$scope.pickDay = function(evt) {
var target = angular.element(evt.target);

if (target.hasClass('_day')) {
Expand All @@ -161,9 +138,9 @@

if (ngModel) {
ngModel.$setViewValue(
$scope.formatDate
? $scope.formatDate(selectedDate)
: selectedDate.toLocaleDateString()
$scope.formatDate ?
$scope.formatDate(selectedDate) :
selectedDate.toLocaleDateString()
);
}

Expand All @@ -173,5 +150,4 @@
}
};
}])
.name; // pass back as dependency name
}));
.name; // pass back as dependency name