From 964930c39f8038fd47293ab1b7f7c272a7b8d9f6 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Sat, 17 Mar 2018 20:58:02 +0300 Subject: [PATCH] Rewrite to es6 class --- .babelrc | 4 + calendar-material.css | 2 +- calendar.js | 607 +++++++++++++++++++++++------------------- calendar.min.js | 2 +- calendar.util.js | 47 ---- package.json | 21 ++ test.htm | 3 +- 7 files changed, 367 insertions(+), 319 deletions(-) create mode 100644 .babelrc delete mode 100644 calendar.util.js create mode 100644 package.json diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..93c2249 --- /dev/null +++ b/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": [ [ "env", { modules: "umd" } ], "stage-1", "react" ], + "retainLines": true +} diff --git a/calendar-material.css b/calendar-material.css index 2b8c64d..9e1fd66 100644 --- a/calendar-material.css +++ b/calendar-material.css @@ -4,7 +4,7 @@ width: 301px; background: #fff; position: absolute; - z-index: 100; + z-index: 10000; padding: 0; font-family: Roboto, sans-serif; box-shadow: 0 19px 60px rgba(0, 0, 0, .3), 0 15px 20px rgba(0, 0, 0, .22) diff --git a/calendar.js b/calendar.js index 5cd687d..4bd618f 100644 --- a/calendar.js +++ b/calendar.js @@ -4,7 +4,7 @@ * * Original: http://www.openjs.com/scripts/ui/calendar/ * Modified: http://yourcmc.ru/git/vitalif-js/calendar - * Version: 2018-03-14 + * Version: 2018-03-17 * License: MIT-like, http://www.openjs.com/license.php * * Example: @@ -13,294 +13,365 @@ * Calendar.set("date"); * */ -function Calendar() +export class Calendar { -} - -// Configuration -Calendar.defaultOptions = { - month_names: ["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"], - close_label: 'Закрыть', - weekdays: ["Пн","Вт","Ср","Чт","Пт","Сб","Вс"], - sunday: 6, - selectboxes: false, // true: use selectboxes for year and month, false: show months and years in table - years: {min: -70, max: 10}, // range of displayed years if selectboxes==true - format: 'd.m.Y', // either d.m.Y or Y-m-d, other formats are not supported - month_days: [31,28,31,30,31,30,31,31,30,31,30,31], - // Today's date - today: new Date(), -}; - -// State variables -Calendar.instance = null; -Calendar.box = null; -Calendar.addedListener = false; - -Calendar.prototype.setHTML = function(html) -{ - html += ""+this.close_label+""; - Calendar.box.innerHTML = html; -}; - -/// Called when the user clicks on a date in the calendar. -Calendar.prototype.selectDate = function(year, month, day) -{ - var i = this.input; - var t = i.value.split(/\s+/, 2)[1]||''; - if (t) - t = ' '+t; - i.value = (this.format == 'Y-m-d' ? year + '-' + month + '-' + day : day + '.' + month + '.' + year) + t; - Calendar.hideCalendar(); -}; - -Calendar.prototype.showMonths = function(year, month) -{ - var cur_y = this.today.getFullYear(); - var cur_m = this.today.getMonth(); - var sel_m = this.selected.getFullYear() == year ? this.selected.getMonth() : -1; - var html = ''; - html += ""; - html += ""; - html += ""; - for (var i in this.month_names) { - if (i && !(i % 3)) - html += ""; - var class_name = (year < cur_y || year == cur_y && i < cur_m ? 'past' : - (year > cur_y || year == cur_y && i > cur_m ? 'future' : 'today')) - + (i == sel_m ? ' selected' : ''); - html += ""; - } - html += ""; - html += "
"; - html += " "+year+""; - html += "
"+this.month_names[i]+"
"; - this.setHTML(html); -}; - -Calendar.prototype.showYears = function(year) -{ - var beg = year & ~15; - var cur_y = this.today.getFullYear(); - var sel_y = this.selected.getFullYear(); - var html = ''; - html += ""; - html += ""; - html += ""; - for (var i = 0; i < 16; i++) { - if (i && !(i % 4)) - html += ""; - var class_name = (beg+i < cur_y ? 'past' : (beg+i > cur_y ? 'future' : 'today')) - + (beg+i == sel_y ? ' selected' : ''); - html += ""; - } - html += ""; - html += "
"; - html += " "; - html += " "+beg+" - "+(beg+15)+""; - html += " "; - html += "
"+(beg+i)+"
"; - this.setHTML(html); -}; - -/// Creates a calendar with the date given in the argument as the selected date. -Calendar.prototype.makeCalendar = function(year, month) -{ - // Display the table - var next_month = month+1; - var next_month_year = year; - if (next_month >= 12) { - next_month = 0; - next_month_year++; + // Configuration + static defaultOptions = { + month_names: ["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"], + close_label: 'Закрыть', + weekdays: ["Пн","Вт","Ср","Чт","Пт","Сб","Вс"], + sunday: 6, + selectboxes: false, // true: use selectboxes for year and month, false: show months and years in table + years: {min: -70, max: 10}, // range of displayed years if selectboxes==true + format: 'd.m.Y', // either d.m.Y or Y-m-d, other formats are not supported + month_days: [31,28,31,30,31,30,31,31,30,31,30,31], + // Today's date + today: new Date(), + callback: null, + start: 'days', } - var previous_month = month-1; - var previous_month_year = year; - if (previous_month < 0) { - previous_month = 11; - previous_month_year--; + // State variables + static instance = null; + static box = null; + static addedListener = false; + + setHTML(html) + { + html += ""+this.close_label+""; + Calendar.box.innerHTML = html; } - var current_year = this.today.getFullYear(); + isVisible() + { + return Calendar.instance == this && Calendar.box.style.display == 'block'; + } - var html = ''; - html += ""; - html += ""; - html += ""; - for (var weekday = 0; weekday < 7; weekday++) - html += ""; - html += ""; - - // Get the first day of this month - var first_day = new Date(year,month,1); - var start_day = (first_day.getDay()+this.sunday)%7; - - var d = 1; - var flag = 0; - - // Leap year support - if (!(year % 4) && ((year % 100) || !(year % 400))) - this.month_days[1] = 29; - else - this.month_days[1] = 28; - - var days_in_this_month = this.month_days[month]; - - // Create the calendar - var yea = this.today.getFullYear(); - var all_diff = (year - yea) || (month - this.today.getMonth()); - var sel_day = year == this.selected.getFullYear() && month == this.selected.getMonth() ? this.selected.getDate() : -1; - for (var i = 0; i <= 5; i++) { - if (w >= days_in_this_month) - break; - html += ""; - for (var j = 0; j < 7; j++) { - if (d > days_in_this_month) - flag = 0; // If the days has overshooted the number of days in this month, stop writing - else if (j >= start_day && !flag) - flag = 1; // If the first day of this month has come, start the date writing - - if (flag) { - var w = d, mon = month+1; - if (w < 10) - w = "0" + w; - if (mon < 10) - mon = "0" + mon; - - // Is it today? - var class_name = ''; - - var diff = all_diff || (d - this.today.getDate()); - if (diff < 0) - class_name = ' past'; - else if (!diff) - class_name = ' today'; - else - class_name = ' future'; - - if (d == sel_day) - class_name += ' selected'; - - class_name += " " + this.weekdays[j].toLowerCase(); - - html += ""; - d++; + else + { + t = (this.format == 'Y-m-d' ? year + '-' + month + '-' + day : day + '.' + month + '.' + year) + t; + i.value = t; + if ("Event" in window) + { + var evt = document.createEvent('Event'); + evt.initEvent('change', true, true); + i.dispatchEvent(evt); } else - html += ""; + i.fireEvent("onchange"); + } + Calendar.instance.hideCalendar(); + } + + showMonths(year) + { + var cur_y = this.today.getFullYear(); + var cur_m = this.today.getMonth(); + var sel_m = this.selected.getFullYear() == year ? this.selected.getMonth() : -1; + var html = ''; + html += "
"; - if (!this.selectboxes) { - html += " "+this.month_names[month]+""; - html += " "+year+""; - } else { - html += " "; - html += ""; - } - html += "
"+this.weekdays[weekday]+"
"+d+" 
"; + html += ""; + html += ""; + for (var i in this.month_names) { + if (i && !(i % 3)) + html += ""; + var class_name = (year < cur_y || year == cur_y && i < cur_m ? 'past' : + (year > cur_y || year == cur_y && i > cur_m ? 'future' : 'today')) + + (i == sel_m ? ' selected' : ''); + html += ""; } html += ""; + html += "
"; + html += " "+year+""; + html += "
"+this.month_names[i]+"
"; + this.setHTML(html); } - html += ""; - this.setHTML(html); -}; -/// Display the calendar - if a date exists in the input box, that will be selected in the calendar. -Calendar.prototype.showCalendar = function() -{ - Calendar.instance = this; - var input = this.input; + showYears(year) + { + var beg = year & ~15; + var cur_y = this.today.getFullYear(); + var sel_y = this.selected.getFullYear(); + var html = ''; + html += ""; + html += ""; + html += ""; + for (var i = 0; i < 16; i++) { + if (i && !(i % 4)) + html += ""; + var class_name = (beg+i < cur_y ? 'past' : (beg+i > cur_y ? 'future' : 'today')) + + (beg+i == sel_y ? ' selected' : ''); + html += ""; + } + html += ""; + html += "
"; + html += " "; + html += " "+beg+" - "+(beg+15)+""; + html += " "; + html += "
"+(beg+i)+"
"; + this.setHTML(html); + } - //Position the div in the correct location... - var div = Calendar.box; - var xy = getOffset(input); - var width = input.clientWidth||input.offsetWidth; - var height = input.clientHeight||input.offsetHeight; - div.style.left = (xy.left-1)+"px"; - div.style.top = (xy.top+height-1)+"px"; + /// Creates a calendar with the date given in the argument as the selected date. + makeCalendar(year, month) + { + // Display the table + var next_month = month+1; + var next_month_year = year; + if (next_month >= 12) { + next_month = 0; + next_month_year++; + } - // Show the calendar with the date in the input as the selected date - this.selected = new Date(); - var date_in_input = input.value.replace(/\s+.*$/, ''); //Remove time - if (date_in_input) { - // date format is HARDCODE - var selected_date = false; - var date_parts = date_in_input.split("-"); - if (date_parts.length == 3) { - // Y-m-d - date_parts[1]--; //Month starts with 0 - selected_date = new Date(date_parts[0], date_parts[1], date_parts[2]); - } else if (date_parts.length == 1) { - date_parts = date_in_input.split('.'); + var previous_month = month-1; + var previous_month_year = year; + if (previous_month < 0) { + previous_month = 11; + previous_month_year--; + } + + var current_year = this.today.getFullYear(); + + var html = ''; + html += ""; + html += ""; + html += ""; + for (var weekday = 0; weekday < 7; weekday++) + html += ""; + html += ""; + + // Get the first day of this month + var first_day = new Date(year,month,1); + var start_day = (first_day.getDay()+this.sunday)%7; + + var d = 1; + var flag = 0; + + // Leap year support + if (!(year % 4) && ((year % 100) || !(year % 400))) + this.month_days[1] = 29; + else + this.month_days[1] = 28; + + var days_in_this_month = this.month_days[month]; + + // Create the calendar + var yea = this.today.getFullYear(); + var all_diff = (year - yea) || (month - this.today.getMonth()); + var sel_day = year == this.selected.getFullYear() && month == this.selected.getMonth() ? this.selected.getDate() : -1; + for (var i = 0; i <= 5; i++) { + if (w >= days_in_this_month) + break; + html += ""; + for (var j = 0; j < 7; j++) { + if (d > days_in_this_month) + flag = 0; // If the days has overshooted the number of days in this month, stop writing + else if (j >= start_day && !flag) + flag = 1; // If the first day of this month has come, start the date writing + + if (flag) { + var w = d, mon = month+1; + if (w < 10) + w = "0" + w; + if (mon < 10) + mon = "0" + mon; + + // Is it today? + var class_name = ''; + + var diff = all_diff || (d - this.today.getDate()); + if (diff < 0) + class_name = ' past'; + else if (!diff) + class_name = ' today'; + else + class_name = ' future'; + + if (d == sel_day) + class_name += ' selected'; + + class_name += " " + this.weekdays[j].toLowerCase(); + + html += ""; + d++; + } + else + html += ""; + } + html += ""; + } + html += "
"; + if (!this.selectboxes) { + html += " "+this.month_names[month]+""; + html += " "+year+""; + } else { + html += " "; + html += ""; + } + html += "
"+this.weekdays[weekday]+"
"+d+" 
"; + this.setHTML(html); + } + + /// Display the calendar - if a date exists in the input box, that will be selected in the calendar. + showCalendar() + { + Calendar.instance = this; + var input = this.input; + + // Show the calendar with the date in the input as the selected date + this.selected = new Date(); + var date_in_input = input.value.replace(/\s+.*$/, ''); //Remove time + if (date_in_input) { + // date format is HARDCODE + var selected_date = false; + var date_parts = date_in_input.split("-"); if (date_parts.length == 3) { - // d.m.Y + // Y-m-d date_parts[1]--; //Month starts with 0 - selected_date = new Date(date_parts[2], date_parts[1], date_parts[0]); + selected_date = new Date(date_parts[0], date_parts[1], date_parts[2]); + } else if (date_parts.length == 1) { + date_parts = date_in_input.split('.'); + if (date_parts.length == 3) { + // d.m.Y + date_parts[1]--; //Month starts with 0 + selected_date = new Date(date_parts[2], date_parts[1], date_parts[0]); + } + } + if (selected_date && !isNaN(selected_date.getFullYear())) { //Valid date. + this.selected = selected_date; } } - if (selected_date && !isNaN(selected_date.getFullYear())) { //Valid date. - this.selected = selected_date; - } + + if (this.start == 'years') + this.showYears(this.selected.getFullYear()); + else if (this.start == 'months') + this.showMonths(this.selected.getFullYear()); + else + this.makeCalendar(this.selected.getFullYear(), this.selected.getMonth()); + + // Position the div in the correct location... + var div = Calendar.box; + var xy = getOffset(input); + var height = input.clientHeight||input.offsetHeight; + div.style.display = "block"; + div.style.left = (xy.left-1)+"px"; + if (div.offsetHeight + xy.top+height-1 >= (document.documentElement.clientHeight||document.body.clientHeight) && + xy.top-div.offsetHeight >= 0) + div.style.top = (xy.top-div.offsetHeight)+'px'; + else + div.style.top = (xy.top+height-1)+"px"; + }; + + /// Hides the currently show calendar. + hideCalendar() + { + Calendar.box.style.display = "none"; } - this.makeCalendar(this.selected.getFullYear(), this.selected.getMonth()); - Calendar.box.style.display = "block"; -}; - -/// Hides the currently show calendar. -Calendar.hideCalendar = function() -{ - Calendar.box.style.display = "none"; -}; - -/// Setup a text input box to be a calendar box. -Calendar.set = function(input_or_id, options) -{ - if (typeof input_or_id == 'string') - input_or_id = document.getElementById(input_or_id); - if (!input_or_id) - return; // If the input field is not there, exit. - options = options||{}; - var instance = new Calendar(); - for (var i in Calendar.defaultOptions) - instance[i] = options[i] || Calendar.defaultOptions[i]; - instance.input = input_or_id; - Calendar.init(); - addListener(input_or_id, 'focus', function(ev) { - instance.showCalendar(); - }); - return instance; -}; - -/// Will be called once when the first input is set. -Calendar.init = function() -{ - if (!Calendar.box || !Calendar.box.parentNode) { - var div = document.createElement('div'); - if (!Calendar.box) - Calendar.box = div; - div.className = "calendar-box"; - addListener(div, "mousedown", function(ev) { - ev = ev || window.event; - if (ev.stopPropagation) - ev.stopPropagation(); - else - ev.cancelBubble = true; - return true; + /// Setup a text input box to be a calendar box. + static set(input_or_id, options) + { + if (typeof input_or_id == 'string') + input_or_id = document.getElementById(input_or_id); + if (!input_or_id) + return; // If the input field is not there, exit. + options = options||{}; + var instance = new Calendar(); + for (var i in Calendar.defaultOptions) + instance[i] = options[i] || Calendar.defaultOptions[i]; + instance.input = input_or_id; + Calendar.init(); + input_or_id.addEventListener('focus', function(ev) { + instance.showCalendar(); }); - document.getElementsByTagName("body")[0].insertBefore(div,document.getElementsByTagName("body")[0].firstChild); - if (!Calendar.addedListener) { - addListener(document, "mousedown", function() { Calendar.hideCalendar(); }); - Calendar.addedListener = true; + return instance; + } + + /// Will be called once when the first input is set. + static init() + { + if (!Calendar.box || !Calendar.box.parentNode) { + var div = document.createElement('div'); + if (!Calendar.box) + Calendar.box = div; + div.className = "calendar-box"; + div.addEventListener("mousedown", function(ev) { + ev = ev || window.event; + if (ev.stopPropagation) + ev.stopPropagation(); + else + ev.cancelBubble = true; + return true; + }); + document.getElementsByTagName("body")[0].insertBefore(div,document.getElementsByTagName("body")[0].firstChild); + if (!Calendar.addedListener) { + document.addEventListener("mousedown", function() { Calendar.instance && Calendar.instance.hideCalendar(); }); + Calendar.addedListener = true; + } } } -}; +} + +window.Calendar = Calendar; + +function getOffsetRect(elem) +{ + var box = elem.getBoundingClientRect(); + + var body = document.body; + var docElem = document.documentElement; + + var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop; + var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft; + var clientTop = docElem.clientTop || body.clientTop || 0; + var clientLeft = docElem.clientLeft || body.clientLeft || 0; + var top = box.top + scrollTop - clientTop; + var left = box.left + scrollLeft - clientLeft; + + return { top: Math.round(top), left: Math.round(left) }; +} + +function getOffsetSum(elem) +{ + var top = 0, left = 0; + while(elem) + { + top = top + parseInt(elem.offsetTop); + left = left + parseInt(elem.offsetLeft); + elem = elem.offsetParent; + } + return { top: top, left: left }; +} + +function getOffset(elem) +{ + if (elem.getBoundingClientRect) + return getOffsetRect(elem); + else + return getOffsetSum(elem); +} diff --git a/calendar.min.js b/calendar.min.js index 5ef4b20..878e6e3 100644 --- a/calendar.min.js +++ b/calendar.min.js @@ -1 +1 @@ -if(!window.Calendar){window.Calendar={month_names:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],close_label:"Закрыть",weekdays:["Пн","Вт","Ср","Чт","Пт","Сб","Вс"],sunday:6,selectboxes:false,years:{min:-70,max:10},format:"d.m.Y",month_days:[31,28,31,30,31,30,31,31,30,31,30,31],today:new Date(),selected:new Date(),opt:{},data:[],addedListener:false,wrt:function(a){this.data.push(a)},fin:function(){this.wrt("");document.getElementById(this.opt.calendar).innerHTML=this.data.join("");this.data=[]},selectDate:function(d,e,a){var c=this.opt.input;var b=c.value.split(/\s+/,2)[1]||"";if(b){b=" "+b}c.value=(this.format=="Y-m-d"?d+"-"+e+"-"+a:a+"."+e+"."+d)+b;this.hideCalendar()},showMonths:function(c,e){var f=this.today.getFullYear();var g=this.today.getMonth();var a=this.selected.getFullYear()==c?this.selected.getMonth():-1;this.wrt("");this.wrt("");this.wrt("");for(var b in this.month_names){if(b&&!(b%3)){this.wrt("")}var d=(cf||c==f&&b>g?"future":"today"))+(b==a?" selected":"");this.wrt("")}this.wrt("");this.wrt("
<");this.wrt(" "+c+"");this.wrt(" >
"+this.month_names[b]+"
");this.fin()},showYears:function(d){var b=d&~15;var f=this.today.getFullYear();var a=this.selected.getFullYear();this.wrt("");this.wrt("");this.wrt("");for(var c=0;c<16;c++){if(c&&!(c%4)){this.wrt("")}var e=(b+cf?"future":"today"))+(b+c==a?" selected":"");this.wrt("")}this.wrt("");this.wrt("
");this.wrt(" <");this.wrt(" "+b+" - "+(b+15)+"");this.wrt(" >");this.wrt("
"+(b+c)+"
");this.fin()},makeCalendar:function(k,x){var a=x+1;var g=k;if(a>=12){a=0;g++}var c=x-1;var f=k;if(c<0){c=11;f--}var m=this.today.getFullYear();this.wrt("");this.wrt("");this.wrt("");for(var b=0;b<7;b++){this.wrt("")}this.wrt("");var o=new Date(k,x,1);var y=(o.getDay()+Calendar.sunday)%7;var v=1;var r=0;if(!(k%4)&&((k%100)||!(k%400))){this.month_days[1]=29}else{this.month_days[1]=28}var t=this.month_days[x];var e=this.today.getFullYear();var u=(k-e)||(x-this.today.getMonth());var z=k==this.selected.getFullYear()&&x==this.selected.getMonth()?this.selected.getDate():-1;for(var s=0;s<=5;s++){if(h>=t){break}this.wrt("");for(var q=0;q<7;q++){if(v>t){r=0}else{if(q>=y&&!r){r=1}}if(r){var h=v,p=x+1;if(h<10){h="0"+h}if(p<10){p="0"+p}var n="";var l=u||(v-this.today.getDate());if(l<0){n=" past"}else{if(!l){n=" today"}else{n=" future"}}if(v==z){n+=" selected"}n+=" "+this.weekdays[q].toLowerCase();this.wrt("");v++}else{this.wrt("")}}this.wrt("")}this.wrt("
<");if(!this.selectboxes){this.wrt(" "+this.month_names[x]+"");this.wrt(" "+k+"")}else{this.wrt(" ");this.wrt("")}this.wrt(" >
"+this.weekdays[b]+"
"+h+" 
");this.fin()},showCalendar:function(){var b=this.opt.input;var h=document.getElementById(this.opt.calendar);var g=getOffset(b);var e=b.clientWidth||b.offsetWidth;var a=b.clientHeight||b.offsetHeight;h.style.left=(g.left-1)+"px";h.style.top=(g.top+a-1)+"px";this.selected=new Date();var d=b.value.replace(/\s+.*$/,"");if(d){var c=false;var f=d.split("-");if(f.length==3){f[1]--;c=new Date(f[0],f[1],f[2])}else{if(f.length==1){f=d.split(".");if(f.length==3){f[1]--;c=new Date(f[2],f[1],f[0])}}}if(c&&!isNaN(c.getFullYear())){this.selected=c}}this.makeCalendar(this.selected.getFullYear(),this.selected.getMonth());document.getElementById(this.opt.calendar).style.display="block"},hideCalendar:function(){document.getElementById(this.opt.calendar).style.display="none"},set:function(a){if(typeof a=="string"){a=document.getElementById(a)}if(!a){return}if(!Calendar.opt.calendar||!document.getElementById(Calendar.opt.calendar)){Calendar.init()}addListener(a,"focus",function(b){Calendar.opt.input=this;Calendar.showCalendar()})},init:function(){if(!this.opt.calendar||!document.getElementById(this.opt.calendar)){var a=document.createElement("div");if(!this.opt.calendar){this.opt.calendar="calender_div_"+Math.round(Math.random()*100)}a.setAttribute("id",this.opt.calendar);a.className="calendar-box";addListener(a,"mousedown",function(b){b=b||window.event;if(b.stopPropagation){b.stopPropagation()}else{b.cancelBubble=true}return true});document.getElementsByTagName("body")[0].insertBefore(a,document.getElementsByTagName("body")[0].firstChild);if(!Calendar.addedListener){addListener(document,"mousedown",function(){Calendar.hideCalendar()});Calendar.addedListener=true}}}}}; \ No newline at end of file +(function(global,factory){if(typeof define==="function"&&define.amd){define(["exports"],factory)}else if(typeof exports!=="undefined"){factory(exports)}else{var mod={exports:{}};factory(mod.exports);global.calendar=mod.exports}})(this,function(exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}var _createClass=function(){function defineProperties(target,props){for(var i=0;i";Calendar.box.innerHTML=html}},{key:"isVisible",value:function isVisible(){return Calendar.instance==this&&Calendar.box.style.display=="block"}},{key:"selectDate",value:function selectDate(year,month,day){var i=this.input;var t=i.value.split(/\s+/,2)[1]||"";if(t)t=" "+t;if(this.callback){var c=this.callback;t=year+"-"+month+"-"+day+t;c(new Date(t))}else{t=(this.format=="Y-m-d"?year+"-"+month+"-"+day:day+"."+month+"."+year)+t;i.value=t;if("Event"in window){var evt=document.createEvent("Event");evt.initEvent("change",true,true);i.dispatchEvent(evt)}else i.fireEvent("onchange")}Calendar.instance.hideCalendar()}},{key:"showMonths",value:function showMonths(year){var cur_y=this.today.getFullYear();var cur_m=this.today.getMonth();var sel_m=this.selected.getFullYear()==year?this.selected.getMonth():-1;var html="";html+="";html+="";html+="";for(var i in this.month_names){if(i&&!(i%3))html+="";var class_name=(yearcur_y||year==cur_y&&i>cur_m?"future":"today")+(i==sel_m?" selected":"");html+=""}html+="";html+="
";html+=" "+year+"";html+="
"+this.month_names[i]+"
";this.setHTML(html)}},{key:"showYears",value:function showYears(year){var beg=year&~15;var cur_y=this.today.getFullYear();var sel_y=this.selected.getFullYear();var html="";html+="";html+="";html+="";for(var i=0;i<16;i++){if(i&&!(i%4))html+="";var class_name=(beg+icur_y?"future":"today")+(beg+i==sel_y?" selected":"");html+=""}html+="";html+="
";html+=" ";html+=" "+beg+" - "+(beg+15)+"";html+=" ";html+="
"+(beg+i)+"
";this.setHTML(html)}},{key:"makeCalendar",value:function makeCalendar(year,month){var next_month=month+1;var next_month_year=year;if(next_month>=12){next_month=0;next_month_year++}var previous_month=month-1;var previous_month_year=year;if(previous_month<0){previous_month=11;previous_month_year--}var current_year=this.today.getFullYear();var html="";html+="";html+="";html+="";for(var weekday=0;weekday<7;weekday++){html+=""}html+="";var first_day=new Date(year,month,1);var start_day=(first_day.getDay()+this.sunday)%7;var d=1;var flag=0;if(!(year%4)&&(year%100||!(year%400)))this.month_days[1]=29;else this.month_days[1]=28;var days_in_this_month=this.month_days[month];var yea=this.today.getFullYear();var all_diff=year-yea||month-this.today.getMonth();var sel_day=year==this.selected.getFullYear()&&month==this.selected.getMonth()?this.selected.getDate():-1;for(var i=0;i<=5;i++){if(w>=days_in_this_month)break;html+="";for(var j=0;j<7;j++){if(d>days_in_this_month)flag=0;else if(j>=start_day&&!flag)flag=1;if(flag){var w=d,mon=month+1;if(w<10)w="0"+w;if(mon<10)mon="0"+mon;var class_name="";var diff=all_diff||d-this.today.getDate();if(diff<0)class_name=" past";else if(!diff)class_name=" today";else class_name=" future";if(d==sel_day)class_name+=" selected";class_name+=" "+this.weekdays[j].toLowerCase();html+="";d++}else html+=""}html+=""}html+="
";if(!this.selectboxes){html+=" "+this.month_names[month]+"";html+=" "+year+""}else{html+=" ";html+=""}html+="
"+this.weekdays[weekday]+"
"+d+" 
";this.setHTML(html)}},{key:"showCalendar",value:function showCalendar(){Calendar.instance=this;var input=this.input;this.selected=new Date;var date_in_input=input.value.replace(/\s+.*$/,"");if(date_in_input){var selected_date=false;var date_parts=date_in_input.split("-");if(date_parts.length==3){date_parts[1]--;selected_date=new Date(date_parts[0],date_parts[1],date_parts[2])}else if(date_parts.length==1){date_parts=date_in_input.split(".");if(date_parts.length==3){date_parts[1]--;selected_date=new Date(date_parts[2],date_parts[1],date_parts[0])}}if(selected_date&&!isNaN(selected_date.getFullYear())){this.selected=selected_date}}if(this.start=="years")this.showYears(this.selected.getFullYear());else if(this.start=="months")this.showMonths(this.selected.getFullYear());else this.makeCalendar(this.selected.getFullYear(),this.selected.getMonth());var div=Calendar.box;var xy=getOffset(input);var height=input.clientHeight||input.offsetHeight;div.style.display="block";div.style.left=xy.left-1+"px";if(div.offsetHeight+xy.top+height-1>=(document.documentElement.clientHeight||document.body.clientHeight)&&xy.top-div.offsetHeight>=0)div.style.top=xy.top-div.offsetHeight+"px";else div.style.top=xy.top+height-1+"px"}},{key:"hideCalendar",value:function hideCalendar(){Calendar.box.style.display="none"}}],[{key:"set",value:function set(input_or_id,options){if(typeof input_or_id=="string")input_or_id=document.getElementById(input_or_id);if(!input_or_id)return;options=options||{};var instance=new Calendar;for(var i in Calendar.defaultOptions){instance[i]=options[i]||Calendar.defaultOptions[i]}instance.input=input_or_id;Calendar.init();input_or_id.addEventListener("focus",function(ev){instance.showCalendar()});return instance}},{key:"init",value:function init(){if(!Calendar.box||!Calendar.box.parentNode){var div=document.createElement("div");if(!Calendar.box)Calendar.box=div;div.className="calendar-box";div.addEventListener("mousedown",function(ev){ev=ev||window.event;if(ev.stopPropagation)ev.stopPropagation();else ev.cancelBubble=true;return true});document.getElementsByTagName("body")[0].insertBefore(div,document.getElementsByTagName("body")[0].firstChild);if(!Calendar.addedListener){document.addEventListener("mousedown",function(){Calendar.instance&&Calendar.instance.hideCalendar()});Calendar.addedListener=true}}}}]);return Calendar}();Calendar.defaultOptions={month_names:["Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь"],close_label:"Закрыть",weekdays:["Пн","Вт","Ср","Чт","Пт","Сб","Вс"],sunday:6,selectboxes:false,years:{min:-70,max:10},format:"d.m.Y",month_days:[31,28,31,30,31,30,31,31,30,31,30,31],today:new Date,callback:null,start:"days"};Calendar.instance=null;Calendar.box=null;Calendar.addedListener=false;window.Calendar=Calendar;function getOffsetRect(elem){var box=elem.getBoundingClientRect();var body=document.body;var docElem=document.documentElement;var scrollTop=window.pageYOffset||docElem.scrollTop||body.scrollTop;var scrollLeft=window.pageXOffset||docElem.scrollLeft||body.scrollLeft;var clientTop=docElem.clientTop||body.clientTop||0;var clientLeft=docElem.clientLeft||body.clientLeft||0;var top=box.top+scrollTop-clientTop;var left=box.left+scrollLeft-clientLeft;return{top:Math.round(top),left:Math.round(left)}}function getOffsetSum(elem){var top=0,left=0;while(elem){top=top+parseInt(elem.offsetTop);left=left+parseInt(elem.offsetLeft);elem=elem.offsetParent}return{top:top,left:left}}function getOffset(elem){if(elem.getBoundingClientRect)return getOffsetRect(elem);else return getOffsetSum(elem)}}); diff --git a/calendar.util.js b/calendar.util.js deleted file mode 100644 index 389c820..0000000 --- a/calendar.util.js +++ /dev/null @@ -1,47 +0,0 @@ -(function() { - -// UTILITY FUNCTIONS -window.addListener = (function() { - return window.addEventListener - ? function(el, type, fn) { el.addEventListener(type, fn, false); } - : function(el, type, fn) { el.attachEvent('on'+type, fn); }; -})(); - -var getOffsetRect = function(elem) -{ - var box = elem.getBoundingClientRect(); - - var body = document.body; - var docElem = document.documentElement; - - var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop; - var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft; - var clientTop = docElem.clientTop || body.clientTop || 0; - var clientLeft = docElem.clientLeft || body.clientLeft || 0; - var top = box.top + scrollTop - clientTop; - var left = box.left + scrollLeft - clientLeft; - - return { top: Math.round(top), left: Math.round(left) }; -}; - -var getOffsetSum = function(elem) -{ - var top = 0, left = 0; - while(elem) - { - top = top + parseInt(elem.offsetTop); - left = left + parseInt(elem.offsetLeft); - elem = elem.offsetParent; - } - return { top: top, left: left }; -}; - -window.getOffset = function(elem) -{ - if (elem.getBoundingClientRect) - return getOffsetRect(elem); - else - return getOffsetSum(elem); -}; - -})(); diff --git a/package.json b/package.json new file mode 100644 index 0000000..b553076 --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "calendarjs", + "author": { + "name": "Vitaliy Filippov", + "email": "vitalif@yourcmc.ru", + "url": "http://yourcmc.ru/wiki/" + }, + "description": "Yet another date picker", + "dependencies": {}, + "devDependencies": { + "babel-cli": "^6.26.0", + "babel-core": "^6.26.0", + "babel-preset-env": "^1.6.1", + "babel-preset-react": "^6.24.1", + "babel-preset-stage-1": "^6.24.1", + "uglify-js": "^3.3.15" + }, + "scripts": { + "compile": "node_modules/.bin/babel calendar.js | node_modules/.bin/uglifyjs > calendar.min.js" + } +} diff --git a/test.htm b/test.htm index 3649be6..64fffb7 100644 --- a/test.htm +++ b/test.htm @@ -1,8 +1,7 @@ - - +