|
2 | 2 | /*jslint vars:true */
|
3 | 3 |
|
4 | 4 | /**
|
5 |
| - * @license angular-bootstrap-datetimepicker version: 0.3.15 |
| 5 | + * @license angular-bootstrap-datetimepicker version: 0.4.0 |
6 | 6 | * Copyright 2015 Knight Rider Consulting, Inc. http://www.knightrider.com
|
7 | 7 | * License: MIT
|
8 | 8 | */
|
|
32 | 32 | dropdownSelector: null,
|
33 | 33 | minuteStep: 5,
|
34 | 34 | minView: 'minute',
|
| 35 | + modelType: 'Date', |
| 36 | + parseFormat: 'YYYY-MM-DDTHH:mm:ss.SSSZZ', |
35 | 37 | renderOn: null,
|
36 | 38 | startView: 'day'
|
37 | 39 | })
|
|
67 | 69 | 'dropdownSelector',
|
68 | 70 | 'minuteStep',
|
69 | 71 | 'minView',
|
| 72 | + 'modelType', |
| 73 | + 'parseFormat', |
70 | 74 | 'renderOn',
|
71 | 75 | 'startView'
|
72 | 76 | ];
|
|
111 | 115 | if (configuration.renderOn !== null && configuration.renderOn.length < 1) {
|
112 | 116 | throw ('renderOn must not be an empty string');
|
113 | 117 | }
|
| 118 | + if (configuration.modelType !== null && !angular.isString(configuration.modelType)) { |
| 119 | + throw ('modelType must be a string'); |
| 120 | + } |
| 121 | + if (configuration.modelType !== null && configuration.modelType.length < 1) { |
| 122 | + throw ('modelType must not be an empty string'); |
| 123 | + } |
| 124 | + if (configuration.modelType !== 'Date' && configuration.modelType !== 'moment' && configuration.modelType !== 'milliseconds') { |
| 125 | + // modelType contains string format, overriding parseFormat with modelType |
| 126 | + configuration.parseFormat = configuration.modelType; |
| 127 | + } |
114 | 128 | if (configuration.dropdownSelector !== null && !angular.isString(configuration.dropdownSelector)) {
|
115 | 129 | throw ('dropdownSelector must be a string');
|
116 | 130 | }
|
|
182 | 196 | var configuration = configure();
|
183 | 197 |
|
184 | 198 |
|
185 |
| - var startOfDecade = function startOfDecade(unixDate) { |
186 |
| - var startYear = (parseInt(moment.utc(unixDate).year() / 10, 10) * 10); |
187 |
| - return moment.utc(unixDate).year(startYear).startOf('year'); |
| 199 | + var startOfDecade = function startOfDecade(milliseconds) { |
| 200 | + var startYear = (parseInt(moment.utc(milliseconds).year() / 10, 10) * 10); |
| 201 | + return moment.utc(milliseconds).year(startYear).startOf('year'); |
| 202 | + }; |
| 203 | + |
| 204 | + var formatValue = function formatValue(timeValue, formatString) { |
| 205 | + if (timeValue) { |
| 206 | + return getMoment(timeValue).format(formatString); |
| 207 | + } else { |
| 208 | + return ''; |
| 209 | + } |
| 210 | + }; |
| 211 | + |
| 212 | + /** |
| 213 | + * Converts a time value into a moment. |
| 214 | + * |
| 215 | + * This function is now necessary because moment logs a warning when parsing a string without a format. |
| 216 | + * @param modelValue |
| 217 | + * a time value in any of the supported formats (Date, moment, milliseconds, and string) |
| 218 | + * @returns {moment} |
| 219 | + * representing the specified time value. |
| 220 | + */ |
| 221 | + |
| 222 | + var getMoment = function getMoment(modelValue) { |
| 223 | + return moment(modelValue, angular.isString(modelValue) ? configuration.parseFormat : undefined); |
| 224 | + }; |
| 225 | + |
| 226 | + /** |
| 227 | + * Converts a time value to UCT/GMT time. |
| 228 | + * @param modelValue |
| 229 | + * a time value in any of the supported formats (Date, moment, milliseconds, and string) |
| 230 | + * @returns {number} |
| 231 | + * number of milliseconds since 1/1/1970 |
| 232 | + */ |
| 233 | + |
| 234 | + var getUTCTime = function getUTCTime(modelValue) { |
| 235 | + var tempDate = new Date(); |
| 236 | + if (modelValue) { |
| 237 | + var tempMoment = getMoment(modelValue); |
| 238 | + if (tempMoment.isValid()) { |
| 239 | + tempDate = tempMoment.toDate(); |
| 240 | + } else { |
| 241 | + throw 'Invalid date: ' + modelValue; |
| 242 | + } |
| 243 | + } |
| 244 | + return tempDate.getTime() - (tempDate.getTimezoneOffset() * 60000); |
188 | 245 | };
|
189 | 246 |
|
190 | 247 | var dataFactory = {
|
191 |
| - year: function year(unixDate) { |
192 |
| - var selectedDate = moment.utc(unixDate).startOf('year'); |
| 248 | + year: function year(milliseconds) { |
| 249 | + var selectedDate = moment.utc(milliseconds).startOf('year'); |
193 | 250 | // View starts one year before the decade starts and ends one year after the decade ends
|
194 | 251 | // i.e. passing in a date of 1/1/2013 will give a range of 2009 to 2020
|
195 | 252 | // Truncate the last digit from the current year and subtract 1 to get the start of the decade
|
196 | 253 | var startDecade = (parseInt(selectedDate.year() / 10, 10) * 10);
|
197 |
| - var startDate = moment.utc(startOfDecade(unixDate)).subtract(1, 'year').startOf('year'); |
| 254 | + var startDate = moment.utc(startOfDecade(milliseconds)).subtract(1, 'year').startOf('year'); |
198 | 255 |
|
199 |
| - var activeYear = ngModelController.$modelValue ? moment(ngModelController.$modelValue).year() : 0; |
| 256 | + var activeYear = formatValue(ngModelController.$modelValue, 'YYYY'); |
200 | 257 |
|
201 | 258 | var result = {
|
202 | 259 | 'currentView': 'year',
|
|
217 | 274 | 'display': yearMoment.format('YYYY'),
|
218 | 275 | 'past': yearMoment.year() < startDecade,
|
219 | 276 | 'future': yearMoment.year() > startDecade + 9,
|
220 |
| - 'active': yearMoment.year() === activeYear |
| 277 | + 'active': yearMoment.format('YYYY') === activeYear |
221 | 278 | };
|
222 | 279 |
|
223 | 280 | result.dates.push(new DateObject(dateValue));
|
|
226 | 283 | return result;
|
227 | 284 | },
|
228 | 285 |
|
229 |
| - month: function month(unixDate) { |
| 286 | + month: function month(milliseconds) { |
230 | 287 |
|
231 |
| - var startDate = moment.utc(unixDate).startOf('year'); |
232 |
| - var previousViewDate = startOfDecade(unixDate); |
233 |
| - var activeDate = ngModelController.$modelValue ? moment(ngModelController.$modelValue).format('YYYY-MMM') : 0; |
| 288 | + var startDate = moment.utc(milliseconds).startOf('year'); |
| 289 | + var previousViewDate = startOfDecade(milliseconds); |
| 290 | + var activeDate = formatValue(ngModelController.$modelValue, 'YYYY-MMM'); |
234 | 291 |
|
235 | 292 | var result = {
|
236 | 293 | 'previousView': 'year',
|
|
259 | 316 | return result;
|
260 | 317 | },
|
261 | 318 |
|
262 |
| - day: function day(unixDate) { |
| 319 | + day: function day(milliseconds) { |
263 | 320 |
|
264 |
| - var selectedDate = moment.utc(unixDate); |
| 321 | + var selectedDate = moment.utc(milliseconds); |
265 | 322 | var startOfMonth = moment.utc(selectedDate).startOf('month');
|
266 | 323 | var previousViewDate = moment.utc(selectedDate).startOf('year');
|
267 | 324 | var endOfMonth = moment.utc(selectedDate).endOf('month');
|
268 | 325 |
|
269 | 326 | var startDate = moment.utc(startOfMonth).subtract(Math.abs(startOfMonth.weekday()), 'days');
|
270 | 327 |
|
271 |
| - var activeDate = ngModelController.$modelValue ? moment(ngModelController.$modelValue).format('YYYY-MMM-DD') : ''; |
| 328 | + var activeDate = formatValue(ngModelController.$modelValue, 'YYYY-MMM-DD'); |
272 | 329 |
|
273 | 330 | var result = {
|
274 | 331 | 'previousView': 'month',
|
|
308 | 365 | return result;
|
309 | 366 | },
|
310 | 367 |
|
311 |
| - hour: function hour(unixDate) { |
312 |
| - var selectedDate = moment.utc(unixDate).startOf('day'); |
| 368 | + hour: function hour(milliseconds) { |
| 369 | + var selectedDate = moment.utc(milliseconds).startOf('day'); |
313 | 370 | var previousViewDate = moment.utc(selectedDate).startOf('month');
|
314 | 371 |
|
315 |
| - var activeFormat = ngModelController.$modelValue ? moment(ngModelController.$modelValue).format('YYYY-MM-DD H') : ''; |
| 372 | + var activeFormat = formatValue(ngModelController.$modelValue, 'YYYY-MM-DD H'); |
316 | 373 |
|
317 | 374 | var result = {
|
318 | 375 | 'previousView': 'day',
|
|
341 | 398 | return result;
|
342 | 399 | },
|
343 | 400 |
|
344 |
| - minute: function minute(unixDate) { |
345 |
| - var selectedDate = moment.utc(unixDate).startOf('hour'); |
| 401 | + minute: function minute(milliseconds) { |
| 402 | + var selectedDate = moment.utc(milliseconds).startOf('hour'); |
346 | 403 | var previousViewDate = moment.utc(selectedDate).startOf('day');
|
347 |
| - var activeFormat = ngModelController.$modelValue ? moment(ngModelController.$modelValue).format('YYYY-MM-DD H:mm') : ''; |
| 404 | + var activeFormat = formatValue(ngModelController.$modelValue, 'YYYY-MM-DD H:mm'); |
348 | 405 |
|
349 | 406 | var result = {
|
350 | 407 | 'previousView': 'hour',
|
|
375 | 432 | return result;
|
376 | 433 | },
|
377 | 434 |
|
378 |
| - setTime: function setTime(unixDate) { |
379 |
| - var tempDate = new Date(unixDate); |
| 435 | + setTime: function setTime(milliseconds) { |
| 436 | + var tempDate = new Date(milliseconds); |
380 | 437 | var newDate = new Date(tempDate.getUTCFullYear(), tempDate.getUTCMonth(), tempDate.getUTCDate(), tempDate.getUTCHours(), tempDate.getUTCMinutes(), tempDate.getUTCSeconds(), tempDate.getUTCMilliseconds());
|
381 | 438 |
|
| 439 | + switch (configuration.modelType) { |
| 440 | + case 'Date': |
| 441 | + // No additional work needed |
| 442 | + break; |
| 443 | + case 'moment': |
| 444 | + newDate = moment(newDate); |
| 445 | + break; |
| 446 | + case 'milliseconds': |
| 447 | + newDate = milliseconds; |
| 448 | + break; |
| 449 | + default: // It is assumed that the modelType is a formatting string. |
| 450 | + newDate = moment(newDate).format(configuration.modelType); |
| 451 | + } |
| 452 | + |
382 | 453 | var oldDate = ngModelController.$modelValue;
|
383 | 454 | ngModelController.$setViewValue(newDate);
|
384 | 455 |
|
|
388 | 459 |
|
389 | 460 | scope.onSetTime({newDate: newDate, oldDate: oldDate});
|
390 | 461 |
|
391 |
| - return dataFactory[configuration.startView](unixDate); |
| 462 | + return dataFactory[configuration.startView](milliseconds); |
392 | 463 | }
|
393 | 464 | };
|
394 | 465 |
|
395 |
| - var getUTCTime = function getUTCTime(modelValue) { |
396 |
| - var tempDate = (modelValue ? moment(modelValue).toDate() : new Date()); |
397 |
| - return tempDate.getTime() - (tempDate.getTimezoneOffset() * 60000); |
398 |
| - }; |
399 |
| - |
400 | 466 | scope.changeView = function changeView(viewName, dateObject, event) {
|
401 | 467 | if (event) {
|
402 | 468 | event.stopPropagation();
|
|
0 commit comments