forked from kineticsocial/angularjs-datetime-picker
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathangularjs-datetime-picker.min.js
More file actions
20 lines (20 loc) · 12 KB
/
angularjs-datetime-picker.min.js
File metadata and controls
20 lines (20 loc) · 12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(function(){'use strict';angular.module('angularjs-datetime-picker',[]);var getTimezoneOffset=function(date){(typeof date=='string')&&(date=new Date(date));var jan=new Date(date.getFullYear(),0,1);var jul=new Date(date.getFullYear(),6,1);var stdTimezoneOffset=Math.max(jan.getTimezoneOffset(),jul.getTimezoneOffset());var isDST=date.getTimezoneOffset()<stdTimezoneOffset;var offset=isDST?stdTimezoneOffset-60:stdTimezoneOffset;var diff=offset>=0?'-':'+';return diff+("0"+(offset/60)).slice(-2)+':'+("0"+(offset%60)).slice(-2)};var DatetimePicker=function($compile,$document,$controller){var datetimePickerCtrl=$controller('DatetimePickerCtrl');return{open:function(options){datetimePickerCtrl.openDatetimePicker(options)},close:function(){datetimePickerCtrl.closeDatetimePicker()}}};DatetimePicker.$inject=['$compile','$document','$controller'];angular.module('angularjs-datetime-picker').factory('DatetimePicker',DatetimePicker);var DatetimePickerCtrl=function($compile,$document){var datetimePickerEl;var _this=this;var removeEl=function(el){el&&el.remove();$document[0].body.removeEventListener('click',_this.closeDatetimePicker)};this.openDatetimePicker=function(options){this.closeDatetimePicker();var div=angular.element('<div datetime-picker-popup ng-cloak></div>');options.dateFormat&&div.attr('date-format',options.dateFormat);options.ngModel&&div.attr('ng-model',options.ngModel);options.year&&div.attr('year',parseInt(options.year));options.month&&div.attr('month',parseInt(options.month));options.day&&div.attr('day',parseInt(options.day));options.hour&&div.attr('hour',parseInt(options.hour));options.minute&&div.attr('minute',parseInt(options.minute));options.allowClose&&div.attr('allow-close',options.allowClose);options.displaySelectedDate&&div.attr('display-selected-date',options.displaySelectedDate);options.ngChange&&div.attr('ng-change',options.ngChange);if(options.dateOnly===''||options.dateOnly===!0){div.attr('date-only','true')}
if(options.closeOnSelect==='false'){div.attr('close-on-select','false')}
var triggerEl=options.triggerEl;options.scope=options.scope||angular.element(triggerEl).scope();datetimePickerEl=$compile(div)(options.scope)[0];datetimePickerEl.triggerEl=options.triggerEl;$document[0].body.appendChild(datetimePickerEl);var bcr=triggerEl.getBoundingClientRect();options.scope.$apply();var datePickerElBcr=datetimePickerEl.getBoundingClientRect();datetimePickerEl.style.position='absolute';if(bcr.width>datePickerElBcr.width){datetimePickerEl.style.left=(bcr.left+bcr.width-datePickerElBcr.width+window.scrollX)+'px'}else{datetimePickerEl.style.left=(bcr.left+window.scrollX)+'px'}
if(bcr.top<500||window.innerHeight-bcr.bottom>500){datetimePickerEl.style.top=(bcr.bottom+window.scrollY)+'px'}else{datetimePickerEl.style.top=(bcr.top-datePickerElBcr.height+window.scrollY)+'px'}
$document[0].body.addEventListener('click',this.closeDatetimePicker)};this.closeDatetimePicker=function(evt){var target=evt&&evt.target;var popupEl=$document[0].querySelector('div[datetime-picker-popup]');if(evt&&target){if(target.hasAttribute('datetime-picker')){}else if(popupEl&&popupEl.contains(target)){}else{removeEl(popupEl)}}else{removeEl(popupEl)}}};DatetimePickerCtrl.$inject=['$compile','$document'];angular.module('angularjs-datetime-picker').controller('DatetimePickerCtrl',DatetimePickerCtrl);var tmpl=['<div class="angularjs-datetime-picker">',' <div class="adp-month adp-top" id="adp-top" style="display: none;">',' <span class="adp-prev" ></span>',' <div>',' <label class="timeLabel">Date:</label> {{ selectedDate | date: "mediumDate" }}<br />',' <a type="button" class="adp-link" ng-click="changeCurrentDate()">Change to today</a><br />',' <a type="button" class="adp-link" ng-click="clearSelectedDate()">Clear</a><br />',' </div>',' <button type="button" class="adp-next adp-close" ng-click="closeDatetimePicker()">x</button>',' </div>',' <div class="adp-month">',' <button type="button" class="adp-prev" ng-click="addMonth(-1)">«</button>',' <span title="{{months[mv.month].fullName}}">{{months[mv.month].shortName}}</span> {{mv.year}}',' <button type="button" class="adp-next" ng-click="addMonth(1)">»</button>',' </div>',' <div class="adp-days" ng-click="setDate($event)">',' <div class="adp-day-of-week" ng-repeat="dayOfWeek in ::daysOfWeek" title="{{dayOfWeek.fullName}}">{{::dayOfWeek.firstLetter}}</div>',' <div class="adp-day" ng-show="mv.leadingDays.length < 7" ng-repeat="day in mv.leadingDays">{{::day}}</div>',' <div class="adp-day selectable" ng-repeat="day in mv.days" ',' today="{{today}}" d2="{{mv.year + \'-\' + (mv.month + 1) + \'-\' + day}}"',' ng-class="{',' selected: (day == selectedDay),',' today: (today == (mv.year + \'-\' + (mv.month + 1) + \'-\' + day)),',' weekend: (mv.leadingDays.length + day)%7 == 1 || (mv.leadingDays.length + day)%7 == 0',' }">',' {{::day}}',' </div>',' <div class="adp-day" ng-show="mv.trailingDays.length < 7" ng-repeat="day in mv.trailingDays">{{::day}}</div>',' </div>',' <div class="adp-days" id="adp-time"> ',' <div class="adp-time"><label class="timeLabel">Time:</label> <span class="timeValue">{{ displayTime() }}</span></div><br/>',' <label class="hourLabel">Hour:</label> <input class="hourInput" type="range" min="0" max="23" ng-model="inputHour" ng-change="updateNgModel(selectedDay)" />',' <label class="minutesLabel">Min:</label> <input class="minutesInput" type="range" min="0" max="59" ng-model="inputMinute" ng-change="updateNgModel(selectedDay)"/> ',' </div> ',' <div class="adp-month adp-top" id="adp-bottom" style="display: none;">',' <a type="button" class="adp-link" ng-click="closeDatetimePicker()">OK</a>',' </div>','</div>'].join("\n");var datetimePickerPopup=function($locale,dateFilter){var days,months,daysOfWeek,firstDayOfWeek;var initVars=function(){days=[],months=[];daysOfWeek=[],firstDayOfWeek=0;for(var i=1;i<=31;i++){days.push(i)}
for(var i=0;i<12;i++){months.push({fullName:$locale.DATETIME_FORMATS.MONTH[i],shortName:$locale.DATETIME_FORMATS.SHORTMONTH[i]})}
for(var i=0;i<7;i++){var day=$locale.DATETIME_FORMATS.DAY[(i+firstDayOfWeek)%7];daysOfWeek.push({fullName:day,firstLetter:day.substr(0,1)})}
firstDayOfWeek=0};var getMonthView=function(year,month){if(month>11){year++}else if(month<0){year--}
month=(month+12)%12;var firstDayOfMonth=new Date(year,month,1),lastDayOfMonth=new Date(year,month+1,0),lastDayOfPreviousMonth=new Date(year,month,0),daysInMonth=lastDayOfMonth.getDate(),daysInLastMonth=lastDayOfPreviousMonth.getDate(),dayOfWeek=firstDayOfMonth.getDay(),leadingDays=(dayOfWeek-firstDayOfWeek+7)%7||7,trailingDays=days.slice(0,6*7-(leadingDays+daysInMonth));if(trailingDays.length>7){trailingDays=trailingDays.slice(0,trailingDays.length-7)}
return{year:year,month:month,days:days.slice(0,daysInMonth),leadingDays:days.slice(-leadingDays-(31-daysInLastMonth),daysInLastMonth),trailingDays:trailingDays}};var linkFunc=function(scope,element,attrs,ctrl){initVars();var dateFormat=attrs.dateFormat||'short';scope.months=months;scope.daysOfWeek=daysOfWeek;scope.inputHour;scope.inputMinute;if(scope.dateOnly===!0){element[0].querySelector('#adp-time').style.display='none'}
if(scope.allowClose===!0){element[0].querySelector('#adp-top').style.display='block';element[0].querySelector('#adp-bottom').style.display='block'}
scope.$applyAsync(function(){ctrl.triggerEl=angular.element(element[0].triggerEl);if(attrs.ngModel){var dateStr=''+ctrl.triggerEl.scope().$eval(attrs.ngModel);if(dateStr){if(!scope.displaySelectedDate){if(!dateStr.match(/[0-9]{2}:/)){dateStr+=" 00:00:00"}
dateStr=dateStr.replace(/([0-9]{2}-[0-9]{2})-([0-9]{4})/,'$2-$1');dateStr=dateStr.replace(/([\/-][0-9]{2,4})\ ([0-9]{2}\:[0-9]{2}\:)/,'$1T$2');dateStr=dateStr.replace(/EDT|EST|CDT|CST|MDT|PDT|PST|UT|GMT/g,'');dateStr=dateStr.replace(/\s*\(\)\s*/,'');dateStr=dateStr.replace(/[\-\+][0-9]{2}:?[0-9]{2}$/,'');dateStr+=getTimezoneOffset(dateStr)}
var d=new Date(dateStr);scope.selectedDate=new Date(d.getFullYear(),d.getMonth(),d.getDate(),d.getHours(),d.getMinutes(),d.getSeconds())}}
if(!scope.selectedDate||isNaN(scope.selectedDate.getTime())){var today=new Date();var year=scope.year||today.getFullYear();var month=scope.month?(scope.month-1):today.getMonth();var day=scope.day||today.getDate();var hour=scope.hour||scope.hour===0?scope.hour:today.getHours();var minute=scope.minute||scope.minute===0?scope.minute:today.getMinutes();scope.selectedDate=new Date(year,month,day,hour,minute,0)}
scope.inputHour=scope.selectedDate.getHours();scope.inputMinute=scope.selectedDate.getMinutes();scope.mv=getMonthView(scope.selectedDate.getFullYear(),scope.selectedDate.getMonth());scope.today=dateFilter(new Date(),'yyyy-M-d');if(scope.mv.year==scope.selectedDate.getFullYear()&&scope.mv.month==scope.selectedDate.getMonth()){scope.selectedDay=scope.selectedDate.getDate()}else{scope.selectedDay=null}});scope.changeCurrentDate=function(){scope.selectedDate=new Date();scope.mv=getMonthView(scope.selectedDate.getFullYear(),scope.selectedDate.getMonth());scope.today=dateFilter(scope.selectedDate,'yyyy-M-d');scope.selectedDay=scope.selectedDate.getDate();if(attrs.ngModel){var elScope=ctrl.triggerEl.scope();elScope.$eval(attrs.ngModel+'= date',{date:scope.selectedDate})}};scope.displayTime=function(){if(scope.inputMinute==null||scope.inputHour==null)
return "";return("0"+scope.inputHour).slice(-2)+":"+("0"+scope.inputMinute).slice(-2)};scope.clearSelectedDate=function(){scope.selectedDate=null;scope.selectedDay=null;scope.inputHour=null;scope.inputMinute=null;if(attrs.ngModel){var elScope=ctrl.triggerEl.scope();elScope.$eval(attrs.ngModel+'= date',{date:null})}};scope.addMonth=function(amount){scope.mv=getMonthView(scope.mv.year,scope.mv.month+amount)};scope.closeDatetimePicker=function(){ctrl.closeDatetimePicker()};scope.setDate=function(evt){var target=angular.element(evt.target)[0];if(target.className.indexOf('selectable')!==-1){scope.updateNgModel(parseInt(target.innerHTML));if(scope.closeOnSelect!==!1){ctrl.closeDatetimePicker()}}};scope.updateNgModel=function(day){day=day?day:scope.selectedDate.getDate();scope.selectedDate=new Date(scope.mv.year,scope.mv.month,day,scope.inputHour,scope.inputMinute,0);scope.selectedDay=scope.selectedDate.getDate();if(attrs.ngModel){scope.selectedDateUTC=new Date(scope.mv.year,scope.mv.month,day,scope.inputHour,scope.inputMinute,0);scope.selectedDateUTC.setMinutes(scope.selectedDateUTC.getMinutes()+scope.selectedDateUTC.getTimezoneOffset());var elScope=ctrl.triggerEl.scope(),dateValue;if(elScope.$eval(attrs.ngModel)&&elScope.$eval(attrs.ngModel).constructor.name==='Date'){dateValue=new Date(dateFilter(scope.selectedDateUTC,dateFormat))}else{dateValue=dateFilter(scope.selectedDateUTC,dateFormat)}
elScope.$eval(attrs.ngModel+'= date',{date:dateValue})}};scope.$on('$destroy',ctrl.closeDatetimePicker)};return{restrict:'A',template:tmpl,controller:'DatetimePickerCtrl',replace:!0,scope:{year:'=',month:'=',day:'=',hour:'=',minute:'=',dateOnly:'=',closeOnSelect:'=',allowClose:'=',displaySelectedDate:'=',ngChange:'=?'},link:linkFunc}};datetimePickerPopup.$inject=['$locale','dateFilter'];angular.module('angularjs-datetime-picker').directive('datetimePickerPopup',datetimePickerPopup);var datetimePicker=function($parse,DatetimePicker){return{require:'ngModel',link:function(scope,element,attrs,ctrl){scope.$watch(attrs.ngModel,function(value){if(!value||value==''){return}
var date=new Date(value);ctrl.$setValidity('date',!date?!1:!0);var now=new Date();if(attrs.hasOwnProperty('futureOnly')){ctrl.$setValidity('future-only',date<now?!1:!0)}
ctrl.$setViewValue(value)});element[0].addEventListener('click',function(){DatetimePicker.open({triggerEl:element[0],dateFormat:attrs.dateFormat,ngModel:attrs.ngModel,year:attrs.year,month:attrs.month,day:attrs.day,hour:attrs.hour,minute:attrs.minute,dateOnly:attrs.dateOnly,futureOnly:attrs.futureOnly,closeOnSelect:attrs.closeOnSelect,displaySelectedDate:attrs.displaySelectedDate,allowClose:attrs.allowClose,ngChange:attrs.ngChange})})}}};datetimePicker.$inject=['$parse','DatetimePicker'];angular.module('angularjs-datetime-picker').directive('datetimePicker',datetimePicker)})()