Tuesday, December 14, 2010

Calendar PopUp

There has been quite a number of Javascript Calendar PopUp available in the internet. Many of them are very professionally made. However, I seems to have trouble using them. They either do not work out-of-the-box or needs a few settings here and there to function properly.

What I wanted is to have a very simple utility that allows me to choose a date in a limited format. I do not want to have too many settings. My habit is always to make life easy for programmers by not bothering them with too much options in my library.

The following is my version of a CalendarPopUp.

var $cP=function(myid,query2,query3){
// must set the id value of the date input element to work properly
// call the funcstion and pass the id value and type (MDY,DMY or YMD). query3 is not user definable
//remember to set the date input element to read only
var months=['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
if (typeof(query3) != "undefined"){
var odate=query3.split("-")
var curdate=new Date(odate[0],odate[1],odate[2],0,0,0,0)
}
else
var curdate=new Date()
var curmth=curdate.getMonth()+1
var curyr=curdate.getFullYear()
var x,y
fdm=new Date(curdate.getFullYear(),curdate.getMonth(),1,0,0,0,0)
if(fdm.getMonth() !=0)
ldm=fdm.getFullYear()+"-"+(fdm.getMonth()-1)+"-"+fdm.getDate()
else
ldm=(fdm.getFullYear()-1)+"-11-"+fdm.getDate()
ndm=fdm.getFullYear()+"-"+(fdm.getMonth()+1)+"-"+fdm.getDate()
fdm.setDate(fdm.getDay()*-1)
var $winP=window.open("","cP","toolbar=0,location=0,drectories=0,menubar=0,scrollbars=0,resizable=0,width=250,height=200,status=0",true)
obj=$winP.document
obj.write('<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">')
obj.write('<html><head><title>Calendar</title>\n');
obj.write('<style type=\'text\/css\'>\n')
obj.write('table {width:100%;border-width: 3px;border-style:solid;border-spacing:0;border-collapse:collapse;}\n')
obj.write('td,th {font-size:12px;margin:0px;border-width: 2px 2px 2px 2px;border-style:solid;border-spacing:0;border-collapse:collapse;text-align:center;cursor:hand}\n')
obj.write('td:hover {background-color:yellow;font-weight:bold;cursor:pointer}\n')
obj.write('.hv:hover {background-color:yellow;font-weight:bold;cursor:pointer}\n')
obj.write('.igray {background-color:#BDBDBD}\n')
obj.write('.iwhite {background-color:white}\n')
obj.write('p {width:100%;text-align:center;margin:0}\n')
obj.write('<\/style>\n')
obj.write('</head><body>');
obj.write('<table>');
obj.write('<tr><th class=\'hv\' onclick=window.opener.$cP(\"'+myid+'\",\"'+query2+'\",\"'+ldm+'\")>&lt;</th><th colspan=5>'+months[curdate.getMonth()]+" "+ curdate.getFullYear()+'</th><th class=\'hv\' onclick=window.opener.$cP(\"'+myid+'\",\"'+query2+'\",\"'+ndm+'\")>&gt;</th></tr>')
obj.write('<tr><th>S</th><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th></tr>')
var myhtml=""
fdm.setDate(fdm.getDate()+1)
for (x=1;x<=5;x++){
myhtml +="<tr>"
for(y=1;y<=7;y++){
newmth=fdm.getMonth()+1
newyr=fdm.getFullYear()
if (curmth != newmth || curyr != newyr)
cal='igray'
else
cal='iwhite'
switch (query2){
case "MDY":
sdm=(fdm.getMonth()+1)+"/"+fdm.getDate()+"/"+fdm.getFullYear()
break
case "DMY":
sdm=fdm.getDate()+"/"+(fdm.getMonth()+1)+"/"+fdm.getFullYear()
break
default:
sdm=fdm.getFullYear()+"-"+(fdm.getMonth()+1)+"-"+fdm.getDate()
}
myhtml +="<td class='"+cal+"' onclick='window.opener.document.getElementById(\""+myid+"\").value=\""+sdm+"\";self.close()'>"+fdm.getDate()+"</td>\n"
fdm.setDate(fdm.getDate()+1)
}
myhtml +="</tr>"
if (x==5 && fdm.getDate() > 29)
x -=1
}
obj.write(myhtml)
obj.write('</table>');
obj.write('<p><a href="javascript:self.close()">close</a></p>');
obj.write('</body></html>');
obj.close();
obj.focus();

}

There is no preset available. The function is complete by itself. Just call the function and pass the necessary parameter and that is all.

In your form you would set the date input field as below example

<input type="text" name="mydate" id="mydate" value="" readonly onclick="$cP(this.id,'YMD')">

When user clicks on the input, the calendar will popup for user to choose a date.

User can navigate by month to choose different months using the "<" and ">" on both sides of the month indicator.

The second parameter of the $cP function has three formats. "YMD" displays "YYYY-MM-DD" format. "DMY" displays "DD/MM/YYYY" format. Finally, "MDY" displays "MM/DD/YYYY" format.

I do not want to add more options beside the three that I always use. It is up to individuals to add their own options. Adding it is very simple. Just go to the place where the switch(query2) is and add another case option.

The above is tested on IE7. Although I could not make the size of the popup less than that which IE7 limited. It worked just fine. Even the css hover worked after I set the DTD to "strict".

On Firefox, the window features seems to have a mind of its own. It does not allow me to hide a number of features which I turned off. However, this is firefox's preferred setting and since it does not hamper the functionality, it is acceptable despite having a bit too much unnecessary things.

On Chrome, only the address line is still visible.

I did not have other browsers installed thus does not test those.


No comments:

Post a Comment