@@ -94,7 +94,7 @@ angular.module('ui.bootstrap.datetimepicker', [])
9494 " <thead>" +
9595 " <tr>" +
9696 " <th class='left' data-ng-click='changeView(data.currentView, data.leftDate, $event)' data-ng-show='data.leftDate.selectable'><i class='glyphicon glyphicon-arrow-left'/></th>" +
97- " <th class='switch' colspan='5' data-ng-show='data.currentDate .selectable' data-ng-click='changeView(data.previousView, data.currentDate , $event)'>{{ data.currentDate .display }}</th>" +
97+ " <th class='switch' colspan='5' data-ng-show='data.previousViewDate .selectable' data-ng-click='changeView(data.previousView, data.previousViewDate , $event)'>{{ data.previousViewDate .display }}</th>" +
9898 " <th class='right' data-ng-click='changeView(data.currentView, data.rightDate, $event)' data-ng-show='data.rightDate.selectable'><i class='glyphicon glyphicon-arrow-right'/></th>" +
9999 " </tr>" +
100100 " <tr>" +
@@ -124,7 +124,7 @@ angular.module('ui.bootstrap.datetimepicker', [])
124124 beforeRender : "&"
125125 } ,
126126 replace : true ,
127- link : function ( scope , element , attrs ) {
127+ link : function ( scope , element , attrs , ngModelController ) {
128128
129129 var directiveConfig = { } ;
130130
@@ -138,22 +138,28 @@ angular.module('ui.bootstrap.datetimepicker', [])
138138
139139 validateConfiguration ( configuration ) ;
140140
141+ var startOfDecade = function ( unixDate ) {
142+ var startYear = ( parseInt ( moment . utc ( unixDate ) . year ( ) / 10 , 10 ) * 10 ) ;
143+ return moment . utc ( unixDate ) . year ( startYear ) . startOf ( 'year' ) ;
144+ } ;
145+
141146 var dataFactory = {
142147 year : function ( unixDate ) {
143148 var selectedDate = moment . utc ( unixDate ) . startOf ( 'year' ) ;
144149 // View starts one year before the decade starts and ends one year after the decade ends
145150 // i.e. passing in a date of 1/1/2013 will give a range of 2009 to 2020
146151 // Truncate the last digit from the current year and subtract 1 to get the start of the decade
147152 var startDecade = ( parseInt ( selectedDate . year ( ) / 10 , 10 ) * 10 ) ;
148- var startDate = moment . utc ( selectedDate ) . year ( startDecade - 1 ) . startOf ( 'year' ) ;
149- var activeYear = scope . ngModel ? moment ( scope . ngModel ) . year ( ) : 0 ;
153+ var startDate = moment . utc ( startOfDecade ( unixDate ) ) . subtract ( 1 , 'year' ) . startOf ( 'year' ) ;
154+
155+ var activeYear = ngModelController . $modelValue ? moment ( ngModelController . $modelValue ) . year ( ) : 0 ;
150156
151157 var result = {
152158 'currentView' : 'year' ,
153159 'nextView' : configuration . minView === 'year' ? 'setTime' : 'month' ,
154- 'currentDate ' : new DateObject ( { dateValue : null , display : startDecade + '-' + ( startDecade + 9 ) } ) ,
155- 'leftDate' : new DateObject ( { dateValue : moment . utc ( startDate ) . subtract ( 9 , 'year' ) . valueOf ( ) } ) ,
156- 'rightDate' : new DateObject ( { dateValue : moment . utc ( startDate ) . add ( 11 , 'year' ) . valueOf ( ) } ) ,
160+ 'previousViewDate ' : new DateObject ( { dateValue : null , display : startDecade + '-' + ( startDecade + 9 ) } ) ,
161+ 'leftDate' : new DateObject ( { dateValue : moment . utc ( startDate ) . subtract ( 9 , 'year' ) . valueOf ( ) } ) ,
162+ 'rightDate' : new DateObject ( { dateValue : moment . utc ( startDate ) . add ( 11 , 'year' ) . valueOf ( ) } ) ,
157163 'dates' : [ ]
158164 } ;
159165
@@ -176,16 +182,19 @@ angular.module('ui.bootstrap.datetimepicker', [])
176182 month : function ( unixDate ) {
177183
178184 var startDate = moment . utc ( unixDate ) . startOf ( 'year' ) ;
179-
180- var activeDate = scope . ngModel ? moment ( scope . ngModel ) . format ( 'YYYY-MMM' ) : 0 ;
185+ var previousViewDate = startOfDecade ( unixDate ) ;
186+ var activeDate = ngModelController . $modelValue ? moment ( ngModelController . $modelValue ) . format ( 'YYYY-MMM' ) : 0 ;
181187
182188 var result = {
183189 'previousView' : 'year' ,
184190 'currentView' : 'month' ,
185191 'nextView' : configuration . minView === 'month' ? 'setTime' : 'day' ,
186- 'currentDate' : new DateObject ( { dateValue : startDate . valueOf ( ) , display : startDate . format ( 'YYYY' ) } ) ,
187- 'leftDate' : new DateObject ( { dateValue : moment . utc ( startDate ) . subtract ( 1 , 'year' ) . valueOf ( ) } ) ,
188- 'rightDate' : new DateObject ( { dateValue : moment . utc ( startDate ) . add ( 1 , 'year' ) . valueOf ( ) } ) ,
192+ 'previousViewDate' : new DateObject ( {
193+ dateValue : previousViewDate . valueOf ( ) ,
194+ display : startDate . format ( 'YYYY' )
195+ } ) ,
196+ 'leftDate' : new DateObject ( { dateValue : moment . utc ( startDate ) . subtract ( 1 , 'year' ) . valueOf ( ) } ) ,
197+ 'rightDate' : new DateObject ( { dateValue : moment . utc ( startDate ) . add ( 1 , 'year' ) . valueOf ( ) } ) ,
189198 'dates' : [ ]
190199 } ;
191200
@@ -207,19 +216,23 @@ angular.module('ui.bootstrap.datetimepicker', [])
207216
208217 var selectedDate = moment . utc ( unixDate ) ;
209218 var startOfMonth = moment . utc ( selectedDate ) . startOf ( 'month' ) ;
219+ var previousViewDate = moment . utc ( selectedDate ) . startOf ( 'year' ) ;
210220 var endOfMonth = moment . utc ( selectedDate ) . endOf ( 'month' ) ;
211221
212222 var startDate = moment . utc ( startOfMonth ) . subtract ( Math . abs ( startOfMonth . weekday ( ) ) , 'days' ) ;
213223
214- var activeDate = scope . ngModel ? moment ( scope . ngModel ) . format ( 'YYYY-MMM-DD' ) : '' ;
224+ var activeDate = ngModelController . $modelValue ? moment ( ngModelController . $modelValue ) . format ( 'YYYY-MMM-DD' ) : '' ;
215225
216226 var result = {
217227 'previousView' : 'month' ,
218228 'currentView' : 'day' ,
219229 'nextView' : configuration . minView === 'day' ? 'setTime' : 'hour' ,
220- 'currentDate' : new DateObject ( { dateValue : startDate . valueOf ( ) , display : selectedDate . format ( 'YYYY-MMM' ) } ) ,
221- 'leftDate' : new DateObject ( { dateValue : moment . utc ( startOfMonth ) . subtract ( 1 , 'months' ) . valueOf ( ) } ) ,
222- 'rightDate' : new DateObject ( { dateValue : moment . utc ( startOfMonth ) . add ( 1 , 'months' ) . valueOf ( ) } ) ,
230+ 'previousViewDate' : new DateObject ( {
231+ dateValue : previousViewDate . valueOf ( ) ,
232+ display : startOfMonth . format ( 'YYYY-MMM' )
233+ } ) ,
234+ 'leftDate' : new DateObject ( { dateValue : moment . utc ( startOfMonth ) . subtract ( 1 , 'months' ) . valueOf ( ) } ) ,
235+ 'rightDate' : new DateObject ( { dateValue : moment . utc ( startOfMonth ) . add ( 1 , 'months' ) . valueOf ( ) } ) ,
223236 'dayNames' : [ ] ,
224237 'weeks' : [ ]
225238 } ;
@@ -249,17 +262,21 @@ angular.module('ui.bootstrap.datetimepicker', [])
249262 } ,
250263
251264 hour : function ( unixDate ) {
252- var selectedDate = moment . utc ( unixDate ) . hour ( 0 ) . minute ( 0 ) . second ( 0 ) ;
265+ var selectedDate = moment . utc ( unixDate ) . startOf ( 'day' ) ;
266+ var previousViewDate = moment . utc ( selectedDate ) . startOf ( 'month' ) ;
253267
254- var activeFormat = scope . ngModel ? moment ( scope . ngModel ) . format ( 'YYYY-MM-DD H' ) : '' ;
268+ var activeFormat = ngModelController . $modelValue ? moment ( ngModelController . $modelValue ) . format ( 'YYYY-MM-DD H' ) : '' ;
255269
256270 var result = {
257271 'previousView' : 'day' ,
258272 'currentView' : 'hour' ,
259273 'nextView' : configuration . minView === 'hour' ? 'setTime' : 'minute' ,
260- 'currentDate' : new DateObject ( { dateValue : selectedDate . valueOf ( ) , display : selectedDate . format ( 'll' ) } ) ,
261- 'leftDate' : new DateObject ( { dateValue : moment . utc ( selectedDate ) . subtract ( 1 , 'days' ) . valueOf ( ) } ) ,
262- 'rightDate' : new DateObject ( { dateValue : moment . utc ( selectedDate ) . add ( 1 , 'days' ) . valueOf ( ) } ) ,
274+ 'previousViewDate' : new DateObject ( {
275+ dateValue : previousViewDate . valueOf ( ) ,
276+ display : selectedDate . format ( 'll' )
277+ } ) ,
278+ 'leftDate' : new DateObject ( { dateValue : moment . utc ( selectedDate ) . subtract ( 1 , 'days' ) . valueOf ( ) } ) ,
279+ 'rightDate' : new DateObject ( { dateValue : moment . utc ( selectedDate ) . add ( 1 , 'days' ) . valueOf ( ) } ) ,
263280 'dates' : [ ]
264281 } ;
265282
@@ -278,17 +295,20 @@ angular.module('ui.bootstrap.datetimepicker', [])
278295 } ,
279296
280297 minute : function ( unixDate ) {
281- var selectedDate = moment . utc ( unixDate ) . minute ( 0 ) . second ( 0 ) ;
282-
283- var activeFormat = scope . ngModel ? moment ( scope . ngModel ) . format ( 'YYYY-MM-DD H:mm' ) : '' ;
298+ var selectedDate = moment . utc ( unixDate ) . startOf ( 'hour' ) ;
299+ var previousViewDate = moment . utc ( selectedDate ) . startOf ( 'day' ) ;
300+ var activeFormat = ngModelController . $modelValue ? moment ( ngModelController . $modelValue ) . format ( 'YYYY-MM-DD H:mm' ) : '' ;
284301
285302 var result = {
286303 'previousView' : 'hour' ,
287304 'currentView' : 'minute' ,
288305 'nextView' : 'setTime' ,
289- 'currentDate' : new DateObject ( { dateValue : selectedDate . valueOf ( ) , display : selectedDate . format ( 'lll' ) } ) ,
290- 'leftDate' : new DateObject ( { dateValue : moment . utc ( selectedDate ) . subtract ( 1 , 'hours' ) . valueOf ( ) } ) ,
291- 'rightDate' : new DateObject ( { dateValue : moment . utc ( selectedDate ) . add ( 1 , 'hours' ) . valueOf ( ) } ) ,
306+ 'previousViewDate' : new DateObject ( {
307+ dateValue : previousViewDate . valueOf ( ) ,
308+ display : selectedDate . format ( 'lll' )
309+ } ) ,
310+ 'leftDate' : new DateObject ( { dateValue : moment . utc ( selectedDate ) . subtract ( 1 , 'hours' ) . valueOf ( ) } ) ,
311+ 'rightDate' : new DateObject ( { dateValue : moment . utc ( selectedDate ) . add ( 1 , 'hours' ) . valueOf ( ) } ) ,
292312 'dates' : [ ]
293313 } ;
294314
@@ -312,21 +332,21 @@ angular.module('ui.bootstrap.datetimepicker', [])
312332 var tempDate = new Date ( unixDate ) ;
313333 var newDate = new Date ( tempDate . getTime ( ) + ( tempDate . getTimezoneOffset ( ) * 60000 ) ) ;
314334
315- var oldDate = scope . ngModel ;
316- scope . ngModel = newDate ;
335+ var oldDate = ngModelController . $modelValue ;
336+ ngModelController . $setViewValue ( newDate ) ;
317337
318338 if ( configuration . dropdownSelector ) {
319339 jQuery ( configuration . dropdownSelector ) . dropdown ( 'toggle' ) ;
320340 }
321341
322- scope . onSetTime ( { newDate : scope . ngModel , oldDate : oldDate } ) ;
342+ scope . onSetTime ( { newDate : newDate , oldDate : oldDate } ) ;
323343
324344 return dataFactory [ configuration . startView ] ( unixDate ) ;
325345 }
326346 } ;
327347
328- var getUTCTime = function ( ) {
329- var tempDate = ( scope . ngModel ? moment ( scope . ngModel ) . toDate ( ) : new Date ( ) ) ;
348+ var getUTCTime = function ( modelValue ) {
349+ var tempDate = ( modelValue ? moment ( modelValue ) . toDate ( ) : new Date ( ) ) ;
330350 return tempDate . getTime ( ) - ( tempDate . getTimezoneOffset ( ) * 60000 ) ;
331351 } ;
332352
@@ -354,19 +374,28 @@ angular.module('ui.bootstrap.datetimepicker', [])
354374 $view : result . currentView ,
355375 $dates : result . dates || weekDates ,
356376 $leftDate : result . leftDate ,
357- $upDate : result . currentDate ,
377+ $upDate : result . previousViewDate ,
358378 $rightDate : result . rightDate
359379 } ) ;
360380
361381 scope . data = result ;
362382 }
363383 } ;
364384
365- scope . changeView ( configuration . startView , new DateObject ( { dateValue : getUTCTime ( ) , selectable : true } ) ) ;
385+ // While is **seems** like the next line should use ngModelController.$modelValue rather than scope.ngModel,
386+ // in fact ngModelController.$modelValue is always NaN for the first call (even if ngModel has a value),
387+ // resulting in an initial rendering with the current date. (at least on angular 1.2.26)
388+ // This results in a call to the beforeRender callback with today's date as the model value when the developer
389+ // would reasonably expect the current model value.
390+
391+ scope . changeView ( configuration . startView , new DateObject ( {
392+ dateValue : getUTCTime ( scope . ngModel ) ,
393+ selectable : true
394+ } ) ) ;
366395
367- scope . $watch ( 'ngModel' , function ( ) {
368- scope . changeView ( scope . data . currentView , new DateObject ( { dateValue : getUTCTime ( ) } ) ) ;
369- } ) ;
396+ ngModelController . $render = function ( ) {
397+ scope . changeView ( scope . data . currentView , new DateObject ( { dateValue : getUTCTime ( ngModelController . $modelValue ) } ) ) ;
398+ } ;
370399 }
371400 } ;
372401 } ] ) ;
0 commit comments