I wrote this date chooser because the ones I could find on the Internet were crummy, too complicated, or not free. The point is to make form entry more usable and help the user enter valid data (of course, you still need to validate your input when processing). I also wanted to code to be compact and fast, and not require a bunch of ugly code injected into the web page.
I made a demo so you can see it in action.
This code uses some code from my article about date formatting and parsing via dynamic code generation, to implement a date-formatting syntax similar to PHP’s date function.
The script depends upon date-functions.js, datechooser.js, select-free.css, and datechooser.css.
How to use it
To create a date-chooser on your HTML document, follow these steps:
- Include the CSS and JavaScript files in the
headof your document. - Wrap
select-free.cssin a conditional comment for IE, as in the demo. - Create a form, a
divto hold the date chooser, a form field to hold the results, and an image to trigger showing and hiding the chooser, as below.
Here’s some sample code:
<input id="dob" name="dob" size="10" maxlength="10" type="text"/><img src="/files/calendar.gif" onclick="showChooser(this, 'dob', 'chooserSpan', 1950, 2010, 'Y-m-d', false);"/> <div id="chooserSpan" class="dateChooser select-free" style="display: none; visibility: hidden; width: 160px;"> </div>
This code causes the date chooser to be shown with a date range of 1950 to 2010, with the date formatted in ISO-8601 date format.
Updates
On May 26 2006, I decided I could no longer procrastinate and integrated many of the helpful suggestions from the comments into the code. Thanks to all who wrote in comments suggesting improvements, and a big thanks to Jared for integrating a bunch of code for me and sending me a comment about it. Changes include a fix for the IE problem of select fields showing through, no conflicts with the Prototype library, and a cleaner show/hide behavior.

Great JavaScript!
Worked perfectly right off the bat! You’re right - it was SO hard to find something useful and elegant until I saw yours.
Thanks again!
Thanks for a great DateChooser, I use it and modified it for my own needs. As I often need to choose months nearby, I added some buttons to step to the previous / next month. If someone wants to try it, here is what you need:
Change row number 178 in
datechooser.jsfrom:var formHtml = " // Creates the extra HTML for monthStepper. DateChooser.prototype.createMonthStepperHtml = function() { var result = " " + "' onclick=\"" + "if(document.forms[0]." + this._prefix + "month.selectedIndex != 11){" + "document.forms[0]."+ this._prefix + "month.selectedIndex++;" + "dateChooserDateChange(this.form, '"+ this._prefix + "');" + "}else{" + "document.forms[0]." + this._prefix + "year.selectedIndex++;" + "document.forms[0]." + this._prefix + "month.selectedIndex = 0;" + "dateChooserDateChange(this.form, '"+ this._prefix + "');" + "}\">" return result; }[ED: It looks like some of the code might have gotten zapped by the comment form. I gotta fix that so people can submit comments with code in them. I think the idea comes through though. Thanks air!
Here is the code correcting the previous post. I suppose it can be written more ‘elegant’. Though it works :)
DateChooser.prototype.createChooserHtml = function() { var formHtml = "" + "rn " +"<a><<” +”"; for (var mon in Date.monthNames) { formHtml += “rn ” + Date.monthNames[mon] + “”; } formHtml += “rn rn “; for (var i = this._start; i ” + i + “”; } formHtml += “rn rn” +”<a>>></a>rn”; formHtml += this.createCalendarHtml(); if (this._isTimeChooser) { formHtml += this.createTimeChooserHtml(); } return formHtml; }Enjoy!
Thanks for sharing this great little tool with us.
SELECT CAUSES PROBLEM IN IE (FIX?)
Note that I really needed to use this for an internal intranet site but the necessary iframe code was, of course, missing.
Using some code from http://www.hedgerwow.com/360/bugs/css-select-free.html I altered the second to last line of datechooser.js:
Note you will need (1) to add the class ’select-free’ to the dateChooser div and (2) add the following css style definition for the iframe to fix the select options from bleeding through:
.select-free { position:absolute; z-index:10; cursor:hand; overflow:hidden;/*must have*/ width:33em;/*must have for any value*/; } .select-free iframe { display:none;/*sorry for IE5*/ display/**/:block;/*sorry for IE5*/ position:absolute;/*must have*/ top:0;/*must have*/ left:0;/*must have*/ z-index:-1;/*must have*/ filter:mask();/*must have*/ width:3000px;/*must have for any big value*/ height:3000px/*must have for any big value*/; }Thank you so much, your open source code is clean and brief. I hope this small contribution can serve as my portion of payment for your work!
Jay
Excellent little script. I love the variety of ways that the date text is returned as well.. THANK YOU!!!!
This is a great script. Thanks for posting it!
I noticed that the onChange event was not being fired by this script when the date was changed. As I had other JS code watching for when the date value changed, I inserted this single line:
I put it immediately after the input value changes, so lines 61-63 of function dateChooserSetDate() in datechooser.js look like this:
Hope that helps someone.
Excellent work! Thank you very much. Rarely do scripts work “out of the box” for both IE and FF. Kudos to you my friend.
-nX
Any chance you could LGPL this? It’s a nice piece of work, but I can’t use it with the GPL license.
Sam, that’s a great suggestion. I have always GPL’ed everything I’ve let other people have, without much further thought, but now that I’m writing re-usable components and libraries that’s not the best idea. I will re-license this and all the other scripts I’ve released, and announce it when I’m done. Subscribe via feed or email to be notified when I do that (should be this weekend).
The code to position the div does not seem to work correctly if used with fieldsets.
I use it with fieldsets all the time, so there must be something else that’s conflicting as well. Perhaps the combination of fieldsets and something else? If you can take a page that has a problem, and trim everything out until you have as small a test case as possible that demonstrates the problem, I’d appreciate it. You can email me directly at .
Great script! I love it!
Has anyone, or does anyone know if, I can modify this so only weekdays are selectable? I’m sure it’s easy. But I can’t find it for the life of me. Thanks in advance!
Sean
Awesome… I only know one other guy who did this. How do you guys do it! Amazing!
Hello, nice calendar:) I seem to have a problem when placing them side by side. The calendar shows too far the right.
I’m glad that you make this script as it is very useful. However, I find some problems. The code
Must be enclosed inside a form, or else it does not refresh the calendar when the pulldown menu is changed. And I discovered another interesting bug (which almost made me kill myself :P). Consider the following code:
Notice that the form tag is inside the table tag.This works just fine with IE. However, if you’re using Opera / Firefox, the calendar doesn’t refresh when the pulldown menu is changed. Interestingly, if the form tag is moved outside the table tag it’ll work just fine. I cannot fix them as I am not really that familiar with JavaScript and I don’t have the time to learn at the moment. I would really appreciate if you can mail me the solution to fix these problems.
Cheers,
Vince
I’ve encapsulated your date chooser into an ASP .NET 2.0 User Control if you are interested. Your javascript provided the foundation for one of the best Date Choosers I’ve seen to date, so I just wanted to make it available for any .Netters who may want such a capable control. Please email me if you would like me to email you the source for your posting.
Vince, sorry the blog software deleted your code segments :-( However, I have these comments in reply: a form control must always be enclosed inside a FORM element according to the HTML 4 spec, and placing the form directly inside a TABLE element is also invalid HTML 4. These may help you solve your problems. Also, it may help to use a validator — the Web Developer extension for Firefox has one, and there is also a HTML Tidy extension that may be more convenient; and Opera has a right-click option (or used to) to validate the page too. Browsers are beginning to be pickier about valid HTML, which I think is great.
I hope that helps!
Hi Francis, it sounds like you may be having a problem with floating elements stacking next to each other. Can you make a test case and post it somewhere, then post another comment with a link to it?
Fix for the positioning problem reported by vericgar:
DateChooser.prototype.show = function() { // calculate the position before making it visible var inputPos = getAbsolutePosition(this._input); // JV 20060724 Fix where _div was not positioned correctly when rendered inside another absolutely positioned div this._div.style.top = (inputPos[0] + this._input.offsetHeight - parseInt(this._div.offsetParent.style.top)) + "px"; this._div.style.left = (inputPos[1] + this._input.offsetWidth - parseInt(this._div.offsetParent.style.left)) + "px";I found that when you use the datechooser within another absolutely positioned div, the code
has the _div actually display itself at X + the parent div’s left. This resolved the problem for me.
Hmm, it still seems as if I am having a problem getting the “selection field” to show up in IE still.
I think I tried to follow the instructions, but I’m having trouble getting it to work.
I’m new to CSS and JS so this is a little difficult for me.
Thank you.
Positioning problem afterburner:
On my previous post, I provided code that seemed to solve the positioning problem for the date-time chooser popup. However, when testing in other context and with other browser, this code failed. Now I’ve solved it in another way by changing the
getAbsolutePositionfunction as follows :// Gets the absolute position on the page of the element passed in function getAbsolutePosition(obj) { var result = [0, 0]; // JV 15082006 : stop at first absolutely positioned element while ((obj != null)&&(obj.style.position != 'absolute')) { result[0] += obj.offsetTop; result[1] += obj.offsetLeft; obj = obj.offsetParent; }This now seems to do the job for me - at least, the popup now show up where you expect it independent of the page structures I’ve tested and identically between IE and FF.
Zach, if Xaprb isn’t interested, I certainly am. Let me know if the offer is still available. It’ll keep me from reinventing several wheels. My email is [deleted].
Kaa, Zach never followed through, sorry. I was very interested and offered to bundle it all together, and we had some emails about it. I’ll ping him back again and see if he’s still willing to put it together.
Excellent.
Hi,
This is very good control.
How do I show date control as is? Without a need of clicking on image icon.
Thanks
Can it be used in Inline calendar mode? The calendar is displayed on the page as part of its design. The example illustrates it use as a popup. It needs click on image.
You could with some modification. I have neglected this script for quite a while, but you can look for me to put more time into it in the next couple of articles. There are several problems — it is not independent of other elements on the page, its CSS isn’t well-separated from other elements, it assumes you’ll want a pop-up, it makes global JavaScript variables and functions, etc etc. I am going to put some time into that and remedy it, if for no other reason than we need it at work and it’s not working well because of CSS conflicts.
Many thanks for a very functional script.
Regards
Ugo
great job. i’m gonna use it.
Great script. However, perhaps you should consider making it completely unobtrusive. The span container needed could be written in by the dom, as could the image - and then you could hook the script up on a input-field with a class=”date-field”, and the title attribute could contain the format for the response from the calender.
Yep, I’ve been meaning to do that. That, and move everything into a Xaprb namespace to avoid conflicts with other scripts. I’ve learned a lot since I banged this out a few years ago.
Very nice! This is something I needed yet did not know how to create from scratch.
Would it be very difficult to put a little “x” in the top right corner so that the user could close the calendar (say if they are just looking at it or otherwise don’t click on a date)?
Not too hard I think, but I’m still struggling to get time to rewrite this. Right now I’m in the middle of a rewrite of innotop, which I consider more important.
Hi-
first off- brilliant calendar script! really has helped me a lot. I have a question tho- i’ve put the script alteration in above that’s supposed to fix the positioning problem but it doesn’t seem to work.
I have 2 layers going on (including the datechooser) and it seems to take the positioning from the containing layer even if I put another layer in between. Consequently, the chooser opens up miles away from the image.
I don’t know enough about JavaScript to know where the problem is- could anyone help out?
Great script buddy I’ve looked everywhere but I couldnt get anything close to what you’ve done, congrats. I tried modifying the demo above to suit my use which is pretty much similar to what is done in the demo. However I wasnt successful so I tried the exact script as that for the demo and it didnt work. The image click is not triggering the pop-up response. Can you please advise me on how i can work around this. Thank you
I’m sorry, I simply don’t have time to work on this at the moment, and probably won’t for months… I hope someone else can jump in and make some improvements to this script, including fixing some CSS and positioning bugs (or at least advising people how to solve it themselves in some common situations), making more options for how to show and hide the chooser, and using unobtrusive Javascript.
Thank you for this wonderful script!
I found that the following 2 enhancements to the showChooser() script have made this a little easier. If the date chooser is showing, clicking in the document outside of the chooser, or on a subsequent chooser icon should cause the chooser to hide. This script causes this behavior. see comments below…
function showChooser(obj, inputId, divId, start, end, format, isTimeChooser) { if (document.getElementById) { var input = document.getElementById(inputId); var div = document.getElementById(divId); if (input !== undefined && div !== undefined) { if (input.DateChooser === undefined) { input.DateChooser = new DateChooser(input, div, start, end, format, isTimeChooser); } input.DateChooser.setDate(Date.parseDate(input.value, format)); if (input.DateChooser.isVisible()) { input.DateChooser.hide(); } else { input.DateChooser.show(); } input.focus();// add this line input.onblur=function(){this.DateChooser.hide();} // and this line too } } }This script is awesome, thank you. Just to let you know the iframe tag datechooser.js causes a security warning if used on an https domain. I attempted to get around this by setting up a dummy src for the iframe, but it did not work so I just dropped support for IE 6.5. Let me know if you have any solution for this, I played around with it for awhile and couldn’t come up with anything
I know I saw a couple post asking about this…didn’t see a response. I too noticed the bug with using the drop downs to change the month and year. Apparently IE dies if you add the form tag in there….and all the other GOOD browser need it to work. so here is what I did to fix it.
Here is the link for the browser detect if anyone needs it.
http://www.quirksmode.org/js/detect.html
Hope this helps.
DateChooser.prototype.createChooserHtml = function() { var browserName = BrowserDetect.browser; var formHtml = ""; if(browserName != "Explorer") formHtml += "<form id='dateChooserForm'>"; formHtml += "<input type="hidden" name="" + this._prefix + "inputId" value="" + this._input.getAttribute('id') + "">" formHtml += "rn <select name="" + this._prefix + "month" onChange="dateChooserDateChange(this.form, '" + this._prefix + "');">"; for (var mon in Date.monthNames) { // Patch: 2007-03-29, Need to test mon to be an integer since monthNames contain added functions from the prototype.js script var mon_int = parseInt(mon); if(mon_int == mon-0) { formHtml += "rn <option value="" + mon + """ + (mon == this._date.getMonth() ? " selected="1"" : "") + ">" + Date.monthNames[mon] + "</option>"; } } formHtml += "rn </select>rn"; //var formHtml += "rn <select name="" + this._prefix // + "month" onChange="dateChooserDateChange(this.form, '" // + this._prefix + "');">"; //for (var mon in Date.monthNames) { // formHtml += "rn <option value="" + mon + """ // + (mon == this._date.getMonth() ? " selected="1"" : "") // + ">" + Date.monthNames[mon] + "</option>"; //} //formHtml += "rn </select>rn"; formHtml += "<select name="" + this._prefix + "year" onChange="dateChooserDateChange(this.form, '" + this._prefix + "');">"; for (var i = this._start; i <= this._end; ++i) { formHtml += "rn <option value="" + i + """ + (i == this._date.getFullYear() ? " selected="1"" : "") + ">" + i + "</option>"; } formHtml += "rn </select>"; formHtml += this.createCalendarHtml(); if (this._isTimeChooser) { formHtml += this.createTimeChooserHtml(); } if(browserName != "Explorer") formHtml += "</form>"; return formHtml; }Your script is fantastic. I’m in Brazil. Thanks!
Hi guys,
Not sure if this is possible to fix, but I have hit upon a problem using this script. I have the demo code placed within a div that has this CSS tag assigned to it:
#main-copy {
color: black;
background-color: white;
margin: auto;
padding: 0.5mm 5mm 5mm 5mm;
min-height: 479px;
border: 1px solid #000;
width: 200px;
}
* html #main-copy {
height: 479px;
position: relative;
left: -3px;
}
Firefox and IE7 display the popup exactly underneath the small calendar.gif whereas in IE6, the popup jumps along way to the right and below it! The only thing that seems to stop this behaviour is removing the position: relative, and left: -3px styles, but i would ideally like to keep these. Is there an easy way around this? Many thanks,
Dan
Thank you so much, that code very useful and easy to use
What if the user has an arbitrary amount of date fields that they wish to enable this date chooser behavior. And given that they have no way to implement explicit IDs for each date field. Due to the nature of passing HTML with embedded onclick events this prevents any kind of DOM oriented implementations. I was really hoping to get away with passing the showChooser method actual elements instead of just their IDs and have it run that way. but the method createCalendarHtml completely fubars that approach.
I totally hear you. I’d write it differently now if I were to do it over again. If you fix this issue, please send your changes to me.
This script is fantastic. Congratulations!!
– always looking for simple code –
excellent.
It seems that in the demo the nice mouse-over “navy” background in FF is not seen in IE. I have created a workaround for this:
1) Added a fake link in datechooser.js (line 258 or so):
result = “\r\n ” “ ” i ” ” “”;
2) Added following css code in datechooser.css:
a.test123 {
.color:black;
.text-decoration:none;
}
a.test123:hover {
.background:navy;
}
Hope this helps someone who had struggles like me with IE.
-Jonathan
I was trying to add a bug fix but it seems not taking it.
If I make a link out of “i” in line 260 of datechooser.js, I am able to add a css class to datechooser.css file. Then I will be able to see the nice mouse-over background in IE just as in FF.
Thanks for this tool, it was very helpful!
I wish to use the \DateChooser with the calender and time choice. However, I do not want the time to be the current time, though the date is ok shown as hte current date in case no date is supplied. However, I do nto want time ot be chosen as the current time.
I cannot get it to work around.
The idea being the user may choose only date or both date and time. The default time is not appropriate for this.
Can anyone give any ideas?