Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

feat(custom-template-urls): allow setting of custom template on a per…

… calendar instance basis

Closes #355
  • Loading branch information...
Matt Lewis
Matt Lewis committed Jun 29, 2016
1 parent fdaea2d commit 0ae7661c3341e145a88ddfa8f58ce012f013d151
@@ -205,6 +205,19 @@ An optional expression that is evaluated on each cell generated for the year and

If set it true it will disable the slidebox on the month and year views

### custom-template-urls

An object where the key is the template name to override and the value is a path to a custom template for that calendar instance. If not set it will fallback to the value of `calendarConfig.templates`.

For example, to change the month view template on just one instance of the month view:
```
// in your controller
$templateCache.put('my-custom-template.html', 'Custom month view template here');
// in your template
<mwl-calendar custom-template-urls="{calendarMonthView: 'my-custom-template.html'}"></mwl-calendar>
```

## Configuring the calendar default config

You can easily customise the date formats and i18n strings used throughout the calendar by using the `calendarConfig` value. Please note that these example formats are those used by moment.js and these won't work if using angular as the date formatter. Example usage:
@@ -215,7 +228,7 @@ angular.module('myModule')
console.log(calendarConfig); //view all available config
calendarConfig.templates.calendarMonthView = 'path/to/custom/template.html'; //change the month view template to a custom template
calendarConfig.templates.calendarMonthView = 'path/to/custom/template.html'; //change the month view template globally to a custom template
calendarConfig.dateFormatter = 'moment'; //use either moment or angular to format dates on the calendar. Default angular. Setting this will override any date formats you have already set.
@@ -1,17 +1,10 @@
angular
.module('mwl.calendar.docs')
.controller('CustomTemplatesCtrl', function($scope, moment, calendarConfig) {
.controller('CustomTemplatesCtrl', function($scope, moment) {

var vm = this;

calendarConfig.templates.calendarMonthCell = 'customMonthCell.html';

vm.events = [];
vm.calendarView = 'month';
vm.viewDate = moment().startOf('month').toDate();

$scope.$on('$destroy', function() {
calendarConfig.templates.calendarMonthCell = 'mwl/calendarMonthCell.html';
});

});
@@ -20,6 +20,7 @@
<mwl-calendar
events="vm.events"
view="vm.calendarView"
view-date="vm.viewDate">
view-date="vm.viewDate"
custom-template-urls="{calendarMonthCell: 'customMonthCell.html'}">
</mwl-calendar>
</div>
@@ -113,10 +113,10 @@ angular
});

})
.directive('mwlCalendar', function(calendarConfig) {
.directive('mwlCalendar', function() {

return {
templateUrl: calendarConfig.templates.calendar,
template: '<div mwl-dynamic-directive-template name="calendar" overrides="vm.customTemplateUrls"></div>',
restrict: 'E',
scope: {
events: '=',
@@ -127,6 +127,7 @@ angular
deleteEventHtml: '=?',
cellIsOpen: '=?',
slideBoxDisabled: '=?',
customTemplateUrls: '=?',
onEventClick: '&',
onEventTimesChanged: '&',
onEditEventClick: '&',
@@ -88,10 +88,10 @@ angular
};

})
.directive('mwlCalendarDay', function(calendarConfig) {
.directive('mwlCalendarDay', function() {

return {
templateUrl: calendarConfig.templates.calendarDayView,
template: '<div mwl-dynamic-directive-template name="calendarDayView" overrides="vm.customTemplateUrls"></div>',
restrict: 'E',
require: '^mwlCalendar',
scope: {
@@ -108,7 +108,8 @@ angular
onEditEventClick: '=',
onDeleteEventClick: '=',
editEventHtml: '=',
deleteEventHtml: '='
deleteEventHtml: '=',
customTemplateUrls: '=?'
},
controller: 'MwlCalendarDayCtrl as vm',
bindToController: true
@@ -100,11 +100,11 @@ angular
};

})
.directive('mwlCalendarHourList', function(calendarConfig) {
.directive('mwlCalendarHourList', function() {

return {
restrict: 'E',
templateUrl: calendarConfig.templates.calendarHourList,
template: '<div mwl-dynamic-directive-template name="calendarHourList" overrides="vm.customTemplateUrls"></div>',
controller: 'MwlCalendarHourListCtrl as vm',
scope: {
viewDate: '=',
@@ -114,7 +114,8 @@ angular
dayWidth: '=?',
onTimespanClick: '=',
onDateRangeSelect: '=',
onEventTimesChanged: '='
onEventTimesChanged: '=',
customTemplateUrls: '=?'
},
bindToController: true
};
@@ -93,10 +93,10 @@ angular
};

})
.directive('mwlCalendarMonth', function(calendarConfig) {
.directive('mwlCalendarMonth', function() {

return {
templateUrl: calendarConfig.templates.calendarMonthView,
template: '<div mwl-dynamic-directive-template name="calendarMonthView" overrides="vm.customTemplateUrls"></div>',
restrict: 'E',
require: '^mwlCalendar',
scope: {
@@ -111,7 +111,8 @@ angular
cellIsOpen: '=',
onTimespanClick: '=',
cellModifier: '=',
slideBoxDisabled: '='
slideBoxDisabled: '=',
customTemplateUrls: '=?'
},
controller: 'MwlCalendarMonthCtrl as vm',
link: function(scope, element, attrs, calendarCtrl) {
@@ -19,11 +19,11 @@ angular
});

})
.directive('mwlCalendarSlideBox', function(calendarConfig) {
.directive('mwlCalendarSlideBox', function() {

return {
restrict: 'E',
templateUrl: calendarConfig.templates.calendarSlideBox,
template: '<div mwl-dynamic-directive-template name="calendarSlideBox" overrides="vm.customTemplateUrls"></div>',
replace: true,
controller: 'MwlCalendarSlideBoxCtrl as vm',
require: ['^?mwlCalendarMonth', '^?mwlCalendarYear'],
@@ -39,7 +39,8 @@ angular
onEditEventClick: '=',
deleteEventHtml: '=',
onDeleteEventClick: '=',
cell: '='
cell: '=',
customTemplateUrls: '=?'
},
bindToController: true
};
@@ -80,10 +80,10 @@ angular
};

})
.directive('mwlCalendarWeek', function(calendarConfig) {
.directive('mwlCalendarWeek', function() {

return {
templateUrl: calendarConfig.templates.calendarWeekView,
template: '<div mwl-dynamic-directive-template name="calendarWeekView" overrides="vm.customTemplateUrls"></div>',
restrict: 'E',
require: '^mwlCalendar',
scope: {
@@ -96,7 +96,8 @@ angular
dayViewSplit: '=',
dayViewEventChunkSize: '=',
onTimespanClick: '=',
onDateRangeSelect: '='
onDateRangeSelect: '=',
customTemplateUrls: '=?'
},
controller: 'MwlCalendarWeekCtrl as vm',
link: function(scope, element, attrs, calendarCtrl) {
@@ -65,10 +65,10 @@ angular
};

})
.directive('mwlCalendarYear', function(calendarConfig) {
.directive('mwlCalendarYear', function() {

return {
templateUrl: calendarConfig.templates.calendarYearView,
template: '<div mwl-dynamic-directive-template name="calendarYearView" overrides="vm.customTemplateUrls"></div>',
restrict: 'E',
require: '^mwlCalendar',
scope: {
@@ -83,7 +83,8 @@ angular
cellIsOpen: '=',
onTimespanClick: '=',
cellModifier: '=',
slideBoxDisabled: '='
slideBoxDisabled: '=',
customTemplateUrls: '=?'
},
controller: 'MwlCalendarYearCtrl as vm',
link: function(scope, element, attrs, calendarCtrl) {
@@ -0,0 +1,34 @@
'use strict';

var angular = require('angular');

angular
.module('mwl.calendar')
.controller('MwlDynamicDirectiveTemplateCtrl', function($compile, $scope, $attrs, $element, $templateCache, calendarConfig) {

$scope.$watch($attrs.overrides, function(overrides) {

var templateName = calendarConfig.templates[$attrs.name];
if (
overrides &&
angular.isObject(overrides) &&
overrides[$attrs.name] &&
$templateCache.get(overrides[$attrs.name])
) {
templateName = overrides[$attrs.name];
}
var template = $templateCache.get(templateName);
$element.html(template);
$compile($element.contents())($scope);

});

})
.directive('mwlDynamicDirectiveTemplate', function() {

return {
restrict: 'A',
controller: 'MwlDynamicDirectiveTemplateCtrl'
};

});
@@ -20,6 +20,7 @@
cell-is-open="vm.cellIsOpen"
cell-modifier="vm.cellModifier"
slide-box-disabled="vm.slideBoxDisabled"
custom-template-urls="vm.customTemplateUrls"
ng-switch-when="year">
</mwl-calendar-year>

@@ -36,6 +37,7 @@
cell-is-open="vm.cellIsOpen"
cell-modifier="vm.cellModifier"
slide-box-disabled="vm.slideBoxDisabled"
custom-template-urls="vm.customTemplateUrls"
ng-switch-when="month">
</mwl-calendar-month>

@@ -50,6 +52,7 @@
day-view-event-chunk-size="vm.dayViewEventChunkSize"
on-timespan-click="vm.onTimespanClick"
on-date-range-select="vm.onDateRangeSelect"
custom-template-urls="vm.customTemplateUrls"
ng-switch-when="week">
</mwl-calendar-week>

@@ -68,6 +71,7 @@
on-delete-event-click="vm.onDeleteEventClick"
edit-event-html="vm.editEventHtml"
delete-event-html="vm.deleteEventHtml"
custom-template-urls="vm.customTemplateUrls"
ng-switch-when="day">
</mwl-calendar-day>
</div>
@@ -35,7 +35,8 @@
on-timespan-click="vm.onTimespanClick"
on-date-range-select="vm.onDateRangeSelect"
on-event-times-changed="vm.onEventTimesChanged"
view-date="vm.viewDate">
view-date="vm.viewDate"
custom-template-urls="vm.customTemplateUrls">
</mwl-calendar-hour-list>

<div
@@ -29,7 +29,7 @@
<i class="fa fa-chevron-up"></i>
</div>

<ng-include src=":: vm.calendarConfig.templates.calendarMonthCellEvents"></ng-include>
<div mwl-dynamic-directive-template name="calendarMonthCellEvents" overrides="vm.customTemplateUrls"></div>

<div id="cal-week-box" ng-if="$first && rowHovered">
<span ng-bind="vm.calendarConfig.i18nStrings.weekNumber.replace('{week}', day.date.clone().add(1, 'day').isoWeek())"></span>
@@ -16,7 +16,7 @@
class="cal-cell1 cal-cell {{ day.highlightClass }}"
ng-click="vm.dayClicked(day, false, $event)"
ng-class="{pointer: day.events.length > 0}">
<ng-include src=":: vm.calendarConfig.templates.calendarMonthCell"></ng-include>
<div mwl-dynamic-directive-template name="calendarMonthCell" overrides="vm.customTemplateUrls"></div>
</div>
</div>

@@ -28,7 +28,8 @@
on-edit-event-click="vm.onEditEventClick"
delete-event-html="vm.deleteEventHtml"
on-delete-event-click="vm.onDeleteEventClick"
cell="vm.view[vm.openDayIndex]">
cell="vm.view[vm.openDayIndex]"
custom-template-urls="vm.customTemplateUrls">
</mwl-calendar-slide-box>

</div>
@@ -38,6 +38,7 @@
view-date="vm.viewDate"
on-timespan-click="vm.onTimespanClick"
on-date-range-select="vm.onDateRangeSelect"
custom-template-urls="vm.customTemplateUrls"
ng-if="vm.showTimes">
</mwl-calendar-hour-list>

@@ -41,7 +41,8 @@
on-edit-event-click="vm.onEditEventClick"
delete-event-html="vm.deleteEventHtml"
on-delete-event-click="vm.onDeleteEventClick"
cell="vm.view[vm.openMonthIndex]">
cell="vm.view[vm.openMonthIndex]"
custom-template-urls="vm.customTemplateUrls">
</mwl-calendar-slide-box>

</div>
@@ -0,0 +1,49 @@
'use strict';

var angular = require('angular');

describe('dynamicDirectiveTemplate directive', function() {

beforeEach(angular.mock.module('mwl.calendar'));

var scope, elm, calendarConfig, $templateCache;
beforeEach(inject(function($rootScope, $compile, _$templateCache_, _calendarConfig_) {
$templateCache = _$templateCache_;
calendarConfig = _calendarConfig_;
scope = $rootScope.$new();
calendarConfig.templates = {
foo: 'foo.html'
};
scope.baz = 'baz';
$templateCache.put('foo.html', 'foo {{ baz }}');
elm = $compile('<div mwl-dynamic-directive-template name="foo" overrides="overrides"></div>')(scope);
scope.$apply();
}));

afterEach(function() {
elm.remove();
scope.$destroy();
});

it('should fallback to the default template if no custom templates are set', function() {
expect(elm.text()).to.equal('foo baz');
});

it('should fallback to the default template if the custom template name doesnt exist in the cache', function() {
scope.overrides = {
foo: 'bam.html'
};
scope.$apply();
expect(elm.text()).to.equal('foo baz');
});

it('should use the custom template', function() {
$templateCache.put('bar.html', 'bar {{ baz }}');
scope.overrides = {
foo: 'bar.html'
};
scope.$apply();
expect(elm.text()).to.equal('bar baz');
});

});

0 comments on commit 0ae7661

Please sign in to comment.
You can’t perform that action at this time.