Skip to content

Commit a9d04e8

Browse files
committed
feat(renderOn): Add renderOn configuration option which will cause the view to be rendered when the
renderOn accepts a string, which is the name of the event that will trigger the re-rendering of the For example, if you want to disable any dates or times that are in the past. You can $broadcast the event at an interval to disable times in the past (or any other time valid dates change). closes dalelotts#166, closes dalelotts#175
1 parent e28b99d commit a9d04e8

File tree

6 files changed

+144
-3
lines changed

6 files changed

+144
-3
lines changed

README.md

+9
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,15 @@ Causes the date/time picker to re-read its configuration when the specified even
180180
For example, perhaps the startView option in the configuration has changed and you would like the
181181
new configuration to be used. You can $broadcast the event to cause this directive to use the new configuration.
182182

183+
### renderOn
184+
185+
String. Default: null
186+
187+
Causes the date/time picker to re-render its view when the specified event is received.
188+
189+
For example, if you want to disable any dates or times that are in the past.
190+
You can $broadcast the event at an interval to disable times in the past (or any other time valid dates change).
191+
183192
### dropdownSelector
184193

185194
When used within a Bootstrap dropdown and jQuery, the selector specified in dropdownSelector will toggle the dropdown when a date/time is selected.

demo/demo-controller.js

+17
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ angular.module('demo.demoController', [])
7474
configureOnConfig: {
7575
startView: 'year',
7676
configureOn: 'config-changed'
77+
},
78+
renderOnConfig: {
79+
startView: 'year',
80+
renderOn: 'valid-dates-changed'
7781
}
7882
};
7983

@@ -88,5 +92,18 @@ angular.module('demo.demoController', [])
8892
$scope.config.configureOnConfig.startView = validViews[newIndex];
8993
$scope.$broadcast('config-changed');
9094
};
95+
96+
var selectable = true;
97+
98+
$scope.renderOnBeforeRender = function ($dates) {
99+
angular.forEach($dates, function (dateObject) {
100+
dateObject.selectable = selectable;
101+
});
102+
};
103+
104+
$scope.renderOnClick = function renderOnClick() {
105+
selectable = (!selectable);
106+
$scope.$broadcast('valid-dates-changed');
107+
};
91108
}
92109
]);

demo/index.html

+18
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,24 @@ <h4>Every time you click the button, the startView is changed</h4>
377377

378378
</div>
379379
</div>
380+
381+
<div class="col-sm-6">
382+
<h3>Embedded calendar with renderOn</h3>
383+
<h4>Every time you click the button, the selectable attribute is toggled.</h4>
384+
385+
<p><code>renderOn: 'valid-dates-changed'</code> to cause the directive to re-render.</p>
386+
387+
<p><button class="btn btn-default" data-ng-click="renderOnClick()">Click me to re-render</button></p>
388+
389+
<div class="well">
390+
391+
<datetimepicker data-ng-model="data.renderOnDate"
392+
data-before-render='renderOnBeforeRender($dates)'
393+
data-datetimepicker-config="config.renderOnConfig"></datetimepicker>
394+
395+
</div>
396+
</div>
397+
380398
</div>
381399
</div>
382400

karma.conf.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ module.exports = function (config) {
5656
// the configure thresholds
5757
thresholdReporter: {
5858
statements: 100,
59-
branches: 97,
59+
branches: 98,
6060
functions: 100,
6161
lines: 100
6262
},

src/js/datetimepicker.js

+13-2
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@
2828
'use strict';
2929
angular.module('ui.bootstrap.datetimepicker', [])
3030
.constant('dateTimePickerConfig', {
31+
configureOn: null,
3132
dropdownSelector: null,
3233
minuteStep: 5,
3334
minView: 'minute',
34-
configureOn: null,
35+
renderOn: null,
3536
startView: 'day'
3637
})
3738
.directive('datetimepicker', ['$log', 'dateTimePickerConfig', function datetimepickerDirective($log, defaultConfig) {
@@ -62,10 +63,11 @@
6263
var validateConfiguration = function validateConfiguration(configuration) {
6364

6465
var validOptions = [
66+
'configureOn',
6567
'dropdownSelector',
6668
'minuteStep',
6769
'minView',
68-
'configureOn',
70+
'renderOn',
6971
'startView'
7072
];
7173

@@ -103,6 +105,12 @@
103105
if (configuration.configureOn !== null && configuration.configureOn.length < 1) {
104106
throw ('configureOn must not be an empty string');
105107
}
108+
if (configuration.renderOn !== null && !angular.isString(configuration.renderOn)) {
109+
throw ('renderOn must be a string');
110+
}
111+
if (configuration.renderOn !== null && configuration.renderOn.length < 1) {
112+
throw ('renderOn must not be an empty string');
113+
}
106114
if (configuration.dropdownSelector !== null && !angular.isString(configuration.dropdownSelector)) {
107115
throw ('dropdownSelector must be a string');
108116
}
@@ -431,6 +439,9 @@
431439
ngModelController.$render();
432440
});
433441
}
442+
if (configuration.renderOn) {
443+
scope.$on(configuration.renderOn, ngModelController.$render);
444+
}
434445
}
435446
};
436447
}]);

test/configuration/renderOn.spec.js

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*globals describe, beforeEach, it, expect, module, inject, jQuery, spyOn */
2+
3+
/**
4+
* @license angular-bootstrap-datetimepicker
5+
* Copyright 2013 Knight Rider Consulting, Inc. http://www.knightrider.com
6+
* License: MIT
7+
*/
8+
9+
/**
10+
*
11+
* @author Dale "Ducky" Lotts
12+
* @since 7/21/13
13+
*/
14+
15+
describe('renderOn', function () {
16+
'use strict';
17+
var $rootScope;
18+
var $compile;
19+
beforeEach(module('ui.bootstrap.datetimepicker'));
20+
beforeEach(inject(function (_$compile_, _$rootScope_) {
21+
$compile = _$compile_;
22+
$rootScope = _$rootScope_;
23+
$rootScope.date = null;
24+
}));
25+
26+
describe('throws exception', function () {
27+
it('if value is an empty string', function () {
28+
function compile() {
29+
$compile('<datetimepicker data-ng-model="date" data-datetimepicker-config="{ renderOn: \'\' }"></datetimepicker>')($rootScope);
30+
}
31+
32+
expect(compile).toThrow('renderOn must not be an empty string');
33+
});
34+
it('if value is numeric', function () {
35+
function compile() {
36+
$compile('<datetimepicker data-ng-model="date" data-datetimepicker-config="{ renderOn: 3 }"></datetimepicker>')($rootScope);
37+
}
38+
39+
expect(compile).toThrow('renderOn must be a string');
40+
});
41+
});
42+
describe('does NOT throw exception', function () {
43+
it('if value is a string', function () {
44+
45+
$compile('<datetimepicker data-ng-model="date" data-datetimepicker-config="{ renderOn: \'foo\' }"></datetimepicker>')($rootScope);
46+
});
47+
});
48+
describe('renderOn event', function () {
49+
it('causes view to re-render after event is received', function () {
50+
51+
52+
var selectable = true;
53+
54+
$rootScope.config = {
55+
data: {
56+
startView: 'year',
57+
renderOn: 'valid-dates-changed'
58+
}
59+
};
60+
61+
$rootScope.beforeRender = function (dates) {
62+
dates[2].selectable = selectable;
63+
};
64+
65+
spyOn($rootScope, 'beforeRender').and.callThrough();
66+
67+
var element = $compile('<datetimepicker data-ng-model="date" data-before-render=\'beforeRender($dates)\' data-datetimepicker-config="config.data"></datetimepicker>')($rootScope);
68+
$rootScope.$digest();
69+
70+
71+
var selectedElement = jQuery(jQuery('.year', element)[2]);
72+
expect(selectedElement.hasClass('disabled')).toBeFalsy();
73+
74+
selectable = false;
75+
76+
$rootScope.$broadcast('valid-dates-changed');
77+
$rootScope.$digest();
78+
79+
expect($rootScope.beforeRender.calls.count()).toBe(2);
80+
81+
selectedElement = jQuery(jQuery('.year', element)[2]);
82+
expect(selectedElement.hasClass('disabled')).toBeTruthy();
83+
});
84+
});
85+
});
86+

0 commit comments

Comments
 (0)