764 lines
23 KiB
JavaScript
Executable File
764 lines
23 KiB
JavaScript
Executable File
'use strict';
|
|
|
|
/**
|
|
* @ngdoc overview
|
|
* @name angularBootstrapCalendarApp
|
|
* @description
|
|
* # angularBootstrapCalendarApp
|
|
*
|
|
* Main module of the application.
|
|
*/
|
|
angular
|
|
.module('mwl.calendar', [
|
|
'ui.bootstrap'
|
|
]);
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* @ngdoc service
|
|
* @name angularBootstrapCalendarApp.moment
|
|
* @description
|
|
* # moment
|
|
* Constant in the angularBootstrapCalendarApp.
|
|
*/
|
|
angular.module('mwl.calendar')
|
|
.constant('moment', window.moment);
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* @ngdoc service
|
|
* @name angularBootstrapCalendarApp.calendarHelper
|
|
* @description
|
|
* # calendarHelper
|
|
* Service in the angularBootstrapCalendarApp.
|
|
*/
|
|
angular.module('mwl.calendar')
|
|
.service('calendarHelper', ["$filter", "moment", function calendarHelper($filter, moment) {
|
|
|
|
var self = this;
|
|
|
|
function isISOWeekBasedOnLocale() {
|
|
return moment().startOf('week').day() === 1;
|
|
}
|
|
|
|
function isISOWeek(userValue) {
|
|
//If a manual override has been set in the directive, use that
|
|
if (angular.isDefined(userValue)) return userValue;
|
|
//Otherwise fallback to the locale
|
|
return isISOWeekBasedOnLocale();
|
|
}
|
|
|
|
this.getMonthNames = function(short) {
|
|
|
|
var format = short ? 'MMM' : 'MMMM';
|
|
|
|
var months = [];
|
|
for (var i = 0; i <= 11; i++) {
|
|
months.push($filter('date')(new Date(2014, i), format));
|
|
}
|
|
|
|
return months;
|
|
|
|
};
|
|
|
|
this.getWeekDayNames = function(short, useISOWeek) {
|
|
|
|
var format = short ? 'EEE' : 'EEEE';
|
|
|
|
var weekdays = [];
|
|
var startDay = isISOWeek(useISOWeek) ? 22 : 21;
|
|
for (var i = 0; i <= 6; i++) {
|
|
weekdays.push($filter('date')(new Date(2014, 8, startDay + i), format));
|
|
}
|
|
|
|
return weekdays;
|
|
|
|
};
|
|
|
|
this.eventIsInPeriod = function(eventStart, eventEnd, periodStart, periodEnd) {
|
|
|
|
return (
|
|
moment(eventStart).isAfter(moment(periodStart)) &&
|
|
moment(eventStart).isBefore(moment(periodEnd))
|
|
) || (
|
|
moment(eventEnd).isAfter(moment(periodStart)) &&
|
|
moment(eventEnd).isBefore(moment(periodEnd))
|
|
) || (
|
|
moment(eventStart).isBefore(moment(periodStart)) &&
|
|
moment(eventEnd).isAfter(moment(periodEnd))
|
|
) || (
|
|
moment(eventStart).isSame(moment(periodStart))
|
|
) || (
|
|
moment(eventEnd).isSame(moment(periodEnd))
|
|
);
|
|
|
|
};
|
|
|
|
this.getYearView = function(events, currentDay) {
|
|
|
|
var grid = [];
|
|
var months = self.getMonthNames();
|
|
|
|
for (var i = 0; i < 3; i++) {
|
|
var row = [];
|
|
for (var j = 0; j < 4; j++) {
|
|
var monthIndex = 12 - months.length;
|
|
var startPeriod = new Date(moment(currentDay).format('YYYY'), monthIndex, 1);
|
|
var endPeriod = moment(startPeriod).add(1, 'month').subtract(1, 'second').toDate();
|
|
|
|
row.push({
|
|
label: months.shift(),
|
|
monthIndex: monthIndex,
|
|
isToday: moment(startPeriod).startOf('month').isSame(moment().startOf('month')),
|
|
events: events.filter(function(event) {
|
|
return self.eventIsInPeriod(event.starts_at, event.ends_at, startPeriod, endPeriod);
|
|
}),
|
|
date: moment(startPeriod).startOf('month')
|
|
});
|
|
}
|
|
grid.push(row);
|
|
}
|
|
|
|
return grid;
|
|
|
|
};
|
|
|
|
this.getMonthView = function(events, currentDay, useISOWeek) {
|
|
|
|
var dateOffset = isISOWeek(useISOWeek) ? 1 : 0;
|
|
|
|
function getWeekDayIndex() {
|
|
var day = startOfMonth.day() - dateOffset;
|
|
if (day < 0) day = 6;
|
|
return day;
|
|
}
|
|
|
|
var startOfMonth = moment(currentDay).startOf('month');
|
|
var numberOfDaysInMonth = moment(currentDay).endOf('month').date();
|
|
|
|
var grid = [];
|
|
var buildRow = new Array(7);
|
|
var eventsWithIds = events.map(function(event, index) {
|
|
event.$id = index;
|
|
return event;
|
|
});
|
|
|
|
for (var i = 1; i <= numberOfDaysInMonth; i++) {
|
|
|
|
if (i == 1) {
|
|
var weekdayIndex = getWeekDayIndex(startOfMonth);
|
|
var prefillMonth = startOfMonth.clone();
|
|
while (weekdayIndex > 0) {
|
|
weekdayIndex--;
|
|
prefillMonth = prefillMonth.subtract(1, 'day');
|
|
buildRow[weekdayIndex] = {
|
|
label: prefillMonth.date(),
|
|
date: prefillMonth.clone(),
|
|
inMonth: false,
|
|
events: []
|
|
};
|
|
}
|
|
}
|
|
|
|
buildRow[getWeekDayIndex(startOfMonth)] = {
|
|
label: startOfMonth.date(),
|
|
inMonth: true,
|
|
isToday: moment().startOf('day').isSame(startOfMonth),
|
|
date: startOfMonth.clone(),
|
|
events: eventsWithIds.filter(function(event) {
|
|
return self.eventIsInPeriod(event.starts_at, event.ends_at, startOfMonth.clone().startOf('day'), startOfMonth.clone().endOf('day'));
|
|
})
|
|
};
|
|
|
|
if (i == numberOfDaysInMonth) {
|
|
var weekdayIndex = getWeekDayIndex(startOfMonth);
|
|
var postfillMonth = startOfMonth.clone();
|
|
while (weekdayIndex < 6) {
|
|
weekdayIndex++;
|
|
postfillMonth = postfillMonth.add(1, 'day');
|
|
buildRow[weekdayIndex] = {
|
|
label: postfillMonth.date(),
|
|
date: postfillMonth.clone(),
|
|
inMonth: false,
|
|
events: []
|
|
};
|
|
}
|
|
}
|
|
|
|
if (getWeekDayIndex(startOfMonth) === 6 || i == numberOfDaysInMonth) {
|
|
grid.push(buildRow);
|
|
buildRow = new Array(7);
|
|
}
|
|
|
|
startOfMonth = startOfMonth.add(1, 'day');
|
|
|
|
}
|
|
|
|
return grid;
|
|
|
|
};
|
|
|
|
this.getWeekView = function(events, currentDay, useISOWeek) {
|
|
|
|
var dateOffset = isISOWeek(useISOWeek) ? 1 : 0;
|
|
var columns = new Array(7);
|
|
var weekDays = self.getWeekDayNames(false, useISOWeek);
|
|
var currentWeekDayIndex = currentDay.getDay();
|
|
var beginningOfWeek, endOfWeek;
|
|
|
|
for (var i = currentWeekDayIndex; i >= 0; i--) {
|
|
var date = moment(currentDay).subtract(currentWeekDayIndex - i, 'days').add(dateOffset, 'day').toDate();
|
|
columns[i] = {
|
|
weekDay: weekDays[i],
|
|
day: $filter('date')(date, 'd'),
|
|
date: $filter('date')(date, 'd MMM'),
|
|
isToday: moment(date).startOf('day').isSame(moment().startOf('day'))
|
|
};
|
|
if (i == 0) {
|
|
beginningOfWeek = date;
|
|
} else if (i == 6) {
|
|
endOfWeek = date;
|
|
}
|
|
}
|
|
|
|
for (var i = currentWeekDayIndex + 1; i < 7; i++) {
|
|
var date = moment(currentDay).add(i - currentWeekDayIndex, 'days').add(dateOffset, 'day').toDate();
|
|
columns[i] = {
|
|
weekDay: weekDays[i],
|
|
day: $filter('date')(date, 'd'),
|
|
date: $filter('date')(date, 'd MMM'),
|
|
isToday: moment(date).startOf('day').isSame(moment().startOf('day'))
|
|
};
|
|
if (i == 0) {
|
|
beginningOfWeek = date;
|
|
} else if (i == 6) {
|
|
endOfWeek = date;
|
|
}
|
|
}
|
|
|
|
endOfWeek = moment(endOfWeek).endOf('day').toDate();
|
|
beginningOfWeek = moment(beginningOfWeek).startOf('day').toDate();
|
|
|
|
var eventsSorted = events.filter(function(event) {
|
|
return self.eventIsInPeriod(event.starts_at, event.ends_at, beginningOfWeek, endOfWeek);
|
|
}).map(function(event) {
|
|
|
|
var eventStart = moment(event.starts_at).startOf('day');
|
|
var eventEnd = moment(event.ends_at).startOf('day');
|
|
var weekViewStart = moment(beginningOfWeek).startOf('day');
|
|
var weekViewEnd = moment(endOfWeek).startOf('day');
|
|
|
|
var offset, span;
|
|
|
|
if (eventStart.isBefore(weekViewStart) || eventStart.isSame(weekViewStart)) {
|
|
offset = 0;
|
|
} else {
|
|
offset = eventStart.diff(weekViewStart, 'days');
|
|
}
|
|
|
|
if (eventEnd.isAfter(weekViewEnd)) {
|
|
eventEnd = weekViewEnd;
|
|
}
|
|
|
|
if (eventStart.isBefore(weekViewStart)) {
|
|
eventStart = weekViewStart;
|
|
}
|
|
|
|
span = moment(eventEnd).diff(eventStart, 'days') + 1;
|
|
|
|
event.daySpan = span;
|
|
event.dayOffset = offset;
|
|
return event;
|
|
});
|
|
|
|
return {columns: columns, events: eventsSorted};
|
|
|
|
};
|
|
|
|
this.getDayView = function(events, currentDay, dayStartHour, dayEndHour) {
|
|
|
|
var calendarStart = moment(currentDay).startOf('day').add(dayStartHour, 'hours');
|
|
var calendarEnd = moment(currentDay).startOf('day').add(dayEndHour, 'hours');
|
|
var calendarHeight = (dayEndHour - dayStartHour + 1) * 60;
|
|
var buckets = [];
|
|
|
|
return events.filter(function(event) {
|
|
return self.eventIsInPeriod(event.starts_at, event.ends_at, moment(currentDay).startOf('day').toDate(), moment(currentDay).endOf('day').toDate());
|
|
}).map(function(event) {
|
|
if (moment(event.starts_at).isBefore(calendarStart)) {
|
|
event.top = 0;
|
|
} else {
|
|
event.top = moment(event.starts_at).startOf('minute').diff(calendarStart.startOf('minute'), 'minutes') - 2;
|
|
}
|
|
|
|
if (moment(event.ends_at).isAfter(calendarEnd)) {
|
|
event.height = calendarHeight - event.top;
|
|
} else {
|
|
var diffStart = event.starts_at;
|
|
if (moment(event.starts_at).isBefore(calendarStart)) {
|
|
diffStart = calendarStart.toDate();
|
|
}
|
|
event.height = moment(event.ends_at).diff(diffStart, 'minutes');
|
|
}
|
|
|
|
if (event.top - event.height > calendarHeight) {
|
|
event.height = 0;
|
|
}
|
|
|
|
event.left = 0;
|
|
|
|
return event;
|
|
}).filter(function(event) {
|
|
return event.height > 0;
|
|
}).map(function(event) {
|
|
|
|
var cannotFitInABucket = true;
|
|
buckets.forEach(function(bucket, bucketIndex) {
|
|
var canFitInThisBucket = true;
|
|
|
|
bucket.forEach(function(bucketItem) {
|
|
if (self.eventIsInPeriod(event.starts_at, event.ends_at, bucketItem.starts_at, bucketItem.ends_at) || self.eventIsInPeriod(bucketItem.starts_at, bucketItem.ends_at, event.starts_at, event.ends_at)) {
|
|
canFitInThisBucket = false;
|
|
}
|
|
});
|
|
|
|
if (canFitInThisBucket && cannotFitInABucket) {
|
|
cannotFitInABucket = false;
|
|
event.left = bucketIndex * 150;
|
|
buckets[bucketIndex].push(event);
|
|
}
|
|
|
|
});
|
|
|
|
if (cannotFitInABucket) {
|
|
event.left = buckets.length * 150;
|
|
buckets.push([event]);
|
|
}
|
|
|
|
return event;
|
|
|
|
});
|
|
|
|
};
|
|
|
|
this.toggleEventBreakdown = function(view, rowIndex, cellIndex) {
|
|
|
|
var openEvents = [];
|
|
|
|
function closeAllOpenItems() {
|
|
view = view.map(function(row) {
|
|
row.isOpened = false;
|
|
return row.map(function(cell) {
|
|
cell.isOpened = false;
|
|
return cell;
|
|
});
|
|
});
|
|
}
|
|
|
|
if (view[rowIndex][cellIndex].events.length > 0) {
|
|
|
|
var isCellOpened = view[rowIndex][cellIndex].isOpened;
|
|
|
|
closeAllOpenItems();
|
|
|
|
view[rowIndex][cellIndex].isOpened = !isCellOpened;
|
|
view[rowIndex].isOpened = !isCellOpened;
|
|
openEvents = view[rowIndex][cellIndex].events;
|
|
} else {
|
|
closeAllOpenItems();
|
|
}
|
|
|
|
return {view: view, openEvents: openEvents};
|
|
|
|
};
|
|
|
|
}]);
|
|
|
|
'use strict';
|
|
|
|
|
|
angular.module('mwl.calendar')
|
|
.filter('truncateEventTitle', function() {
|
|
|
|
return function(string, length, boxHeight) {
|
|
if (!string) return '';
|
|
|
|
//Only truncate if if actually needs truncating
|
|
if (string.length >= length && string.length / 20 > boxHeight / 30) {
|
|
return string.substr(0, length) + '...';
|
|
} else {
|
|
return string;
|
|
}
|
|
};
|
|
|
|
});
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* @ngdoc directive
|
|
* @name angularBootstrapCalendarApp.directive:mwlCalendarYear
|
|
* @description
|
|
* # mwlCalendarYear
|
|
*/
|
|
angular.module('mwl.calendar')
|
|
.directive('mwlCalendarYear', ["$sce", "$timeout", "calendarHelper", "moment", function($sce, $timeout, calendarHelper, moment) {
|
|
return {
|
|
templateUrl: 'templates/year.html',
|
|
restrict: 'EA',
|
|
require: '^mwlCalendar',
|
|
scope: {
|
|
events: '=calendarEvents',
|
|
currentDay: '=calendarCurrentDay',
|
|
eventClick: '=calendarEventClick',
|
|
eventEditClick: '=calendarEditEventClick',
|
|
eventDeleteClick: '=calendarDeleteEventClick',
|
|
editEventHtml: '=calendarEditEventHtml',
|
|
deleteEventHtml: '=calendarDeleteEventHtml',
|
|
autoOpen: '=calendarAutoOpen',
|
|
timespanClick: '=calendarTimespanClick'
|
|
},
|
|
link: function postLink(scope, element, attrs, calendarCtrl) {
|
|
|
|
var firstRun = false;
|
|
|
|
scope.$sce = $sce;
|
|
|
|
calendarCtrl.titleFunctions.year = function(currentDay) {
|
|
return moment(currentDay).format('YYYY');
|
|
};
|
|
|
|
function updateView() {
|
|
scope.view = calendarHelper.getYearView(scope.events, scope.currentDay);
|
|
|
|
//Auto open the calendar to the current day if set
|
|
if (scope.autoOpen && !firstRun) {
|
|
scope.view.forEach(function(row, rowIndex) {
|
|
row.forEach(function(year, cellIndex) {
|
|
if (year.label == moment(scope.currentDay).format('MMMM')) {
|
|
scope.monthClicked(rowIndex, cellIndex, true);
|
|
$timeout(function() {
|
|
firstRun = false;
|
|
});
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
scope.$watch('currentDay', updateView);
|
|
scope.$watch('events', updateView, true);
|
|
|
|
scope.monthClicked = function(yearIndex, monthIndex, firstRun) {
|
|
|
|
if (!firstRun) {
|
|
scope.timespanClick({$date: scope.view[yearIndex][monthIndex].date.startOf('month').toDate()});
|
|
}
|
|
|
|
var handler = calendarHelper.toggleEventBreakdown(scope.view, yearIndex, monthIndex);
|
|
scope.view = handler.view;
|
|
scope.openEvents = handler.openEvents;
|
|
|
|
};
|
|
|
|
scope.drillDown = function(month) {
|
|
calendarCtrl.changeView('month', moment(scope.currentDay).clone().month(month).toDate());
|
|
};
|
|
|
|
}
|
|
};
|
|
}]);
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* @ngdoc directive
|
|
* @name angularBootstrapCalendarApp.directive:mwlCalendarWeek
|
|
* @description
|
|
* # mwlCalendarWeek
|
|
*/
|
|
angular.module('mwl.calendar')
|
|
.directive('mwlCalendarWeek', ["moment", "calendarHelper", function(moment, calendarHelper) {
|
|
return {
|
|
templateUrl: 'templates/week.html',
|
|
restrict: 'EA',
|
|
require: '^mwlCalendar',
|
|
scope: {
|
|
events: '=calendarEvents',
|
|
currentDay: '=calendarCurrentDay',
|
|
eventClick: '=calendarEventClick',
|
|
useIsoWeek: '=calendarUseIsoWeek',
|
|
weekTitleLabel: '@calendarWeekTitleLabel'
|
|
},
|
|
link: function postLink(scope, element, attrs, calendarCtrl) {
|
|
|
|
var titleLabel = scope.weekTitleLabel || 'Week {week} of {year}';
|
|
|
|
calendarCtrl.titleFunctions.week = function(currentDay) {
|
|
return titleLabel.replace('{week}', moment(currentDay).week()).replace('{year}', moment(currentDay).format('YYYY'));
|
|
};
|
|
|
|
function updateView() {
|
|
scope.view = calendarHelper.getWeekView(scope.events, scope.currentDay, scope.useIsoWeek);
|
|
}
|
|
|
|
scope.drillDown = function(day) {
|
|
calendarCtrl.changeView('day', moment(scope.currentDay).clone().date(day).toDate());
|
|
};
|
|
|
|
scope.$watch('currentDay', updateView);
|
|
scope.$watch('events', updateView, true);
|
|
|
|
}
|
|
};
|
|
}]);
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* @ngdoc directive
|
|
* @name angularBootstrapCalendarApp.directive:mwlCalendarMonth
|
|
* @description
|
|
* # mwlCalendarMonth
|
|
*/
|
|
angular.module('mwl.calendar')
|
|
.directive('mwlCalendarMonth', ["$sce", "$timeout", "$filter", "moment", "calendarHelper", function ($sce, $timeout, $filter, moment, calendarHelper) {
|
|
return {
|
|
templateUrl: 'templates/month.html',
|
|
restrict: 'EA',
|
|
require: '^mwlCalendar',
|
|
scope: {
|
|
events: '=calendarEvents',
|
|
currentDay: '=calendarCurrentDay',
|
|
eventClick: '=calendarEventClick',
|
|
eventEditClick: '=calendarEditEventClick',
|
|
eventDeleteClick: '=calendarDeleteEventClick',
|
|
editEventHtml: '=calendarEditEventHtml',
|
|
deleteEventHtml: '=calendarDeleteEventHtml',
|
|
autoOpen: '=calendarAutoOpen',
|
|
useIsoWeek: '=calendarUseIsoWeek',
|
|
timespanClick: '=calendarTimespanClick'
|
|
},
|
|
link: function postLink(scope, element, attrs, calendarCtrl) {
|
|
|
|
var firstRun = false;
|
|
|
|
scope.$sce = $sce;
|
|
|
|
calendarCtrl.titleFunctions.month = function(currentDay) {
|
|
return $filter('date')(currentDay, 'MMMM yyyy');
|
|
};
|
|
|
|
function updateView() {
|
|
scope.view = calendarHelper.getMonthView(scope.events, scope.currentDay, scope.useIsoWeek);
|
|
|
|
//Auto open the calendar to the current day if set
|
|
if (scope.autoOpen && !firstRun) {
|
|
scope.view.forEach(function(week, rowIndex) {
|
|
week.forEach(function(day, cellIndex) {
|
|
if (day.inMonth && moment(scope.currentDay).startOf('day').isSame(day.date.startOf('day'))) {
|
|
scope.dayClicked(rowIndex, cellIndex, true);
|
|
$timeout(function() {
|
|
firstRun = false;
|
|
});
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
scope.$watch('currentDay', updateView);
|
|
scope.$watch('events', updateView, true);
|
|
|
|
scope.weekDays = calendarHelper.getWeekDayNames(false, scope.useIsoWeek);
|
|
|
|
scope.dayClicked = function(rowIndex, cellIndex, firstRun) {
|
|
|
|
if (!firstRun) {
|
|
scope.timespanClick({$date: scope.view[rowIndex][cellIndex].date.startOf('day').toDate()});
|
|
}
|
|
|
|
var handler = calendarHelper.toggleEventBreakdown(scope.view, rowIndex, cellIndex);
|
|
scope.view = handler.view;
|
|
scope.openEvents = handler.openEvents;
|
|
|
|
};
|
|
|
|
scope.drillDown = function(day) {
|
|
calendarCtrl.changeView('day', moment(scope.currentDay).clone().date(day).toDate());
|
|
};
|
|
|
|
scope.highlightEvent = function(event, shouldAddClass) {
|
|
|
|
scope.view = scope.view.map(function(week) {
|
|
|
|
week.isOpened = false;
|
|
|
|
return week.map(function(day) {
|
|
|
|
delete day.highlightClass;
|
|
day.isOpened = false;
|
|
|
|
if (shouldAddClass) {
|
|
var dayContainsEvent = day.events.filter(function(e) {
|
|
return e.$id == event.$id;
|
|
}).length > 0;
|
|
|
|
if (dayContainsEvent) {
|
|
day.highlightClass = 'day-highlight dh-event-' + event.type;
|
|
}
|
|
}
|
|
|
|
return day;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
};
|
|
}]);
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* @ngdoc directive
|
|
* @name angularBootstrapCalendarApp.directive:mwlCalendarDay
|
|
* @description
|
|
* # mwlCalendarDay
|
|
*/
|
|
angular.module('mwl.calendar')
|
|
.directive('mwlCalendarDay', ["$filter", "moment", "calendarHelper", function($filter, moment, calendarHelper) {
|
|
return {
|
|
templateUrl: 'templates/day.html',
|
|
restrict: 'EA',
|
|
require: '^mwlCalendar',
|
|
scope: {
|
|
events: '=calendarEvents',
|
|
currentDay: '=calendarCurrentDay',
|
|
eventClick: '=calendarEventClick',
|
|
eventLabel: '@calendarEventLabel',
|
|
timeLabel: '@calendarTimeLabel',
|
|
dayViewStart:'@calendarDayViewStart',
|
|
dayViewEnd:'@calendarDayViewEnd'
|
|
},
|
|
link: function postLink(scope, element, attrs, calendarCtrl) {
|
|
|
|
var dayViewStart = moment(scope.dayViewStart || '00:00', 'HH:mm');
|
|
var dayViewEnd = moment(scope.dayViewEnd || '23:00', 'HH:mm');
|
|
|
|
scope.days = [];
|
|
var dayCounter = moment(dayViewStart);
|
|
for (var i = 0; i <= dayViewEnd.diff(dayViewStart, 'hours'); i++) {
|
|
scope.days.push({
|
|
label: dayCounter.format('ha')
|
|
});
|
|
dayCounter.add(1, 'hour');
|
|
}
|
|
|
|
calendarCtrl.titleFunctions.day = function(currentDay) {
|
|
return $filter('date')(currentDay, 'EEEE d MMMM, yyyy');
|
|
};
|
|
|
|
function updateView() {
|
|
scope.view = calendarHelper.getDayView(scope.events, scope.currentDay, dayViewStart.hours(), dayViewEnd.hours());
|
|
}
|
|
|
|
scope.$watch('currentDay', updateView);
|
|
scope.$watch('events', updateView, true);
|
|
|
|
}
|
|
};
|
|
}]);
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* @ngdoc directive
|
|
* @name angularBootstrapCalendarApp.directive:mwlCalendar
|
|
* @description
|
|
* # mwlCalendar
|
|
*/
|
|
angular.module('mwl.calendar')
|
|
.directive('mwlCalendar', function () {
|
|
return {
|
|
templateUrl: 'templates/main.html',
|
|
restrict: 'EA',
|
|
scope: {
|
|
events: '=calendarEvents',
|
|
view: '=calendarView',
|
|
currentDay: '=calendarCurrentDay',
|
|
control: '=calendarControl',
|
|
eventClick: '&calendarEventClick',
|
|
eventEditClick: '&calendarEditEventClick',
|
|
eventDeleteClick: '&calendarDeleteEventClick',
|
|
editEventHtml: '=calendarEditEventHtml',
|
|
deleteEventHtml: '=calendarDeleteEventHtml',
|
|
autoOpen: '=calendarAutoOpen',
|
|
useIsoWeek: '=calendarUseIsoWeek',
|
|
eventLabel: '@calendarEventLabel',
|
|
timeLabel: '@calendarTimeLabel',
|
|
dayViewStart:'@calendarDayViewStart',
|
|
dayViewEnd:'@calendarDayViewEnd',
|
|
weekTitleLabel: '@calendarWeekTitleLabel',
|
|
timespanClick: '&calendarTimespanClick'
|
|
},
|
|
controller: ["$scope", "$timeout", "$locale", "moment", function($scope, $timeout, $locale, moment) {
|
|
|
|
var self = this;
|
|
|
|
this.titleFunctions = {};
|
|
|
|
this.changeView = function(view, newDay) {
|
|
$scope.view = view;
|
|
$scope.currentDay = newDay;
|
|
};
|
|
|
|
$scope.control = $scope.control || {};
|
|
|
|
$scope.control.prev = function() {
|
|
$scope.currentDay = moment($scope.currentDay).subtract(1, $scope.view).toDate();
|
|
};
|
|
|
|
$scope.control.next = function() {
|
|
$scope.currentDay = moment($scope.currentDay).add(1, $scope.view).toDate();
|
|
};
|
|
|
|
$scope.control.getTitle = function() {
|
|
if (!self.titleFunctions[$scope.view]) {
|
|
return '';
|
|
}
|
|
return self.titleFunctions[$scope.view]($scope.currentDay);
|
|
};
|
|
|
|
//Auto update the calendar when the locale changes
|
|
var firstRunWatcher = true;
|
|
var unbindWatcher = $scope.$watch(function() {
|
|
return moment.locale() + $locale.id;
|
|
}, function() {
|
|
if (firstRunWatcher) { //dont run the first time the calendar is initialised
|
|
firstRunWatcher = false;
|
|
return;
|
|
}
|
|
var originalView = angular.copy($scope.view);
|
|
$scope.view = 'redraw';
|
|
$timeout(function() { //bit of a hacky way to redraw the calendar, should be refactored at some point
|
|
$scope.view = originalView;
|
|
});
|
|
});
|
|
|
|
//Remove the watcher when the calendar is destroyed
|
|
var unbindDestroyListener = $scope.$on('$destroy', function() {
|
|
unbindDestroyListener();
|
|
unbindWatcher();
|
|
});
|
|
|
|
}]
|
|
};
|
|
});
|