Skip to content

Commit 9c3d569

Browse files
committed
docs(Readme): Update Date Range picker example in the readme and add it to the demo page.
The original example did not have code to re-render the directive when the start or end date changed. It is now a more complete example. Fix #315
1 parent a5dbe27 commit 9c3d569

File tree

3 files changed

+175
-45
lines changed

3 files changed

+175
-45
lines changed

README.md

Lines changed: 59 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -341,49 +341,80 @@ the drop-down is toggled closed after the user selectes a date/time.
341341
### Create a date range picker with validation controls
342342
```html
343343
<div class="dropdown form-group">
344-
<a class="dropdown-toggle" id="dropdown1" role="button" data-toggle="dropdown" data-target="#" href="#">
345-
<div class="input-group date">
346-
<input type="text" class="form-control" data-ng-model="dateRangeStart">
347-
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
348-
</div>
349-
</a>
350-
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
351-
<datetimepicker data-ng-model="dateRangeStart" data-datetimepicker-config="{ dropdownSelector: '#dropdown1'}" data-before-render="beforeRenderStartDate($view, $dates, $leftDate, $upDate, $rightDate)"></datetimepicker>
352-
</ul>
344+
<label for="dateRangeStart">Start Date</label>
345+
<a class="dropdown-toggle" id="dropdownStart" role="button" data-toggle="dropdown" data-target="#"
346+
href="#">
347+
<div class="input-group date">
348+
<input id="dateRangeStart" type="text" class="form-control" data-ng-model="dateRangeStart">
349+
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
350+
</div>
351+
</a>
352+
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
353+
<datetimepicker data-ng-model="dateRangeStart"
354+
data-datetimepicker-config="{ dropdownSelector: '#dropdownStart', renderOn: 'end-date-changed' }"
355+
data-on-set-time="startDateOnSetTime()"
356+
data-before-render="startDateBeforeRender($dates)"></datetimepicker>
357+
</ul>
353358
</div>
354359

355360
<div class="dropdown form-group">
356-
<a class="dropdown-toggle" id="dropdown2" role="button" data-toggle="dropdown" data-target="#" href="#">
357-
<div class="input-group date">
358-
<input type="text" class="form-control" data-ng-model="dateRangeEnd">
359-
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
360-
</div>
361-
</a>
362-
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
363-
<datetimepicker data-ng-model="dateRangeEnd" data-datetimepicker-config="{ dropdownSelector: '#dropdown2'}" data-before-render="beforeRenderEndDate($view, $dates, $leftDate, $upDate, $rightDate)"></datetimepicker>
364-
</ul>
361+
<label for="dateRangeStart">End Date</label>
362+
<a class="dropdown-toggle" id="dropdownEnd" role="button" data-toggle="dropdown" data-target="#"
363+
href="#">
364+
<div class="input-group date">
365+
<input type="text" class="form-control" data-ng-model="dateRangeEnd">
366+
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
367+
</div>
368+
</a>
369+
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
370+
<datetimepicker data-ng-model="dateRangeEnd"
371+
data-datetimepicker-config="{ dropdownSelector: '#dropdownEnd', renderOn: 'start-date-changed' }"
372+
data-on-set-time="endDateOnSetTime()"
373+
data-before-render="endDateBeforeRender($view, $dates, $leftDate, $upDate, $rightDate)"></datetimepicker>
374+
</ul>
365375
</div>
366376
```
367377
In this example, two elements are created : one for the start date and the second for the end date of the range.
368378

369379
```JavaScript
370-
$scope.beforeRenderStartDate = function($view, $dates, $leftDate, $upDate, $rightDate) {
380+
/* Bindable functions
381+
-----------------------------------------------*/
382+
$scope.endDateBeforeRender = endDateBeforeRender
383+
$scope.endDateOnSetTime = endDateOnSetTime
384+
$scope.startDateBeforeRender = startDateBeforeRender
385+
$scope.startDateOnSetTime = startDateOnSetTime
386+
387+
function startDateOnSetTime () {
388+
selectable = (!selectable);
389+
$scope.$broadcast('start-date-changed');
390+
}
391+
392+
function endDateOnSetTime () {
393+
selectable = (!selectable);
394+
$scope.$broadcast('end-date-changed');
395+
}
396+
397+
function startDateBeforeRender ($dates) {
371398
if ($scope.dateRangeEnd) {
372399
var activeDate = moment($scope.dateRangeEnd);
373-
for (var i = 0; i < $dates.length; i++) {
374-
if ($dates[i].localDateValue() >= activeDate.valueOf()) $dates[i].selectable = false;
375-
}
400+
401+
$dates.filter(function (date) {
402+
return date.localDateValue() >= activeDate.valueOf()
403+
}).forEach(function (date) {
404+
date.selectable = false;
405+
})
376406
}
377407
}
378408

379-
$scope.beforeRenderEndDate = function($view, $dates, $leftDate, $upDate, $rightDate) {
409+
function endDateBeforeRender ($view, $dates) {
380410
if ($scope.dateRangeStart) {
381411
var activeDate = moment($scope.dateRangeStart).subtract(1, $view).add(1, 'minute');
382-
for (var i = 0; i < $dates.length; i++) {
383-
if ($dates[i].localDateValue() <= activeDate.valueOf()) {
384-
$dates[i].selectable = false;
385-
}
386-
}
412+
413+
$dates.filter(function (date) {
414+
return date.localDateValue() <= activeDate.valueOf()
415+
}).forEach(function (date) {
416+
date.selectable = false;
417+
})
387418
}
388419
}
389420
```

demo/demo-controller.js

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
demoController.$inject = ['$scope', '$log'];
1010

11-
function demoController($scope, $log) {
11+
function demoController ($scope, $log) {
1212

1313
var validViews = ['year', 'month', 'day', 'hour', 'minute'];
1414
var selectable = true;
@@ -21,12 +21,16 @@
2121
$scope.changeConfig = changeConfig;
2222
$scope.checkboxOnTimeSet = checkboxOnTimeSet;
2323
$scope.configFunction = configFunction;
24+
$scope.endDateBeforeRender = endDateBeforeRender
25+
$scope.endDateOnSetTime = endDateOnSetTime
2426
$scope.getLocale = getLocale;
2527
$scope.guardianOnSetTime = guardianOnSetTime;
2628
$scope.inputOnTimeSet = inputOnTimeSet;
2729
$scope.renderOnBeforeRender = renderOnBeforeRender;
2830
$scope.renderOnClick = renderOnClick;
2931
$scope.setLocale = setLocale;
32+
$scope.startDateBeforeRender = startDateBeforeRender
33+
$scope.startDateOnSetTime = startDateOnSetTime
3034

3135
moment.locale('en');
3236

@@ -60,11 +64,11 @@
6064
}
6165
};
6266

63-
function checkboxOnTimeSet() {
67+
function checkboxOnTimeSet () {
6468
$scope.data.checked = false;
6569
}
6670

67-
function inputOnTimeSet(newDate) {
71+
function inputOnTimeSet (newDate) {
6872
// If you are not using jQuery or bootstrap.js,
6973
// this will throw an error.
7074
// However, can write this function to take any
@@ -74,33 +78,33 @@
7478
$('#dropdown3').dropdown('toggle');
7579
}
7680

77-
function getLocale() {
81+
function getLocale () {
7882
return moment.locale();
7983
}
8084

81-
function setLocale(newLocale) {
85+
function setLocale (newLocale) {
8286
moment.locale(newLocale);
8387
}
8488

85-
function guardianOnSetTime($index, guardian, newDate, oldDate) {
89+
function guardianOnSetTime ($index, guardian, newDate, oldDate) {
8690
$log.info($index);
8791
$log.info(guardian.name);
8892
$log.info(newDate);
8993
$log.info(oldDate);
9094
angular.element('#guardian' + $index).dropdown('toggle');
9195
}
9296

93-
function beforeRender($dates) {
97+
function beforeRender ($dates) {
9498
var index = Math.ceil($dates.length / 2);
9599
$log.info(index);
96100
$dates[index].selectable = false;
97101
}
98102

99-
function configFunction() {
103+
function configFunction () {
100104
return {startView: 'month'};
101105
}
102106

103-
function changeConfig() {
107+
function changeConfig () {
104108
var newIndex = validViews.indexOf($scope.config.configureOnConfig.startView) + 1;
105109
console.log(newIndex);
106110
if (newIndex >= validViews.length) {
@@ -110,17 +114,49 @@
110114
$scope.$broadcast('config-changed');
111115
}
112116

113-
function renderOnBeforeRender($dates) {
117+
function renderOnBeforeRender ($dates) {
114118
angular.forEach($dates, function (dateObject) {
115119
dateObject.selectable = selectable;
116120
});
117121
}
118122

119-
function renderOnClick() {
123+
function renderOnClick () {
120124
selectable = (!selectable);
121125
$scope.$broadcast('valid-dates-changed');
122126
}
123127

124-
}
128+
function startDateOnSetTime () {
129+
selectable = (!selectable);
130+
$scope.$broadcast('start-date-changed');
131+
}
132+
133+
function endDateOnSetTime () {
134+
selectable = (!selectable);
135+
$scope.$broadcast('end-date-changed');
136+
}
137+
138+
function startDateBeforeRender ($dates) {
139+
if ($scope.dateRangeEnd) {
140+
var activeDate = moment($scope.dateRangeEnd);
125141

142+
$dates.filter(function (date) {
143+
return date.localDateValue() >= activeDate.valueOf()
144+
}).forEach(function (date) {
145+
date.selectable = false;
146+
})
147+
}
148+
}
149+
150+
function endDateBeforeRender ($view, $dates) {
151+
if ($scope.dateRangeStart) {
152+
var activeDate = moment($scope.dateRangeStart).subtract(1, $view).add(1, 'minute');
153+
154+
$dates.filter(function (date) {
155+
return date.localDateValue() <= activeDate.valueOf()
156+
}).forEach(function (date) {
157+
date.selectable = false;
158+
})
159+
}
160+
}
161+
}
126162
})();

demo/index.html

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ <h4>No formatting</h4>
7777
</div>
7878
<div class="col-sm-6">
7979
<h3>Drop-down Datetime with input box</h3>
80-
<h4>Localized formatting using <a href="https://github.com/dalelotts/angular-date-time-input"><code>angular-date-time-input</code></a> directive</h4>
80+
<h4>Localized formatting using <a href="https://github.com/dalelotts/angular-date-time-input"><code>angular-date-time-input</code></a>
81+
directive</h4>
8182

8283
<p>Notice that you CAN enter a date with the keyboard.</p>
8384

@@ -90,7 +91,8 @@ <h4>Localized formatting using <a href="https://github.com/dalelotts/angular-dat
9091
<a class="dropdown-toggle" id="dropdown2" role="button" data-toggle="dropdown" data-target="#"
9192
href="#">
9293
<div class="input-group">
93-
<input type="text" class="form-control" data-ng-model="data.dateDropDownInput" data-date-time-input="YYYY-MM-DD HH:mm a">
94+
<input type="text" class="form-control" data-ng-model="data.dateDropDownInput"
95+
data-date-time-input="YYYY-MM-DD HH:mm a">
9496
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
9597
</div>
9698
</a>
@@ -355,7 +357,9 @@ <h4>Every time you click the button, the startView is changed</h4>
355357

356358
<p><code>configureOn: 'config-changed'</code> to cause the directive to re-read its configuration.</p>
357359

358-
<p><button class="btn btn-default" data-ng-click="changeConfig()">Click me to change startView</button></p>
360+
<p>
361+
<button class="btn btn-default" data-ng-click="changeConfig()">Click me to change startView</button>
362+
</p>
359363

360364
<div class="well">
361365
<p>Start View: {{ config.configureOnConfig.startView }}</p>
@@ -372,7 +376,9 @@ <h4>Every time you click the button, the selectable attribute is toggled.</h4>
372376

373377
<p><code>renderOn: 'valid-dates-changed'</code> to cause the directive to re-render.</p>
374378

375-
<p><button class="btn btn-default" data-ng-click="renderOnClick()">Click me to re-render</button></p>
379+
<p>
380+
<button class="btn btn-default" data-ng-click="renderOnClick()">Click me to re-render</button>
381+
</p>
376382

377383
<div class="well">
378384

@@ -384,8 +390,65 @@ <h4>Every time you click the button, the selectable attribute is toggled.</h4>
384390
</div>
385391

386392
</div>
387-
</div>
388393

394+
<div class="row">
395+
<div class="col-sm-6">
396+
<h3>Date range picker</h3>
397+
<h4>Every time you select a start date, dates before the start date are disabled in the end date.</h4>
398+
399+
<p>This is a little more complex than the other examples.</p>
400+
<p><strong>Start Date:</strong> <code>renderOn: 'end-date-changed'</code> to cause the directive to re-render when the end date changes,
401+
and <code>data-on-set-time="startDateOnSetTime()"</code> to broadcast when the start date changes,
402+
and finally <code>data-before-render="beforeRenderStartDate($dates)"</code>
403+
to disable the dates after the selected end date.</p>
404+
405+
<p><strong>End Date:</strong> <code>renderOn: 'start-date-changed'</code> to cause the directive to re-render when the start date changes,
406+
and <code>data-on-set-time="endDateOnSetTime()"</code> to broadcast when the end date changes,
407+
and finally <code>data-before-render="beforeRenderEndDate($view, $dates, $leftDate, $upDate, $rightDate)"</code>
408+
to disable the dates before the selected start date.</p>
409+
410+
<p>NB: It is possible that data coming from the server (or via a defect in the controller) that the start date is after the end date.
411+
To allow the user to get themselves out of this situation, your implementation might not disable any dates if the start date is greater than the end date.
412+
</p>
413+
414+
<div class="well">
415+
<div class="dropdown form-group">
416+
<label for="dateRangeStart">Start Date</label>
417+
<a class="dropdown-toggle" id="dropdownStart" role="button" data-toggle="dropdown" data-target="#"
418+
href="#">
419+
<div class="input-group date">
420+
<input id="dateRangeStart" type="text" class="form-control" data-ng-model="dateRangeStart">
421+
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
422+
</div>
423+
</a>
424+
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
425+
<datetimepicker data-ng-model="dateRangeStart"
426+
data-datetimepicker-config="{ dropdownSelector: '#dropdownStart', renderOn: 'end-date-changed' }"
427+
data-on-set-time="startDateOnSetTime()"
428+
data-before-render="startDateBeforeRender($dates)"></datetimepicker>
429+
</ul>
430+
</div>
431+
432+
<div class="dropdown form-group">
433+
<label for="dateRangeStart">End Date</label>
434+
<a class="dropdown-toggle" id="dropdownEnd" role="button" data-toggle="dropdown" data-target="#"
435+
href="#">
436+
<div class="input-group date">
437+
<input type="text" class="form-control" data-ng-model="dateRangeEnd">
438+
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
439+
</div>
440+
</a>
441+
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
442+
<datetimepicker data-ng-model="dateRangeEnd"
443+
data-datetimepicker-config="{ dropdownSelector: '#dropdownEnd', renderOn: 'start-date-changed' }"
444+
data-on-set-time="endDateOnSetTime()"
445+
data-before-render="endDateBeforeRender($view, $dates, $leftDate, $upDate, $rightDate)"></datetimepicker>
446+
</ul>
447+
</div>
448+
</div>
449+
</div>
450+
</div>
451+
</div>
389452

390453
</body>
391454
</html>

0 commit comments

Comments
 (0)