From e5c55c9f126ee118fe0d37d7cf4d28ac5e461e77 Mon Sep 17 00:00:00 2001 From: Vitaliy Filippov Date: Sat, 17 Mar 2018 21:30:04 +0300 Subject: [PATCH] Reposition on change --- calendar.js | 20 ++++++++++++++++++++ calendar.min.js | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/calendar.js b/calendar.js index 4bd618f..7f186d1 100644 --- a/calendar.js +++ b/calendar.js @@ -40,6 +40,18 @@ export class Calendar { html += ""+this.close_label+""; Calendar.box.innerHTML = html; + if (this.position) + { + // Position the div in the correct location... + var div = Calendar.box; + var xy = getOffset(this.input); + var height = this.input.clientHeight||this.input.offsetHeight; + div.style.left = (xy.left-1)+"px"; + if (this.position == 'top') + div.style.top = (xy.top-div.offsetHeight)+'px'; + else + div.style.top = (xy.top+height-1)+"px"; + } } isVisible() @@ -267,6 +279,8 @@ export class Calendar } } + this.position = ''; + if (this.start == 'years') this.showYears(this.selected.getFullYear()); else if (this.start == 'months') @@ -282,9 +296,15 @@ export class Calendar 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) + { + this.position = 'top'; div.style.top = (xy.top-div.offsetHeight)+'px'; + } else + { + this.position = 'bottom'; div.style.top = (xy.top+height-1)+"px"; + } }; /// Hides the currently show calendar. diff --git a/calendar.min.js b/calendar.min.js index 878e6e3..978fa65 100644 --- a/calendar.min.js +++ b/calendar.min.js @@ -1 +1 @@ -(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)}}); +(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;if(this.position){var div=Calendar.box;var xy=getOffset(this.input);var height=this.input.clientHeight||this.input.offsetHeight;div.style.left=xy.left-1+"px";if(this.position=="top")div.style.top=xy.top-div.offsetHeight+"px";else div.style.top=xy.top+height-1+"px"}}},{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}}this.position="";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){this.position="top";div.style.top=xy.top-div.offsetHeight+"px"}else{this.position="bottom";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)}});