/** * @file datepicker.js * @version 20170905 ms * @type JS * GUI-Komponenten zur Anzeige eines Mini-Kalenders zum Auswählen eines Datums oder einer Datums-Spanne */ class KDatePicker { /** * @class KDatePicker * @constructor complex * param {object} o * param {int} x * param {int} y * param {string:datetime} showDate * param {boolean} minimizable */ constructor(o,x,y,showDate,minimizable){ this.res={ dxs1:{de:"Mo",en:"M",pl:"P"}, dxs2:{de:"Di",en:"T",pl:"W"}, dxs3:{de:"Mi",en:"W",pl:"Ś"}, dxs4:{de:"Do",en:"T",pl:"C"}, dxs5:{de:"Fr",en:"F",pl:"P"}, dxs6:{de:"Sa",en:"S",pl:"S"}, dxs0:{de:"So",en:"S",pl:"N"}, m1:{de:"Januar",en:"January",pl:"Styczeń"}, m2:{de:"Februar",en:"February",pl:"Luty"}, m3:{de:"März",en:"March",pl:"Marzec"}, m4:{de:"April",en:"April",pl:"Kwiecień"}, m5:{de:"Mai",en:"May",pl:"Maj"}, m6:{de:"Juni",en:"June",pl:"Czerwiec"}, m7:{de:"Juli",en:"July",pl:"Lipiec"}, m8:{de:"August",en:"August",pl:"Sierpień"}, m9:{de:"September",en:"September",pl:"Wrzesień"}, m10:{de:"Oktober",en:"October",pl:"Październik"}, m11:{de:"November",en:"November",pl:"Listopad"}, m12:{de:"Dezember",en:"December",pl:"Grudzień"} }; this.selectableFrom=null; this.selectableUntil=null; this.selected=null; this.selectRange=false; this.selectedUntil=null; this.firstDayOfWeek=1; this.DefaultLang="en"; this.Lang="de"; //this.fontSize="11pt"; this.paddingHorizontal=3; this.paddingVertical=1; this.outerBgColor="#FFFFFF"; this.outerBorderColor="#999999"; this.outerBorderColor="#999999"; this.titleColor="#000000"; this.daysColor="#000000"; this.dayOfCurrentMonthColor="#000000"; this.dayOffCurrentMonthColor="#999999"; this.inselectableColor="#999999"; this.todayBorderColor="#999999"; this.todayBgColor="#EEEEEE"; this.selectedColor="#EEEEEE"; if(o) o.style.position="relative"; else{ o=document.createElement("div");document.body.appendChild(o); o.style.position="absolute";o.style.left=x+"px";o.style.top=y+"px";o.style.backgroundColor=this.outerBgColor;o.style.border="1px solid "+this.outerBorderColor; this.closable=true; } this.o=o; var oo=o; var m=this; this.minimizable=minimizable; if(minimizable){ this.ot=document.createElement("table");this.o.appendChild(this.ot);var st=this.ot.style;st.borderSpacing="0";st.borderCollapse="collapse"; var tr=this.ot.insertRow(0); var td=tr.insertCell(0); var st=td.style;st.color=this.titleColor;st.padding=this.paddingVertical+"px "+this.paddingHorizontal+"px";st.cursor="pointer";st.MozUserSelect="none";st.webkitUserSelect="none";st.msUserSelect="none";st.userSelect="none"; td.innerHTML="▼"; oo=tr.insertCell(1); var td2=tr.insertCell(2); var st=td2.style;st.display="none";st.color=this.titleColor;st.fontWeight="bold";st.textAlign="left";st.padding=this.paddingVertical+"px "+this.paddingHorizontal+"px";st.cursor="pointer";st.MozUserSelect="none";st.webkitUserSelect="none";st.msUserSelect="none";st.userSelect="none"; this.minimized=false; td.onclick=function(){m.Toggle()} td2.onclick=function(){m.Toggle()} } this.table=document.createElement("table");oo.appendChild(this.table);var st=this.table.style;st.borderSpacing="1px";st.borderCollapse="collapse"; this.title=""; this.eb=-1; this.table.onmousemove=function(e){m.MouseMove(e)}; this.table.onmousedown=function(e){m.MouseDown(e)}; //this.table.onmouseup=function(e){m.MouseUp(e)}; document.body.addEventListener("mouseup",function(e){m.MouseUp(e)}); if("onmousewheel" in document) this.table.onmousewheel=function(e){m.MouseWheel(e)}; else this.table.addEventListener('DOMMouseScroll',function(e){m.MouseWheel(e)}); if(showDate) showDate=KDatePicker.ParseDate(showDate); if(showDate) this.SetCurrentMonth(showDate.getFullYear(),showDate.getMonth()+1); else{ var today=new Date(); this.SetCurrentMonth(today.getFullYear(),today.getMonth()+1); } this.hooverColor="#FFB400"; } /** * @fn s(id) * @memberof KDatePicker * @param id * @returns * Private method. */ s(id){ var r=this.res[id]; if(r && Object.keys(r).length) return r[this.Lang] || r[this.DefaultLang] || r[Object.keys(r)[0]]; else return "["+id+"]"; } /** * @fn LangChange * @memberof KDatePicker * @param l * Public method. */ LangChange(l){ this.Lang=l; this.Refresh(); } /** * @fn ParseDate(text) * @memberof KDatePicker * @param text * @returns * Private method. */ static ParseDate(text){ if(typeof text=="object" && typeof text.getMonth=='function') return text; else if(typeof text=="string"){ if(text.indexOf(" ")>-1) text=text.substr(0,text.indexOf(" ")); // strip time if(text.indexOf("-")>-1){ var t=text.split("-");if(t.length==3) return new Date(t[0],t[1]-1,t[2]); }else if(text.indexOf(".")>-1){ var t=text.split(".");if(t.length==3) return new Date(t[2],t[1]-1,t[0]); }else if(text.indexOf("/")>-1){ var t=text.split("/");if(t.length==3) return new Date(t[2],t[0]-1,t[1]); } }else return null; } /** * @fn Toggle * @memberof KDatePicker * Private method. */ Toggle(){ this.minimized=!this.minimized; this.ot.rows[0].cells[0].innerHTML=this.minimized?"▶":"▼"; this.ot.rows[0].cells[2].style.display=this.minimized?"":"none"; this.ot.rows[0].cells[2].style.width=this.table.offsetWidth+"px"; this.ot.rows[0].cells[1].style.display=this.minimized?"none":""; } /** * @fn SetSelectable(from,until) * @memberof KDatePicker * @param from * @param until * Public method. */ SetSelectable(from,until){ this.selectableFrom=KDatePicker.ParseDate(from); this.selectableUntil=KDatePicker.ParseDate(until); this.Refresh(); } /** * @fn SetSelect(from,until,ready,noFeedback) * @memberof KDatePicker * @param from * @param until * @param ready * @param noFeedback * Private method. */ Select(from,until,ready,noFeedback){ if(from){if(typeof from!="object" || typeof from.getMonth!=='function') from=KDatePicker.ParseDate(from)} else from=this.selected; if(until){if(typeof until!="object" || typeof until.getMonth!=='function') until=KDatePicker.ParseDate(until)} else until=this.selectedUntil; if(!until) until=from; if(from && until && from.getTime()>until.getTime()){var m=from;from=until;until=m} if(ready || String(this.selected)!=String(from) || String(this.selectedUntil)!=String(until)){ this.selected=from; this.selectedUntil=until; this.Refresh(); if(!noFeedback) this.Selected(this.selected,this.selectedUntil,ready); } } /** * @fn Selected(from,until,ready) * @memberof KDatePicker * @param from * @param until * @param ready * Public method. */ Selected(from,until,ready){ // can be overwritten } /** * @fn EnsureVisible(from,until) * @memberof KDatePicker * @param from * @param until * Private method. */ EnsureVisible(from,until){ if(!(until.getTime()>=this.startDate.getTime() && from.getTime()<=this.endDate.getTime())){ var m=new Date((from.getTime()+until.getTime())/2); this.SetCurrentMonth(m.getFullYear(),m.getMonth()+1); } } /** * @fn SetCurrentMonth(year,month) * @memberof KDatePicker * @param year * @param month * Public method. */ SetCurrentMonth(year,month){ if(month<1){month=12;year--} if(month>12){month=1;year++} this.currentYear=year; this.currentMonth=month; this.startDate=new Date(this.currentYear,this.currentMonth-1,1); while(this.startDate.getDay()!=this.firstDayOfWeek) this.startDate=new Date(this.startDate.getFullYear(),this.startDate.getMonth(),this.startDate.getDate()-1); this.endDate=new Date(this.currentYear,this.currentMonth,0); var lastDayOfWeek=0;if(this.firstDayOfWeek==0) lastDayOfWeek=6;else if(this.firstDayOfWeek==6) lastDayOfWeek=5; while(this.endDate.getDay()!=lastDayOfWeek) this.endDate=new Date(this.endDate.getFullYear(),this.endDate.getMonth(),this.endDate.getDate()+1); this.Refresh(); this.CurrentMonthChanged(year,month); } /** * @fn CurrentMonthChanged(year,month) * @memberof KDatePicker * @param year * @param month * Public method. */ CurrentMonthChanged(year,month){ // can be overwritten } /** * @fn Refresh() * @memberof KDatePicker * Private method. */ Refresh(){ var t=this.table; for(var a=t.rows.length-1;a>=0;a--) t.deleteRow(a); var m=this; var tr=t.insertRow(0); var td=tr.insertCell(0);td.colSpan="7"; var tt=document.createElement("table");td.appendChild(tt);var st=tt.style;st.borderSpacing="0";st.borderCollapse="collapse";st.width="100%"; var ttr=tt.insertRow(0); var ttd=ttr.insertCell(0);var st=ttd.style;st.color=this.titleColor;st.fontWeight="bold";st.textAlign="left";st.padding=this.paddingVertical+"px "+this.paddingHorizontal+"px";st.cursor=this.minimizable?"pointer":"default";st.MozUserSelect="none";st.webkitUserSelect="none";st.msUserSelect="none";st.userSelect="none"; if(this.fontSize) ttd.style.fontSize=this.fontSize; var s=this.s("m"+this.currentMonth)+" "+this.currentYear; ttd.innerHTML=s; if(this.minimizable){ this.ot.rows[0].cells[2].innerHTML=s; ttd.onclick=function(){m.Toggle()} } ttd=ttr.insertCell(1);var st=ttd.style;st.textAlign="right";st.padding=this.paddingVertical+"px 0"; var d=document.createElement("span");ttd.appendChild(d);var st=d.style;st.color=this.titleColor;st.padding="0 "+this.paddingHorizontal+"px";st.cursor="pointer";st.MozUserSelect="none";st.webkitUserSelect="none";st.msUserSelect="none";st.userSelect="none"; if(this.fontSize) d.style.fontSize=this.fontSize; d.innerHTML="◀"; d.onclick=function(){m.SetCurrentMonth(m.currentYear,m.currentMonth-1)} d=document.createElement("span");ttd.appendChild(d);var st=d.style;st.color=this.titleColor;st.padding="0 "+this.paddingHorizontal+"px";st.cursor="pointer";st.MozUserSelect="none";st.webkitUserSelect="none";st.msUserSelect="none";st.userSelect="none"; if(this.fontSize) d.style.fontSize=this.fontSize; d.innerHTML="▶"; d.onclick=function(){m.SetCurrentMonth(m.currentYear,m.currentMonth+1)} if(this.closable){ d=document.createElement("span");ttd.appendChild(d);var st=d.style;st.color=this.titleColor;st.fontWeight="bold";st.paddingLeft=this.paddingHorizontal+"px";st.paddingRight=this.paddingHorizontal+"px";st.cursor="pointer";st.MozUserSelect="none";st.webkitUserSelect="none";st.msUserSelect="none";st.userSelect="none"; if(this.fontSize) d.style.fontSize=this.fontSize; d.innerHTML="X"; d.onclick=function(e){e.stopPropagation();m.Close()} } // draw day of week initials: tr=t.insertRow(1); var dow=this.firstDayOfWeek; var a=0; do{ td=tr.insertCell(a);var st=td.style;st.color=this.daysColor;st.textAlign="center";st.padding=this.paddingVertical+"px "+this.paddingHorizontal+"px";st.cursor="default";st.MozUserSelect="none";st.webkitUserSelect="none";st.msUserSelect="none";st.userSelect="none"; if(this.fontSize) td.style.fontSize=this.fontSize; td.innerHTML=this.s("dxs"+dow); a++; dow++;if(dow>6) dow=0; }while(dow!=this.firstDayOfWeek); // draw plot: var firstDayOfMonth=new Date(this.currentYear,this.currentMonth-1,1); var lastDayOfMonth=new Date(this.currentYear,this.currentMonth,0); var today=new Date(); var day=this.startDate; do{ tr=t.insertRow(); a=0; do{ var col=day.getTime()>=firstDayOfMonth.getTime() && day.getTime()<=lastDayOfMonth.getTime() ? this.dayOfCurrentMonthColor:this.dayOffCurrentMonthColor; var mptr="pointer"; if(this.selectableFrom && day.getTime()this.selectableUntil.getTime()){col=this.inselectableColor;mptr="default"} td=tr.insertCell(a);var st=td.style;st.color=col;st.textAlign="center";st.padding=this.paddingVertical+"px "+this.paddingHorizontal+"px";st.cursor=mptr;st.MozUserSelect="none";st.webkitUserSelect="none";st.msUserSelect="none";st.userSelect="none"; if(this.fontSize) td.style.fontSize=this.fontSize; if(day.getDate()==today.getDate() && day.getMonth()==today.getMonth() && day.getFullYear()==today.getFullYear()){var st=td.style;st.backgroundColor=this.todayBgColor;st.border="1px solid";st.borderColor=this.todayBorderColor;} if(this.selected && day.getTime()>=this.selected.getTime() && day.getTime()<=this.selectedUntil.getTime()) td.style.backgroundColor=this.selectedColor; td.innerHTML=day.getDate(); if(mptr=="pointer"){ td.onmouseover=function(){this.oldBgC=this.style.backgroundColor;this.style.backgroundColor=m.hooverColor} td.onmouseout=function(){this.style.backgroundColor=this.oldBgC} } a++; day=new Date(day.getFullYear(),day.getMonth(),day.getDate()+1); }while(day.getDay()!=this.firstDayOfWeek); }while(day.getTime()=this.table.rows[2].offsetTop){ e.preventDefault(); e.stopPropagation(); var row=Math.floor((ey-this.table.rows[2].offsetTop)/this.table.rows[3].offsetHeight); var col=Math.floor(ex/this.table.offsetWidth*7); this.day=this.startDate; for(var a=0;athis.selectableUntil.getTime()){selectable=false;this.day=this.selectableUntil} if(this.eb>-1){ if(this.selectRange && this.day1) this.Select(this.day1,this.day); else this.Select(this.day,this.day); }else if(!selectable) this.day=null; }else this.day=null; } /** * @fn MouseWheel(e) * @memberof KDatePicker * @param e * Private method. */ MouseWheel(e){ var raw=e.detail?e.detail:e.wheelDelta; var d=e.detail ? e.detail * -1 : e.wheelDelta/40; if(d>0) d=1; else if(d<0) d=-1; this.SetCurrentMonth(this.currentYear,this.currentMonth-d); e.preventDefault(); e.stopPropagation(); } /** * @fn Close() * @memberof KDatePicker * Public method. */ Close(){ if(this.closable) document.body.removeChild(this.o); this.Closed(); } /** * @fn Closed() * @memberof KDatePicker * Public method. */ Closed(){ // can be overwritten } }