Skip to content
This repository has been archived by the owner on May 29, 2019. It is now read-only.

Commit

Permalink
feat(datepicker): allow custom templates
Browse files Browse the repository at this point in the history
- Allow custom templates for datepicker and popup
- Expose controller to template
  • Loading branch information
wesleycho committed Aug 8, 2015
1 parent 991c91d commit 48e8839
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 13 deletions.
26 changes: 18 additions & 8 deletions src/datepicker/datepicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,21 +225,22 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
return {
restrict: 'EA',
replace: true,
templateUrl: 'template/datepicker/datepicker.html',
templateUrl: function(element, attrs) {
return attrs.templateUrl || 'template/datepicker/datepicker.html';
},
scope: {
datepickerMode: '=?',
dateDisabled: '&',
customClass: '&',
shortcutPropagation: '&?'
},
require: ['datepicker', '?^ngModel'],
require: ['datepicker', '^ngModel'],
controller: 'DatepickerController',
controllerAs: 'datepicker',
link: function(scope, element, attrs, ctrls) {
var datepickerCtrl = ctrls[0], ngModelCtrl = ctrls[1];

if ( ngModelCtrl ) {
datepickerCtrl.init( ngModelCtrl );
}
datepickerCtrl.init(ngModelCtrl);
}
};
})
Expand Down Expand Up @@ -477,6 +478,8 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst

.constant('datepickerPopupConfig', {
datepickerPopup: 'yyyy-MM-dd',
datepickerPopupTemplateUrl: 'template/datepicker/popup.html',
datepickerTemplateUrl: 'template/datepicker/datepicker.html',
html5Types: {
date: 'yyyy-MM-dd',
'datetime-local': 'yyyy-MM-ddTHH:mm:ss.sss',
Expand Down Expand Up @@ -506,7 +509,9 @@ function ($compile, $parse, $document, $rootScope, $position, dateFilter, datePa
link: function(scope, element, attrs, ngModel) {
var dateFormat,
closeOnDateSelection = angular.isDefined(attrs.closeOnDateSelection) ? scope.$parent.$eval(attrs.closeOnDateSelection) : datepickerPopupConfig.closeOnDateSelection,
appendToBody = angular.isDefined(attrs.datepickerAppendToBody) ? scope.$parent.$eval(attrs.datepickerAppendToBody) : datepickerPopupConfig.appendToBody;
appendToBody = angular.isDefined(attrs.datepickerAppendToBody) ? scope.$parent.$eval(attrs.datepickerAppendToBody) : datepickerPopupConfig.appendToBody,
datepickerPopupTemplateUrl = angular.isDefined(attrs.datepickerPopupTemplateUrl) ? attrs.datepickerPopupTemplateUrl : datepickerPopupConfig.datepickerPopupTemplateUrl,
datepickerTemplateUrl = angular.isDefined(attrs.datepickerTemplateUrl) ? attrs.datepickerTemplateUrl : datepickerPopupConfig.datepickerTemplateUrl;

scope.showButtonBar = angular.isDefined(attrs.showButtonBar) ? scope.$parent.$eval(attrs.showButtonBar) : datepickerPopupConfig.showButtonBar;

Expand Down Expand Up @@ -547,7 +552,8 @@ function ($compile, $parse, $document, $rootScope, $position, dateFilter, datePa
var popupEl = angular.element('<div datepicker-popup-wrap><div datepicker></div></div>');
popupEl.attr({
'ng-model': 'date',
'ng-change': 'dateSelection(date)'
'ng-change': 'dateSelection(date)',
'template-url': datepickerPopupTemplateUrl
});

function cameltoDash( string ){
Expand All @@ -556,6 +562,8 @@ function ($compile, $parse, $document, $rootScope, $position, dateFilter, datePa

// datepicker element
var datepickerEl = angular.element(popupEl.children()[0]);
datepickerEl.attr('template-url', datepickerTemplateUrl);

if (isHtml5DateInput) {
if (attrs.type == 'month') {
datepickerEl.attr('datepicker-mode', '"month"');
Expand Down Expand Up @@ -785,6 +793,8 @@ function ($compile, $parse, $document, $rootScope, $position, dateFilter, datePa
restrict:'EA',
replace: true,
transclude: true,
templateUrl: 'template/datepicker/popup.html'
templateUrl: function(element, attrs) {
return attrs.templateUrl || 'template/datepicker/popup.html';
}
};
});
18 changes: 15 additions & 3 deletions src/datepicker/docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,14 @@ All settings can be provided as attributes in the `datepicker` or globally confi
* `year-range`
_(Default: 20)_ :
Number of years displayed in year selection.

* `shortcut-propagation`
_(Default: false)_ :
An option to disable or enable shortcut's event propagation.
_(Default: false)_ :
An option to disable or enable shortcut's event propagation.

* `template-url`
_(Default: 'template/datepicker/datepicker.html') :
Allows overriding of default template of the datepicker


### Popup Settings ###
Expand Down Expand Up @@ -115,6 +119,14 @@ Specific settings for the `datepicker-popup`, that can globally configured throu
_(Default: true)_ :
Whether to close calendar when a date is chosen.

* `datepicker-popup-template-url`
_(Default: 'template/datepicker/popup.html') :
Allows overriding of default template of the popup

* `datepicker-template-url`
_(Default: 'template/datepicker/popup.html') :
Allows overriding of default template of the datepicker used in popup

* `datepicker-append-to-body`
_(Default: false)_:
Append the datepicker popup element to `body`, rather than inserting after `datepicker-popup`. For global configuration, use `datepickerPopupConfig.appendToBody`.
Expand Down
74 changes: 72 additions & 2 deletions src/datepicker/test/datepicker.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
describe('datepicker directive', function () {
var $rootScope, $compile, element;
var $rootScope, $compile, $templateCache, element;
beforeEach(module('ui.bootstrap.datepicker'));
beforeEach(module('template/datepicker/datepicker.html'));
beforeEach(module('template/datepicker/day.html'));
Expand Down Expand Up @@ -198,10 +198,11 @@ describe('datepicker directive', function () {
});

describe('', function () {
beforeEach(inject(function(_$compile_, _$rootScope_) {
beforeEach(inject(function(_$compile_, _$rootScope_, _$templateCache_) {
$compile = _$compile_;
$rootScope = _$rootScope_;
$rootScope.date = new Date('September 30, 2010 15:30:00');
$templateCache = _$templateCache_;
}));


Expand Down Expand Up @@ -352,6 +353,31 @@ describe('datepicker directive', function () {
expect(getTitle()).toBe('January 2014');
});

it('should support custom templates', function() {
$templateCache.put('foo/bar.html', '<div>baz</div>');

element = $compile('<datepicker ng-model="date" template-url="foo/bar.html"></datepicker>')($rootScope);
$rootScope.$digest();

expect(element.html()).toBe('baz');
});

it('should expose the controller in the template', function() {
$templateCache.put('template/datepicker/datepicker.html', '<div>{{datepicker.text}}</div>');

element = $compile('<datepicker ng-model="date"></datepicker>')($rootScope);
$rootScope.$digest();

var ctrl = element.controller('datepicker');
expect(ctrl).toBeDefined();
expect(element.html()).toBe('');

ctrl.text = 'baz';
$rootScope.$digest();

expect(element.html()).toBe('baz');
});

// issue #3079
describe('time zone bug', function () {

Expand Down Expand Up @@ -2007,6 +2033,50 @@ describe('datepicker directive', function () {
});
});

describe('with datepicker-popup-template-url', function() {
beforeEach(function() {
$rootScope.date = new Date();
});

afterEach(function () {
$document.find('body').find('.dropdown-menu').remove();
});

it('should allow custom templates for the popup', function() {
$templateCache.put('foo/bar.html', '<div>baz</div>');

var elm = angular.element('<div><input ng-model="date" datepicker-popup datepicker-popup-template-url="foo/bar.html" is-open="true"></div>');

$compile(elm)($rootScope);
$rootScope.$digest();

expect(elm.children().eq(1).html()).toBe('baz');
});
});

describe('with datepicker-template-url', function() {
beforeEach(function() {
$rootScope.date = new Date();
});

afterEach(function () {
$document.find('body').find('.dropdown-menu').remove();
});

it('should allow custom templates for the datepicker', function() {
$templateCache.put('foo/bar.html', '<div>baz</div>');

var elm = angular.element('<div><input ng-model="date" datepicker-popup datepicker-template-url="foo/bar.html" is-open="true"></div>');

$compile(elm)($rootScope);
$rootScope.$digest();

var datepicker = elm.find('[datepicker]');

expect(datepicker.html()).toBe('baz');
});
});

describe('with an append-to-body attribute', function() {
beforeEach(function() {
$rootScope.date = new Date();
Expand Down

0 comments on commit 48e8839

Please sign in to comment.