UNPKG

adm-dtp

Version:
1,113 lines (973 loc) 74.9 kB
/* * Picking date & time in AngularJS is easier than ever. * * Demo: http://amirkabirdataminers.github.io/ADM-dateTimePicker * * @version 1.2.0 * * © 2017 Amirkabir Data Miners <info@adm-co.net> - www.adm-co.net */ (function(angular) { 'use strict'; if (!angular.merge) angular.merge = angular.extend; String.prototype.toPersianDigits = function(){ var id= ['۰','۱','۲','۳','۴','۵','۶','۷','۸','۹']; return this.replace(/[0-9]/g, function(w){ return id[+w] }); }; String.prototype.toEnglishDigits = function(){ var id= {'۰':'0','۱':'1','۲':'2','۳':'3','۴':'4','۵':'5','۶':'6','۷':'7','۸':'8','۹':'9'}; return this.replace(/[^0-9.]/g, function(w){ return id[w]||w; }); }; String.prototype.lZero = function() { return (this.length<2 ? '0'+this : this); }; Array.prototype.toNumber = function() { return this.map(function(item) {return Number(item);}); }; Array.prototype.dtp_toDate = function(type) { var splitter = '-'; if (/invalid/i.test(new Date('1991-9-12'))) splitter = '/'; var date = this.join(splitter); if (this.length == 5) date = this.slice(0,3).join(splitter) +' '+ this.slice(3,5).join(':') if (!type) return date; date = new Date(date); if (type == 'unix') return date.getTime(); return date; }; Number.prototype.lZero = function() { return (this<10 ? '0'+this : this); }; Date.prototype.dtp_shortDate = function () { return [this.getFullYear(), this.getMonth() + 1, this.getDate()].dtp_toDate(); } var ADMdtpProvider = function() { var options = { calType: 'gregorian', format: 'YYYY/MM/DD hh:mm', multiple: true, autoClose: false, transition: true, disabled: [], smartDisabling: true, minuteStep: 1, gregorianStartDay: 0, gregorianDic: { title: 'Gregorian', monthsNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], daysNames: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], todayBtn: 'Today', }, jalaliDic: { title: 'جلالی', monthsNames: ['فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند'], daysNames: ['ش', 'ی', 'د', 'س', 'چ', 'پ', 'ج'], todayBtn: 'امروز' } }; var ADMdtp = { getOptions: function(type) { var typeOptions = type && options[type] || options; return typeOptions; } }; this.setOptions = function(type, customOptions) { if (!customOptions) { customOptions = type; options = angular.merge(options, customOptions); return; } options[type] = angular.merge(options[type] || {}, customOptions); }; this.$get = function() { return ADMdtp; }; }; var ADMdtpDigitTypeFilter = function() { return function(input, type) { return type=='jalali' ? String(input).toPersianDigits() : input; }; }; var ADMdtpConvertor = function() { function getJalaliDate(date) { var daysPassedInGregorianCalender = getDaysPassedInGregorianCalender(date); daysPassedInGregorianCalender -= 226894; return getJalaliDateOfDay(daysPassedInGregorianCalender); } function getJalaliDateOfDay(daysPassedInJalaliCalender) { var yearOfDay = getYearJalaliCalender(daysPassedInJalaliCalender); var monthOfDay = getMonthJalaliCalender(daysPassedInJalaliCalender, yearOfDay); var dayOfMonth = getDayJalaliCalender(daysPassedInJalaliCalender, yearOfDay, monthOfDay); var date = { day: dayOfMonth, month: monthOfDay, year: yearOfDay }; return date; } function getDayJalaliCalender(daysPassedInJalaliCalender, yearOfDay, monthOfDay) { var leaps = howManyLeapsYearPassedInJalaliCalender(yearOfDay); daysPassedInJalaliCalender -= leaps + ((yearOfDay - 1) * 365); for (var i = 1; i < monthOfDay; i++) { if (i <= 6) { daysPassedInJalaliCalender -= 31; } else { daysPassedInJalaliCalender -= 30; } } return daysPassedInJalaliCalender; } function getMonthJalaliCalender(daysPassedInJalaliCalender, yearOfDay) { var leaps = howManyLeapsYearPassedInJalaliCalender(yearOfDay); daysPassedInJalaliCalender -= leaps + ((yearOfDay - 1) * 365); var jalaliMonths = getJalaliMonths(); for (var i = 0; i < jalaliMonths.length; i++) { if (daysPassedInJalaliCalender <= jalaliMonths[i].count) { return jalaliMonths[i].id; } daysPassedInJalaliCalender -= jalaliMonths[i].count; } return 12; } function getJalaliMonths() { return [ { id: 1, count: 31 }, { id: 2, count: 31 }, { id: 3, count: 31 }, { id: 4, count: 31 }, { id: 5, count: 31 }, { id: 6, count: 31 }, { id: 7, count: 30 }, { id: 8, count: 30 }, { id: 9, count: 30 }, { id: 10, count: 30 }, { id: 11, count: 30 }, { id: 12, count: 29 } ]; } function getYearJalaliCalender(daysPassedInJalaliCalender) { var years = Math.floor((daysPassedInJalaliCalender - 1) / 365); var leapsCount = 0; if (years > 22) { var year1 = years - 22 - 1; var year2 = years - 22; var siose = Math.floor(year1 / 33); var remainYear = (year2 - (siose * 33)); if (remainYear >= 28) { remainYear = 28; } var a = Math.floor(remainYear / 4); var sum = a + (siose * 8) + 6; var sal = Math.floor((daysPassedInJalaliCalender - sum) / 365); leapsCount = howManyLeapsYearPassedInJalaliCalender(sal); if (daysPassedInJalaliCalender - (sal * 365) - leapsCount - (isLeapYearInJalaliCalender(sal) ? 1 : 0) > 0) { sal++; return sal; } else if (daysPassedInJalaliCalender - (sal * 365) + leapsCount <= 0) { return sal; } return sal; } else { if (years < 1) { leapsCount = 0; } else if (years >= 1 && years <= 4) { leapsCount = 1; } else if (years >= 5 && years <= 8) { leapsCount = 2; } else if (years >= 9 && years <= 12) { leapsCount = 3; } else if (years >= 13 && years <= 16) { leapsCount = 4; } else if (years >= 17 && years < 22) { leapsCount = 5; } else { leapsCount = 6; } years = Math.floor((daysPassedInJalaliCalender - leapsCount - 1) / 365); return years + 1; } } function howManyLeapsYearPassedInJalaliCalender(year) { if (year < 23) { switch (year) { case 1: return 0; case 2: case 3: case 4: case 5: return 1; case 6: case 7: case 8: case 9: return 2; case 10: case 11: case 12: case 13: return 3; case 14: case 15: case 16: case 17: return 4; case 18: case 19: case 20: case 21: case 22: return 5; } } var yearAfterFirstEra = year - 22; var countSioSe = Math.floor((yearAfterFirstEra - 1) / 33); var remainOfNormalLeapsYear = yearAfterFirstEra - countSioSe * 33; if (remainOfNormalLeapsYear > 28) { remainOfNormalLeapsYear = 28; } var leapsCount = Math.floor(remainOfNormalLeapsYear / 4) + countSioSe * 8 + 6; if (isLeapYearInJalaliCalender(year) && (yearAfterFirstEra - countSioSe * 33) <= 28) { leapsCount--; } return leapsCount; } function getDaysPassedInGregorianCalender(date) { var gregorianMonths = getGregorianMonths(); var passedLeapYears = howManyGregorianLeapsYearPassed(date.year); var days = passedLeapYears; var isMiladiLeaps = isGregorianLeapYear(date.year); days += (date.year - 1) * 365; for (var i = 0; i < date.month - 1; i++) { if (isMiladiLeaps && i + 1 == 2) { gregorianMonths[i].count = 29; } days += gregorianMonths[i].count; } days += date.day; return days; } function getGregorianMonths() { return [ { id: 1, count: 31 }, { id: 2, count: 28 }, { id: 3, count: 31 }, { id: 4, count: 30 }, { id: 5, count: 31 }, { id: 6, count: 30 }, { id: 7, count: 31 }, { id: 8, count: 31 }, { id: 9, count: 30 }, { id: 10, count: 31 }, { id: 11, count: 30 }, { id: 12, count: 31 } ]; } function isGregorianLeapYear(year) { if (year % 4 != 0) { return false; } if (year % 100 != 0) { return true; } if (year % 400 != 0) { return false; } return true; } function howManyGregorianLeapsYearPassed(year) { var yearsPassed = year - 1; var countOfFourYears = Math.floor(yearsPassed / 4); var countOfHandredYears = Math.floor(yearsPassed / 100); var countOfFourHandredYears = Math.floor(yearsPassed / 400); return countOfFourYears - countOfHandredYears + countOfFourHandredYears; } function getGregorianYear(gregorianPassedDays) { var pureYear = Math.floor((gregorianPassedDays) / 365); var gregorianLeapsYear = howManyGregorianLeapsYearPassed(pureYear); var year = Math.floor((gregorianPassedDays - gregorianLeapsYear) / 365); var remainDay = gregorianPassedDays - year * 365 - gregorianLeapsYear; if (remainDay != 0) { year++; } else if (isGregorianLeapYear(year + 1)) { year += gregorianLeapsYear / 365; } return Math.floor(year); } function getGregorianMonth(daysPassed) { var year = getGregorianYear(daysPassed); var leaspYearCount = howManyGregorianLeapsYearPassed(year); daysPassed -= (year - 1) * 365 + leaspYearCount; var months = getGregorianMonths(); var month = 0; var isCurrentYearLeaps = isGregorianLeapYear(year); for (var i = 0; i < months.length; i++) { if (isCurrentYearLeaps && months[i].id == 2) { months[i].count = 29; } if (daysPassed < months[i].count) { if (daysPassed != 0 || month == 0) { month++; } return month; } daysPassed -= months[i].count; month = months[i].id; } return month; } function getGregorianDayOfMonthByPassedDay(daysPassed) { var year = getGregorianYear(daysPassed); var month = getGregorianMonth(daysPassed); return getGregorianDayOfMonth(year, month, daysPassed); } function getGregorianDayOfMonth(year, month, daysPassed) { var leaspYearCount = howManyGregorianLeapsYearPassed(year); var months = getGregorianMonths(); var sumOfMonths = 0; for (var i = 0; i < months.length; i++) { if (months[i].id < month) { sumOfMonths += months[i].count; } } if (isGregorianLeapYear(year) && month > 2) { sumOfMonths++; } return daysPassed - (year - 1) * 365 - leaspYearCount - sumOfMonths; } function getDaysPassedInJalaliCalander(date) { var days = date.day; days += passedDaysFromMonthsInJalaliCalander(date.month); days += passedDaysToYearsInJalaliCalander(date.year); return days; } function passedDaysFromMonthsInJalaliCalander(month) { var days = 0; var months = getJalaliMonths(); for (var i = 0; i < month - 1; i++) { days += months[i].count; } return days; } function passedDaysToYearsInJalaliCalander(years) { var days = howManyLeapsYearPassedInJalaliCalender(years); days += (years - 1) * 365; return days; } function getGregorianDate(date) { var daysPassed = getDaysPassedInJalaliCalander(date) + 226894; var day = getGregorianDayOfMonthByPassedDay(daysPassed); var month = getGregorianMonth(daysPassed); var year = getGregorianYear(daysPassed); if (day == 0) { day = 31; month = 12; year--; } return { day: day, month: month, year: year }; } var isLeapYearInJalaliCalender = function(years) { if (years == 1 || years == 5 || years == 9 || years == 13 || years == 17 || years == 22) { return true; } else if (years < 22) { return false; } var year = years - 22; var siosesal = Math.floor(year / 33); return ((year - (siosesal * 33)) % 4 == 0) && (year - (siosesal * 33)) / 4 != 8; } var getPersianDate = function(year, month, day) { year = (year<=99)?(2000+year):year; var date = { year: year, month: month, day: day }; date = getJalaliDate(date); return date; } var getGregorianDates = function(year, mont, day) { year = (year<=99)?(1300+year):year; var date= getGregorianDate( { day: day, month: mont, year: year }); return date; } return { toJalali: getPersianDate, toGregorian: getGregorianDates, isLeapJalali: isLeapYearInJalaliCalender } } var ADMdtpFactory = function(ADMdtpConvertor) { this.dateFormat = function(date, time, format, notView) { if (!date.year) return ''; var year = date.year; var halfYear = notView ? date.year : date.year%100; var month = date.month.lZero(); var day = date.day.lZero(); var hour = time.hour.lZero(); var minute = time.minute.lZero(); var replaceMap = [ {key: 'YYYY', value: year}, {key: 'YY', value: halfYear}, {key: 'MM', value: month}, {key: 'DD', value: day}, {key: 'hh', value: hour}, {key: 'mm', value: minute} ] for(var i=0,j=replaceMap.length;i<j;i++) { format = format.replace(replaceMap[i].key, replaceMap[i].value); } return format; }; this.parseString = function(str, format) { var _keys = [], _date = {}; var formats = ['YY/MM/DD', 'YY/MM/DD hh:mm', 'YY-MM-DD', 'YY-MM-DD hh:mm', 'MM/DD/YY', 'MM-DD-YY', 'MM/DD/YY hh:mm', 'MM-DD-YY hh:mm']; formats.unshift(format); for(var i=0,j=formats.length;i<j;i++) { var _isValid = new RegExp('^' + formats[i].replace(/[a-z]+/gi, function(key) { var _mustReplace = false; if (key.indexOf('YY') != -1) _keys.push('year'), _mustReplace=true; else if (key.indexOf('MM') != -1) _keys.push('month'), _mustReplace=true; else if (key.indexOf('DD') != -1) _keys.push('day'), _mustReplace=true; else if (key.indexOf('hh') != -1) _keys.push('hour'), _mustReplace=true; else if (key.indexOf('mm') != -1) _keys.push('minute'), _mustReplace=true; if (_mustReplace) return '[0-9]+'; else return key; }).replace(/[(]/g, '[(]').replace(/[)]/g, '[)]') + '$').test(str); if (!_isValid) continue; _keys.reverse(); str.replace(/[0-9]+/g, function(value) { _date[_keys.pop()] = Number(value); return value; }); _date.hour = _date.hour || 0; _date.minute = _date.minute || 0; return _date; } return false; }; this.toRegularFormat = function(date, type, format) { if (!date) return false; if (typeof date == "string") date = this.parseString(date, format); else if (typeof date == "number") date = this.convertFromUnix(date, type); if (!date) return false; if (date.year<=99) date.year = ((type == 'jalali') ? 1300+date.year : 2000+date.year); return [date.year, date.month.lZero(), date.day.lZero(), date.hour.lZero(), date.minute.lZero()].dtp_toDate(); }; this.isDateEqual = function(date1, date2) { var diff = new Date(date1) - new Date(date2); return diff==0; }; this.isDateBigger = function(date1, date2) { var diff = new Date(date1) - new Date(date2); return diff>=0; }; this.isMonthBigger = function(date1, date2) { var diff = new Date(date1.year, date1.month) - new Date(date2.year, date2.month); return diff>=0; }; this.joinTime = function(date, time) { return new Date(new Date(new Date(date).setHours(time.hour)).setMinutes(time.minute)); }; this.removeTime = function(date) { return [date.getFullYear(), date.getMonth()+1, date.getDate()].dtp_toDate('date'); } this.validateJalaliDateSeparate = function(date, time) { if (date.length!=3 || time.length!=2) return false; if (time[0]>23 || time[0]<0 || time[1]>59 || time[1]<0 || date[0]<0 || date[1]<1 || date[1]>12) return false; if (date[1]>0 && date[1]<7) { if (date[2]<1 || date[2]>31) return false; } else if (date[1]>6 && date[1]<12) { if (date[2]<1 || date[2]>30) return false; } else if (date[1] == 12) { var isLeap = ADMdtpConvertor.isLeapJalali(date[0]); if ((isLeap && (date[2]<1 || date[2]>30)) || (!isLeap && (date[2]<1 || date[2]>29))) return false; } return true; } this.validateJalaliDate = function(input, format) { var _dateTime; if (typeof input == "number") { var _gDate = new Date(input); if (/invalid/i.test(_gDate)) return false; var _pDate = this.convertToJalali(_gDate); _dateTime = angular.merge(_pDate, {hour: _gDate.getHours(), minute: _gDate.getMinutes()}); } else if (typeof input == "string") _dateTime = this.parseString(input, format); else if (input instanceof Object) _dateTime = input; if (!_dateTime) return false; var _date = [_dateTime.year, _dateTime.month, _dateTime.day]; var _time = [_dateTime.hour, _dateTime.minute]; if (this.validateJalaliDateSeparate(_date, _time)) { var _gDateC = ADMdtpConvertor.toGregorian(_date[0],_date[1],_date[2]); var _gDate = [_gDateC.year, _gDateC.month, _gDateC.day, _time[0], _time[1]].dtp_toDate('date'); return { year: _date[0], month: _date[1], day: _date[2], hour: _time[0], minute: _time[1], unix: _gDate.getTime(), gDate: _gDate } } return false; }; this.convertToUnix = function(value, type, format) { if (!value) return null; if (typeof value == "number") return value; if (typeof value == "string") { value = this.parseString(value, format); } else if (value instanceof Date) value = {year: value.getFullYear(), month: value.getMonth()+1, day: value.getDate(), hour: value.getHours(), minute: value.getMinutes()}; else return null; if (value.year<=99) value.year = ((type == 'jalali') ? 1300+value.year : 2000+value.year); if (type == 'jalali') { var _dateTime = this.validateJalaliDate(value, format); return _dateTime.unix || null; } else if (type == 'gregorian') { var _dateTime = new Date(this.toRegularFormat(value, type)); return (/invalid/i.test(_dateTime))?null:_dateTime.getTime(); } return null; }; this.convertFromUnix = function(unix, type) { var _gDate = new Date(unix); if (type == 'jalali') return this.convertToJalali(_gDate); else if (type == 'gregorian') return { year: _gDate.getFullYear(), month: _gDate.getMonth()+1, day: _gDate.getDate(), unix: unix }; }; this.convertToJalali = function(date) { if (date instanceof Date) { var _date = { year: date.getFullYear(), month: date.getMonth()+1, day: date.getDate(), unix: date.getTime() } date = _date; } if (date instanceof Object) { return angular.merge(ADMdtpConvertor.toJalali(date.year, date.month, date.day), {unix: date.unix}); } }; this.parseDisablePattern = function(options) { var arr = options.disabled, smart = options.smartDisabling, calType = options.calType, format = options.format; var _inWeek = Array.apply(null, Array(7)).map(Number.prototype.valueOf,0); var _inMonth = Array.apply(null, Array(31)).map(Number.prototype.valueOf,0); var _static = {}; if (arr instanceof Array) { for (var i=0,j=arr.length; i<j; i++) { if (typeof arr[i] == "number") { var _gDate = new Date(arr[i]); if (!/invalid/i.test(_gDate)) _static[this.removeTime(_gDate).getTime()] = true; } else if (typeof arr[i] == "string") { arr[i] = arr[i].toLowerCase(); if (arr[i].indexOf('d') == -1 && arr[i].indexOf('i') == -1) { var _unix = this.convertToUnix(arr[i], calType, format); if (_unix) _static[_unix] = true; } else { var _inMonthValid = new RegExp("^[!]?(([0-9]?[0-9])?[d]([+][0-9][0-9]?)?)([&]([0-9]?[0-9])?[d]([+][0-9][0-9]?)?)*?$").test(arr[i]); var _inWeekhValid = new RegExp("^[!]?([i]([+][0-9][0-9]?)?)([&][i]([+][0-9][0-9]?)?)*?$").test(arr[i]); if (_inMonthValid || _inWeekhValid) { var _not = arr[i][0]=='!'; arr[i] = _not?arr[i].split('!')[1]:arr[i]; var _patt = arr[i].split('&'); if (_inMonthValid) { var _tmpObj = {}; _patt.forEach(function(item) { var _params = item.split(/d[+]?/).map(function(str) {return Number(str);}); _params[0] = _params[0]?_params[0]:1; _params[1]%=31; for (var k=0; k<31; k++) { if (_params[0]!=1 && k%_params[0] == _params[1] || _params[0]==1 && k==_params[1]) _tmpObj[k] = 1; } }); for (var k=0; k<31; k++) { if (_not) { if (!_tmpObj[k]) _inMonth[k] = 1; } else { if (_tmpObj[k]) _inMonth[k] = 1; } } } else if (_inWeekhValid) { var _tmpObj = {}; _patt.forEach(function(item) { var _params = item.split(/i[+]?/).map(function(str) {return Number(str);}); _params[1]%=7; _tmpObj[_params[1]] = 1; }); for (var k=0; k<7; k++) { if (_not) { if (!_tmpObj[k]) _inWeek[k] = 1; } else { if (_tmpObj[k]) _inWeek[k] = 1; } } } } else { console.warn(arr[i] + " is not valid!"); } } } } } return {smart: smart, calType: calType, static: _static, inWeek: _inWeek, inMonth: _inMonth}; } this.isDayDisable = function(calType, disabled, day) { if (disabled.static[day.unix]) return true; var _gap = 0; if (disabled.smart) { if (disabled.calType=='gregorian' && calType=='jalali') _gap = +1; else if (disabled.calType=='jalali' && calType=='gregorian') _gap = -1; } else { if (disabled.calType=='gregorian' && calType=='jalali') _gap = -1; else if (disabled.calType=='jalali' && calType=='gregorian') _gap = +1; } var _dayName = (day.dayName + 7 + _gap)%7; if (disabled.inMonth[day.day-1]) return true; return !!+disabled.inWeek[_dayName]; } return { dateFormat: this.dateFormat, parseString: this.parseString, toRegularFormat: this.toRegularFormat, isDateEqual: this.isDateEqual, isDateBigger: this.isDateBigger, isMonthBigger: this.isMonthBigger, joinTime: this.joinTime, removeTime: this.removeTime, validateJalaliDateSeparate: this.validateJalaliDateSeparate, validateJalaliDate: this.validateJalaliDate, convertToUnix: this.convertToUnix, convertFromUnix: this.convertFromUnix, convertToJalali: this.convertToJalali, parseDisablePattern: this.parseDisablePattern, isDayDisable: this.isDayDisable, counter: 0 } } var ADMdtpCalendarDirective = function(ADMdtp, ADMdtpConvertor, ADMdtpFactory, constants, $timeout) { return { restrict: 'E', replace: true, //require: '^^admDtp', link: function(scope, element, attrs) { var admDtp = scope.api; var _standValue; if (!scope.dtpValue.unix) _standValue = new Date(); else _standValue = new Date(scope.dtpValue.fullDate); if (scope.calType == 'jalali') _standValue = ADMdtpFactory.convertToJalali(_standValue); admDtp.fillDays(_standValue, !scope.option.transition); scope.previousMonth = function(flag) { if (scope.calType == 'jalali' && !flag) { scope.nextMonth(true); return; } if (scope.current.month == 1) scope.current.month = 12, scope.current.year--; else scope.current.month-- admDtp.reload(); } scope.nextMonth = function(flag) { if (scope.calType == 'jalali' && !flag) { scope.previousMonth(true); return; } if (scope.current.month == 12) scope.current.month = 1, scope.current.year++; else scope.current.month++ admDtp.reload(); } scope.previousYear = function(flag) { if (scope.calType == 'jalali' && !flag) { scope.nextYear(true); return; } var _firstYear = scope.generatedYears.shift(); scope.generatedYears = []; for (var i=1;i<17;i++) { scope.generatedYears.push(_firstYear - 17 + i); } } scope.nextYear = function(flag) { if (scope.calType == 'jalali' && !flag) { scope.previousYear(true); return; } var _lastYear = scope.generatedYears.pop(); scope.generatedYears = []; for (var i=1;i<17;i++) { scope.generatedYears.push(_lastYear + i); } } scope.selectMonthInit = function() { scope.yearSelectStat = false; scope.monthPickerStat = true; } scope.selectYearInit = function() { scope.yearSelectStat = true; scope.generatedYears = []; for (var i=0;i<16;i++) { scope.generatedYears.push(scope.current.year + i - 7); } } scope.selectMonth = function(monthIdx) { if (monthIdx+1 != scope.current.month) { scope.current.month = monthIdx+1; admDtp.reload(); } scope.monthPickerStat = false; } scope.selectYear = function(yearName) { if (yearName != scope.current.year) { scope.current.year = yearName; admDtp.reload(); } scope.monthPickerStat = false; //scope.yearSelectStat = false; } scope.selectThisDay = function(day) { if (day.valid == 0) return; scope.dtpValue.selected = false; admDtp.updateMasterValue(day, 'day'); if (scope.option.autoClose) { $timeout(function() { scope.closeCalendar(); },100); return; } if (day.disable) { $timeout(function() { if (ADMdtpFactory.isMonthBigger(day, scope.current)) scope.nextMonth(true); else scope.previousMonth(true); }, 0); } else day.selected = true; } scope.today = function() { var _standValue = new Date(); if (scope.calType == 'jalali') _standValue = ADMdtpFactory.convertToJalali(_standValue); admDtp.fillDays(_standValue, !scope.option.transition); } scope.changeTimeValue = function(variable, value) { value *= (variable=='minute' ? scope.option.minuteStep : 1); var _num = (Number(scope.time[variable]) + value + ((variable=='hour')?24:60)) % ((variable=='hour')?24:60); var _timeCopy = angular.copy(scope.time); _timeCopy[variable] = _num.lZero(); if (scope.dtpValue.unix) { if (scope.minDate || scope.maxDate) { var _dateTime = ADMdtpFactory.joinTime(scope.dtpValue.unix, _timeCopy); if ((scope.minDate && !ADMdtpFactory.isDateBigger(_dateTime,scope.minDate)) || (scope.maxDate && !ADMdtpFactory.isDateBigger(scope.maxDate,_dateTime))) return; } } scope.time[variable] = _num.lZero(); if (scope.dtpValue.unix) admDtp.updateMasterValue(false, 'time'); admDtp.reload(); } scope.modelChanged = function(input) { var _value = (angular.isDefined(input) ? input : scope.dtpValue.formated); if (!_value) { if (scope.dtpValue.unix) scope.destroy(); return; } var _inputUnix = ADMdtpFactory.convertToUnix(_value, scope.calType, scope.option.format); if (!_inputUnix || scope.option.freezeInput || scope.disable || ((scope.minDate && !ADMdtpFactory.isDateBigger(_inputUnix,scope.minDate)) || (scope.maxDate && !ADMdtpFactory.isDateBigger(scope.maxDate,_inputUnix)))) { admDtp.updateMasterValue(false); return; } if (_inputUnix == scope.fullData.unix) return; scope.parseInputValue(_value, false, true); var _gDate = new Date(_inputUnix); if (scope.calType == 'jalali') _gDate = ADMdtpFactory.convertToJalali(_gDate); admDtp.fillDays(_gDate, true); } admDtp.modelChanged = scope.modelChanged; scope.calTypeChanged = function(calType) { scope.calType = (calType ? calType : ((scope.calType=='gregorian')?'jalali':'gregorian')); scope.monthNames = scope.option[scope.calType + 'Dic'].monthsNames; scope.daysNames = scope.option[scope.calType + 'Dic'].daysNames; var _cur = angular.copy(scope.current); var _mainDate; if (scope.calType == 'jalali') { _mainDate = ADMdtpConvertor.toJalali(_cur.year, _cur.month, 15); } else { _mainDate = ADMdtpConvertor.toGregorian(_cur.year, _cur.month, 15); _mainDate = [_mainDate.year, _mainDate.month, _mainDate.day].dtp_toDate('date'); } if (scope.dtpValue.unix) { admDtp.updateMasterValue(ADMdtpFactory.convertFromUnix(scope.dtpValue.unix, scope.calType)); } admDtp.fillDays(_mainDate, true); } }, //templateUrl: 'js/ADM-dateTimePicker/ADM-dateTimePicker_calendar.html' template: '<div class="ADMdtp-box ADMdtp-calendar-container" ng-class="{rtl: (calType==\'jalali\'), square: monthPickerStat||timePickerStat}"> <div class="dtpNewBox" ng-class="{active: monthPickerStat}"> <i class="calendarIcon" ng-class="{show: monthPickerStat}" ng-click="monthPickerStat = false"> <svg class="dtp-i" viewBox="0 0 24 24"> <use xlink:href="#dtp-i-calendar" /> </svg> </i> <div class="content"> <div class="ADMdtpMonths" ng-class="{onYear: yearSelectStat, rtl: (calType==\'jalali\')}"> <div class="ADMdtpYears"> <svg class="dtp-i dtp-i-180 dtp-trs-3 arrow left" viewBox="0 0 24 24" ng-if="yearSelectStat" ng-click="previousYear()"> <use xlink:href="#dtp-i-right" /> </svg> <p class="dtp-trs-3" ng-click="selectYearInit()">{{current.year | digitType:calType}}</p> <svg class="dtp-i dtp-trs-3 arrow right" viewBox="0 0 24 24" ng-if="yearSelectStat" ng-click="nextYear()"> <use xlink:href="#dtp-i-right" /> </svg> </div> <span ng-repeat="yearName in generatedYears" ng-if="yearSelectStat"><span class="dtp-trs-5" ng-class="{selected: yearName==current.year}" ng-click="selectYear(yearName)">{{yearName | digitType:calType}}</span></span> <span ng-repeat="monthName in monthNames" ng-if="!yearSelectStat"><span class="dtp-trs-5" ng-class="{selected: monthName==current.monthDscr}" ng-click="selectMonth($index)">{{monthName}}</span></span> </div> </div> </div> <div class="dtpNewBox" ng-class="{active: timePickerStat}"> <i class="calendarIcon" ng-class="{show: timePickerStat}" ng-click="timePickerStat = false"> <svg class="dtp-i" viewBox="0 0 24 24"> <use xlink:href="#dtp-i-calendar" /> </svg> </i> <div class="content"> <div class="ADMdtpTime"> <span class="dtpIcon null up" ng-click="changeTimeValue(\'hour\', 1)"><svg class="dtp-i dtp-trs-5 dtp-i-270" viewBox="0 0 24 24"><use xlink:href="#dtp-i-right" /></svg></span><!-- --><span></span><!-- --><span class="dtpIcon null up" ng-click="changeTimeValue(\'minute\', 1)"><svg class="dtp-i dtp-trs-5 dtp-i-270" viewBox="0 0 24 24"><use xlink:href="#dtp-i-right" /></svg></span><!-- --><span>{{time.hour}}</span><!-- --><span class="period">:</span><!-- --><span>{{time.minute}}</span><!-- --><span class="dtpIcon null down" ng-click="changeTimeValue(\'hour\', -1)"><svg class="dtp-i dtp-trs-5 dtp-i-90" viewBox="0 0 24 24"><use xlink:href="#dtp-i-right" /></svg></span><!-- --><span></span><!-- --><span class="dtpIcon null down" ng-click="changeTimeValue(\'minute\', -1)"><svg class="dtp-i dtp-trs-5 dtp-i-90" viewBox="0 0 24 24"><use xlink:href="#dtp-i-right" /></svg></span> </div> </div> </div> <header> <svg class="dtp-i dtp-i-180 dtp-trs-3 arrow left" viewBox="0 0 24 24" ng-click="previousMonth()"> <use xlink:href="#dtp-i-right" /> </svg> <span class="yearMonth" ng-click="selectMonthInit()">{{current.monthDscr}} {{current.year | digitType:calType}}</span> <svg class="dtp-i dtp-trs-3 arrow right" viewBox="0 0 24 24" ng-click="nextMonth()"> <use xlink:href="#dtp-i-right" /> </svg> </header> <div class="daysNames"> <span ng-repeat="dayName in daysNames">{{dayName}}</span> </div> <hr> <div class="ADMdtpDays" ng-class="{loading:loadingDays}"> <span ng-repeat="day in current.days" ng-click="selectThisDay(day)"><span ng-class="[{disable: day.disable||!day.valid, today: day.today, selected: day.selected, valid:(day.valid==2)}, (day.isMin)?((calType==\'jalali\')?\'max\':\'min\'):\'\', (day.isMax)?((calType==\'jalali\')?\'min\':\'max\'):\'\']">{{day.day | digitType:calType}}</span></span> </div> <hr> <footer> <div class="calTypeContainer dtp-trs-3" ng-class="$parent.calType" ng-click="calTypeChanged()" ng-if="option.multiple"> <p class="gregorian">{{option.gregorianDic.title}}</p> <p class="jalali">{{option.jalaliDic.title}}</p> </div> <button type="button" class="today dtp-trs-3" ng-click="today()">{{option[calType + "Dic"].todayBtn}}</button> <svg class="dtp-i dtp-trs-5 timeSelectIcon" viewBox="0 0 24 24" ng-show="option.dtpType != \'date\'" ng-click="timePickerStat = !timePickerStat"> <use xlink:href="#dtp-i-clock" /> </svg> </footer> </div>' } } var ADMdtpDirective = function(ADMdtp, ADMdtpConvertor, ADMdtpFactory, constants, $compile, $timeout) { return { restrict: 'E', replace: true, transclude: true, require: ['ngModel', 'admDtp'], scope: { options: '=?', fullData: '=?', name: '=?', ngRequired: '=?', onChange: '&?', onDatechange: '&?', onTimechange: '&?', onOpen: '&?', onClose: '&?', }, link: function(scope, element, attrs, ctrls) { var ngModel = ctrls[0], admDtp = ctrls[1]; scope.api = admDtp; scope.dtpId = 'adm-' + (++ADMdtpFactory.counter); if (!element.find('ng-transclude').children().length) { scope.defaultTemplate = true; element.find('ng-transclude').remove(); } var _options = scope.options; if (!(_options instanceof Object)) _options = {}; scope.option = angular.merge(angular.copy(ADMdtp.getOptions()), _options); scope.option.minuteStep = Math.max(Math.min(scope.option.minuteStep, 60), 1); var dayNames = angular.copy(scope.option.gregorianDic.daysNames); scope.option.gregorianDic.daysNamesUntouched = dayNames; scope.option.gregorianDic.daysNames = dayNames.slice(scope.option.gregorianStartDay,7).concat(dayNames.slice(0,scope.option.gregorianStartDay)); scope.disableDays = ADMdtpFactory.parseDisablePattern(scope.option); scope.calType = scope.option.calType; scope.monthNames = scope.option[scope.calType + 'Dic'].monthsNames; scope.daysNames = scope.option[scope.calType + 'Dic'].daysNames; scope.timeoutValue = [0,0]; scope.dtpValue = {}; scope.minDate = scope.mindate?new Date(scope.mindate):null; scope.maxDate = scope.maxdate?new Date(scope.maxdate):null; scope.current = { year: '', month: '', monthDscr: '', days: [] }; scope.updateMasterValue = function(newDate, releaseTheBeast) { if (!newDate) newDate = (scope.dtpValue.unix ? scope.dtpValue : {}); scope.$applyAsync(function() { scope.dtpValue = newDate; var minute = Number(scope.time.minute); minute -= minute % scope.option.minuteStep; scope.time.minute = minute.lZero(); scope.dtpValue.formated = ADMdtpFactory.dateFormat(newDate, scope.time, scope.option.format); scope.dtpValue.fullDate = ADMdtpFactory.joinTime(newDate.unix, scope.time); scope.fullData = { formated: scope.dtpValue.formated, lDate: scope.dtpValue.fullDate.dtp_shortDate(), gDate: scope.dtpValue.fullDate, unix: scope.dtpValue.fullDate.getTime(), year: newDate.year, month: newDate.month, day: newDate.day, hour: Number(scope.time.hour), minute: Number(scope.time.minute), minDate: scope.minDate, maxDate: scope.maxDate, calType: scope.calType, format: scope.option.format } ngModel.$setViewValue( scope.dtpValue.formated ); ngModel.$render();