1 Overview
1.1 How does The Calendar work?
2 Quick startup
2.1 Installing a popup calendar
2.2 Installing a flat calendar
2.2.1 Flat calendar with multiple days
2.3 Zapatec.Calendar.setup in detail
3 The Calendar object overview
3.1 Creating a calendar
3.2 Order Matters
3.3 Caching the Calendar object
3.4 Callback functions
4 The DHTML Calendar object API reference
4.1 Calendar constructor
4.2 Useful member variables (properties)
4.3 Public methods
4.3.1 Calendar.create
4.3.2 Calendar.callHandler
4.3.3 Calendar.callCloseHandler
4.3.4 Calendar.hide
4.3.5 Calendar.setDateFormat
4.3.6 Calendar.setTtDateFormat
4.3.7 Calendar.setDateStatusHandler
Calendar.setDateStatusHandler and disabling times
4.3.8 Calendar.show
4.3.9 Calendar.showAt
4.3.10 Calendar.showAtElement
Vertical alignment
Horizontal alignment
Default values
4.3.11 Calendar.setDate
4.3.12 Calendar.setFirstDayOfWeek
4.3.13 Calendar.parseDate
4.3.14 Calendar.setRange
The Zapatec DHTML Calendar provides your site’s end-users with an easy-to-use, versatile, and interactive way to select the date and time. The Calendar can be set up to pop up ("popup version") on user action or remain on the screen all the time ("flat version" great for blogging!). The Calendar works in many different browsers including Internet Explorer, Mozilla, Opera 7, Firefox, Safari, and Konqueror. The DHTML Calendar is the best choice for ensuring that your site’s visitors can use your form or application because of this cross-browser compatibility.
You can find the latest info and version at the Calendar in the products section of Zapatec’s home page at
The Calendar employs DHTML (dynamic HTML) for a combination of an easily customizable application and an attractive, simple, end-user experience. DHTML refers to the combination of Hyper Text Markup Language (HTML), Cascading Style Sheets (CSS), JavaScript and Document Object Model (DOM). DOM is a set of interfaces that glues the other three together. In other words, DOM allows dynamic modification of an HTML page through a program. The Calendar’s programming and modifications are in JavaScript, and its appearance is customized with Cascading Style Sheets (CSS).
Using DOM calls, the program dynamically creates a <table> element that contains a calendar for the given date and then inserts it in the document body. It then shows this table at a specified position. Usually the position is related to some element in which the date needs to be displayed/entered, such as an input field.
The layout and colors of the calendar are controlled by CSS attributes. By assigning a certain CSS class to the table we can control the look of the calendar. To change the colors, backgrounds, rollover effects and other CSS properties, you can change the CSS file—modification of the program itself is not necessary.
First you have to include the needed scripts and style-sheet. Make sure you do this in your document’s <head> section. Make sure you put the correct paths to the scripts.
<style type="text/css">@import url(calendar-win2k-1.css);</style> <script type="text/javascript" src="utils.js"></script> <script type="text/javascript" src="calendar.js"></script> <script type="text/javascript" src="lang/calendar-en.js"></script> <script type="text/javascript" src="calendar-setup.js"></script>
Now suppose you have the following HTML:
<form ...> <input type="text" id="data" name="data" /> <button id="trigger">...</button> </form>
You want the button to popup a calendar widget when clicked? Just insert the following code immediately after the HTML form:
<script type="text/javascript"> Zapatec.Calendar.setup( { inputField : "data", // ID of the input field ifFormat : "%m %d, %Y", // the date format button : "trigger" // ID of the button } ); </script> <noscript> <br/> This page uses a <a href='http://www.zapatec.com/products/prod1'> Javascript Calendar </a>, but your browser does not support Javascript. <br/> Either enable Javascript in your Browser or upgrade to a newer version. </noscript>
The Calendar.setup function, defined in calendar-setup.js, takes care of "patching" the button to display a calendar when clicked. The calendar is by default in single-click mode and linked with the given input field, so that when the end-user selects a date it will update the input field with the date in the given format and close the calendar.
By looking at the example above we can see that the function Calendar.setup receives only one parameter: a JavaScript object. Further, that object can have lots of properties that tell to the setup function how would we like to have the calendar. For instance, if we would like a calendar that closes at double-click instead of single-click we would also include the following: singleClick:false.
For a list of all supported parameters please see the section 2.3.
You can configure a flat calendar, using the same Calendar.setup function. First, you should have an empty element with an ID. This element will act as a container for the calendar. It can be any block-level element, such as DIV, TABLE, etc. We will use a DIV in this example.
<div id="calendar-container"></div>
Then there is the JavaScript code that sets up the calendar into the "calendar-container" DIV. The code can occur anywhere in HTML after the DIV element.
<script type="text/javascript"> function dateChanged(calendar) { // Beware that this function is called even if the end-user only // changed the month/year. In order to determine if a date was // clicked you can use the dateClicked property of the calendar: if (calendar.dateClicked) { // OK, a date was clicked, redirect to /yyyy/mm/dd/index.php var y = calendar.date.getFullYear(); var m = calendar.date.getMonth(); // integer, 0..11 var d = calendar.date.getDate(); // integer, 1..31 // redirect... window.location = "/" + y + "/" + m + "/" + d + "/index.php"; } }; Zapatec.Calendar.setup( { flat : "calendar-container", // ID of the parent element flatCallback : dateChanged // our callback function } ); </script> <noscript> <br/> This page uses a <a href='http://www.zapatec.com/products/prod1'> Javascript Calendar </a>, but your browser does not support Javascript. <br/> Either enable Javascript in your Browser or upgrade to a newer version. </noscript>
You can set up a flat calendar where the user can choose multiple days just as you can a popup calendar. But how do you tell the calendar to submit the dates? With a popup calendar you click on the close button. With a flat calendar you need to call the submitFlatDates method of the calendar. The following code shows setting up the calendar.
var flatCalObj = Zapatec.Calendar.setup({ flat : "flatcalMultiDays", // ID of the parent element flatCallback: flatCallback, align : "BR", showOthers : true, //sortOrder : "desc", //default is "asc"ending; or remove comment to //sort in "desc"ending order; or "none" to NOT sort the multiple dates. multiple : MA // pass the initial or computed array of multiple dates //to be initially selected });
and you can fetch the dates using
<input type="button" value="Submit" id='button7' onClick="flatCalObj.submitFlatDates();" name="button7">
When the user clicks on the Submit button the onclick will call submitFlatDates on the flatCalObj calendar object. The calendar will then call the callback with the array of dates.
Below is the complete list of properties interpreted by Zapatec.Calendar.setup. All of them have default values, so you can pass only those that you would like to customize. Regardless, you must pass at least one of inputField, displayArea or button, for a popup calendar, or flat for a flat calendar. Otherwise you will get a warning message saying that there is nothing to setup.
You can set up a fully functional Calendar with the function presented in the previous section.
This advanced section will give you the information you need to add functionality and customize the calendar even further.
The file calendar.js implements the functionality of the calendar. Almost all functions and variables are embedded in the JavaScript object "Calendar".
You can instantiate a Calendar object by calling the constructor with the following code: var cal = new Calendar(...). We will discuss the parameters later. After creating the object, the variable cal contains a reference to the Calendar object. You can use this reference to access further options of the calendar, for instance:
cal.weekNumbers = false; // do not display week numbers cal.showsTime = true; // include a time selector cal.setDateFormat("%Y.%m.%d %H:%M"); // set this format: 2003.12.31 23:59 cal.setDateStatusHandler(function(date, year, month, day) { // verify date and return true if it has to be disabled // "date" is a JS Date object, but if you only need the // year, month and/or day you can get them separately as // next 3 parameters, as you can see in the declaration if (year == 2004) { // disable all dates from 2004 return true; } return false; });
The Calendar is created by following some of the same steps as are found in section 2. While you can skip optional (marked "opt") steps if you’re happy with the defaults, using the order outlined below will make it easier for you to customize and avoid errors.
Instantiate a Calendar object. Details about this in section 4.1.
opt Set the weekNumbers property to false if you don’t want the calendar to display week numbers.
opt Set the showsTime property to true if you want the calendar to also provide a time selector.
opt Set the time24 property to false if you want the time selector to be in 12-hour format. Default is 24-hour format. This property only has effect if you also set showsTime to true.
opt Set the range of years available for selection (see section 4.3.14). The default range is [1970..2050].
opt Set the getDateStatus property. You should pass here a function that receives a JavaScript Date object and returns true if the given date should be disabled, false otherwise (details in section IGNORE).
opt Set a date format. Your handler function, passed to the calendar constructor, will be called when a date is selected with a reference to the calendar and a date string in this format.
Create the HTML elements related to the calendar. This step actually puts the calendar in your HTML page. You simply call Calendar.create(). You can give an optional parameter if you want to create a flat calendar (details in section 4.3.1).
opt Initialize the calendar to a certain date, from the input field, or a default date that is application specific.
Show the javascript calendar (details in section 4.3.8).
Two things happen when you create a Calendar. First, you create the JavaScript object. Second, the HTML elements that actually let you see and manipulate the Calendar are created.
When we instantiate the Calendar, we in effect create the JavaScript object. We configure properties and create the HTML elements that will provide the end-user with a visible, interactive UI. The function Calendar.create described in section 4.3.1, is responsible for creation of the HTML element, and with it you can create pop up or flat Calendars.
Some properties will not work unless they are set before creating the HTML elements. One example is weekNumbers. WeekNumbers is true by default. If you do not want the Calendar to display the week numbers, you must set this to false. If you set the value to false after calling the calendar.create file, however, it will not work. Calling the calendar.create creates the HTML elements (tables, cells, etc.) and it will create the table based on your property values. So, if weekNumbers falls after the calendar.create is called, your calendar will still display the table elements required for the week number because it didn’t see the information to leave it out (a value of false ahead of time. For this reason the order of the steps above is important.
The order of actions also matters when you want to show the calendar. The "create" function does create the HTML elements, but they are initially hidden (have the style "display: none") unless the calendar is a flat calendar which should always be visible in the page. Obviously, the Calendar.show function should be called after calling Calendar.create.
Suppose the end-user has popped up a calendar and selects a date. The calendar then closes. What is really happening?
The Zapatec.Calendar.setup function caches the JavaScript object. It does this by checking the global variable window.calendar and if it is not null it assumes it is the created Calendar object. When the end-user closes the calendar, our code will only call "hide" on it, therefore keeping the JavaScript object and the HTML elements in place.
Caching the calendar improves speed, specifically when you have several calendars on one pages, and when the user opens and closes the same calendar several times.
The calendar uses callback functions as a way to tell that a date is selected; it has to update an input field or go to a certain URL when a date is clicked in flat mode.The Calendar object has no awareness of an input field and it does not know where to redirect the browser when a date is clicked in the flat calendar.
The calendar object calls the callback when a particular event is triggered, and your code is responsible for handling it from there. For a general-purpose library, this is the best model for making a truly reusable widget.
The calendar supports the following user callbacks:
onSelect — this function gets called when the end-user changes the date in the calendar. Documented in section IGNORE.
onClose — this function gets called when the calendar should close. It is your responsibility to close the calendar. Details in section IGNORE.
getDateStatus — Prior to displaying a specific month this function gets called for any day in that month. It is called with a JavaScript Date object as a parameter. This function should return true for dates that should be disabled, false for an ordinary date where no action should be taken. It can also return a string, in which case the returned value will be appended to the element’s CSS class. This provides a powerful way to make some dates "special", i.e. highlight them differently. Details in section IGNORE.
var calendar = Calendar(firstDayOfWeek, date, onSelect, onClose);
Parameters are as follows:
firstDayOfWeek — specifies which day is to be displayed as the first day of week. Possible values are 0 to 6; 0 means Sunday, 1 means Monday, ..., 6 means Saturday.
date — a JavaScript Date object or null. If null is passed then the calendar will default to today date. Otherwise it will initialize to the given date.
onSelect — your callback for the "onChange" event. See above.
onClose — your callback for the "onClose" event. See above.
Assuming you have a input field with an id "myInputField", here is a typical implementation of this function:
function onSelect(calendar, date) { var input_field = document.getElementById("myInputField"); input_field.value = date; };
date is displayed in the format selected with calendar.setDateFormat (see section 4.3.5). This code simply updates the input field. If you want the calendar to be in single-click mode then you should also close the calendar after you updated the input field. Here’s the updated version:
function onSelect(calendar, date) { var input_field = document.getElementById("myInputField"); input_field.value = date; if (calendar.dateClicked) { calendar.callCloseHandler(); // this calls "onClose" (see above) } };
Note that this function is called when the user clicks inside the calendar. We check the member variable dateClicked and only hide the calendar if it’s true. If this variable is false it means that no date was actually selected, but the user only clicked to change the month/year using the navigation buttons or the menus. We do not want to hide the calendar in that case.
This event is triggered when the calendar should close. It should hide or destroy the calendar object—the calendar itself just triggers the event, but it won’t close itself.
A typical implementation of this function is the following:
function onClose(calendar) { calendar.hide(); // or calendar.destroy(); };
After creating the Calendar object you can access the following properties:
date — a JavaScript Date object that always reflects the date shown in the calendar, even if the calendar is hidden.
isPopup — when true the current Calendar object is a popup calendar. If false we have a flat calendar. This variable is set from Calendar.create and has no meaning before this function is called.
dateClicked — particularly useful in the onSelect handler, this variable tells us if a date was really clicked. That’s because the onSelect handler is called even if the end-user only changed the month/year but did not select a date. We don’t want to close the calendar in that case.
weekNumbers — when true (default) then the calendar displays week numbers. If you don’t want week numbers you have to set this variable to false before calling Calendar.create.
showsTime – if you set this to true (it is false by default) then the calendar will also include a time selector.
time24 – if you set this to false then the time selector will be in 12-hour format. It is in 24-hour format by default.
firstDayOfWeek — specifies the first day of week (0 to 6, pass 0 for Sunday, 1 for Monday, ..., 6 for Saturday). This variable is set in the constructor, but you still have a chance to modify it before calling Calendar.create.
This function creates the different HTML elements that are needed to display the calendar. You should call it after setting the calendar properties.
calendar.create(); // creates a popup calendar // -- or -- calendar.create(document.getElementById(parent_id)); // makes a flat calendar
The function creates a popup or a flat calendar. If the "parent" argument is present (it should be a reference—not ID—to an HTML element) then a flat calendar is created and it is inserted in the given element.
At any moment, given a reference to a calendar object, we can check the boolean member variable isPopup to see if it’s a popup or a flat calendar:
if (calendar.isPopup) { // this is a popup calendar } else { // this is a flat calendar }
This function calls the first user callback (the onSelect handler) with the required parameters.
This function calls the second user callback (the onClose handler). It is useful when you want to have a "single-click" calendar—just call this in your onSelect handler, if a date was clicked.
Call this function to hide the calendar. The calendar object and HTML elements will not be destroyed, thus you can later call one of the show functions on the same element.
This function configures the format in which the calendar reports the date to your "onSelect" handler. Call it like this:
calendar.setDateFormat("%y/%m/%d");
It receives only one parameter, the required format. In addition to special characters, you can insert spaces, commas, tabs and other constant characters. The special characters are the following:
%a | abbreviated weekday name |
%A | full weekday name |
%b | abbreviated month name |
%B | full month name |
%C | century number |
%d | the day of the month ( 00 .. 31 ) |
%e | the day of the month ( 0 .. 31 ) |
%H | hour ( 00 .. 23 ) |
%I | hour ( 01 .. 12 ) |
%j | day of the year ( 000 .. 366 ) |
%k | hour ( 0 .. 23 ) |
%l | hour ( 1 .. 12 ) |
%m | month ( 01 .. 12 ) |
%M | minute ( 00 .. 59 ) |
%n | a newline character |
%p | "PM" or "AM" |
%P | "pm" or "am" |
%S | second ( 00 .. 59 ) |
%s | number of seconds since Epoch (since Jan 01 1970 00:00:00 UTC) |
%t | a tab character |
%U, %W, %V | the week number |
%u | the day of the week ( 1 .. 7, 1 = MON ) |
%w | the day of the week ( 0 .. 6, 0 = SUN ) |
%y | year without the century ( 00 .. 99 ) |
%Y | year including the century ( ex. 1979 ) |
%% | a literal % character |
All three specifiers %U, %W, %V currently implement the same week number algorithm, as defined by ISO 8601: "Week 01 is the week that has the Thursday in the current year, which is equivalent to the week that contains the fourth day of January. Weeks start on Monday."
uses the same format as Calendar.setDateFormat, but refers to the format of the date displayed in the "status bar" when the mouse is over some date.
Sets the callback for disabling and customizing specific dates and times. You need to write the callback that will return a boolean or a string. If the return value is (true the date is disabled and the user cannot click on it. If it is false) it is available for clicking.
If the returned value is a string then the given date will gain an additional CSS class, namely the returned value. You can use this to highlight some dates in some way. Note that you are responsible for defining the CSS class that you return. If you return string that contains "disabled" the date will be disabled, just as if you returned true. This provides you with custom ways to display disabled dates.
Here is a simple scenario that shows what you can do with this function. The following should be present in some of your styles, or in the document head in a STYLE tag (but put it after the place where the calendar styles were loaded):
.special { background-color: #000; color: #fff; }
And you would use the following code before calling Calendar.create():
// this table holds your "special" days, so that we can automatize // things a bit: var SPECIAL_DAYS = { 0 : [ 13, 24 ], // "special days" in January 2 : [ 1, 6, 8, 12, 18 ], // "special days" in March 8 : [ 21, 11 ], // "special days" in September 11 : [ 25, 28 ] // "special days" in December }; // this function returns true if the passed date is special function dateIsSpecial(year, month, day) { var m = SPECIAL_DAYS[month]; if (!m) return false; for (var i in m) if (m[i] == day) return true; return false; } // this is the actual date status handler. Note that it receives the // date object as well as separate values of year, month and date, for // your confort. function dateStatusHandler(date, y, m, d) { if (dateIsSpecial(y, m, d)) return "special"; else return false; // return true above if you want to disable other dates } // configure it to the calendar calendar.setDateStatusHandler(dateStatusHandler);
The above code adds the "special" class name to some dates that are defined in the SPECIAL_DAYS table. Other dates will simply be displayed as default, enabled.
You can disable specific times as well as dates using the setDateStatusHandler.
function timeOutOfRange(date, year, month, day, hours, minutes) { if (date.getDay() == 0) { //No Sunday return true; } if (typeof(hours) != "undefined") { if (date.getDay() == 6) { //only allow 11AM to 5PM on Saturday if (hours < 17 && hours >= 11) { return false; } else { return true; } } //on saturdays allow if (date.getDay() == 5) { //only allow 8AM to 9:45PM on Friday if (hours > 21 || hours < 8) { return true; //not within the hours } if (hours != 21) { return false; //within the hours } //hours = 21 if (minutes <= 45) { return false; } else { return true; } } } return false; } Zapatec.Calendar.setup({ inputField : "sel9", // id of the input field singleClick : false, // require two clicks to submit ifFormat : '%a, %b %e, %Y [%H:%M]', // format of the input field ampm : false, showsTime : true, // show time as well as date button : "button9", // trigger button dateStatusFunc : timeOutOfRange, floating : true });
The calendar calls the callback timeOutOfRange on two events, when the date changes, and when the time changes. To see which check it is, see if the hours variable is defined. In the above example the user is limited to 11AM - 5PM on Saturdays and 8AM to 9:45 PM on Friday.
Sometimes the user could end up in a time that’s not permited. This can happen when the calendar first start up. For instance let’s say the user clicks on the calendar on Saturday at 6PM. This can also happen when the user switches days and the time was allowed on the old day but not on the new one. For instance the user scrolls the time to 8PM on a Monday and changes the day to Saturday.
In both cases the calendar automatically scrolls to the first permissable time in 5 minute increment. So if the current time is 9:42PM on a Saturday and you click on the above calendar it will set the time to 11:02 AM.
Call this function do show the calendar. It basically sets the CSS "display" property to "block". It doesn’t modify the calendar position.
This function only makes sense when the javascript calendar is in popup mode.
Call this to show the calendar at a certain (x, y) position.
calendar.showAt(x, y);
The parameters are absolute coordinates relative to the top left corner of the page, thus they are page coordinates not screen coordinates.
After setting the given coordinates it calls Calendar.show. This function only makes sense when the calendar is in popup mode.
This function is useful if you want to display the calendar near some element.
calendar.showAtElement(element, align);
where element is a reference to your element (for instance it can be the input field that displays the date) and align is an optional parameter, of type string, containing one or two characters. For instance, if you pass "Br" as align, the calendar will appear below the element and with its right margin continuing the element’s right margin.
Align may contain one or two characters. The first character dictates the vertical alignment relative to the element, and the second character dictates the horizontal alignment. If the second character is missing, it will be assumed "l" (the left margin of the calendar will be at the same horizontal position as the left margin of the element).
The characters given for the align parameters are case sensitive. This function only makes sense when the calendar is in popup mode. After computing the position, it uses Calendar.showAt to display the calendar as specified.
The first character in "align" can take one of the following values:
T — completely above the reference element (bottom margin of the calendar aligned to the top margin of the element).
t — above the element but may overlap it (bottom margin of the calendar aligned to the bottom margin of the element).
c — the calendar displays vertically centered to the reference element. It might overlap it (that depends on the horizontal alignment).
b — below the element but may overlap it (top margin of the calendar aligned to the top margin of the element).
B — completely below the element (top margin of the calendar aligned to the bottom margin of the element).
The second character in "align" can take one of the following values:
L — completely to the left of the reference element (right margin of the calendar aligned to the left margin of the element).
l — to the left of the element but may overlap it (left margin of the calendar aligned to the left margin of the element).
c — horizontally centered to the element. Might overlap it, depending on the vertical alignment.
r — to the right of the element but may overlap it (right margin of the calendar aligned to the right margin of the element).
R — completely to the right of the element (left margin of the calendar aligned to the right margin of the element).
If the "align" parameter is not set the calendar defaults to "Br".
Sets the Calendar to the date passed in the parameter. This parameter needs to be a JavaScript Date object. If the calendar is visible the new date is displayed immediately.
calendar.setDate(new Date()); // go today
Changes the first day of week. The parameter has to be a numeric value ranging from 0 to 6. Pass 0 for Sunday, 1 for Monday, ..., 6 for Saturday.
calendar.setFirstDayOfWeek(5); // start weeks on Friday
Use this function to parse a date given as string and to move the calendar to that date.
The algorithm tries to parse the date according to the format that was previously set with Calendar.setDateFormat; if that fails, it still tries to get a valid date.
calendar.parseDate("2003/07/06");
Sets the range of years that are allowed in the calendar.
calendar.setRange(1970, 2050);
The <strong> DHTML calendar </strong> code was intentionally embedded in an object to make it have as few as possible side effects. There are some side effects. This following is a list of the side effects;
The global variable window.calendar is initially set to null. This variable is used by the calendar code, especially when doing drag & drop for moving the calendar.
The JavaScript Date object is modified. We add some properties and functions that are useful to our calendar. It made more sense to add them directly to the Date object than to the calendar itself.
Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
Date.SECOND = 1000 /* milliseconds */;
Date.MINUTE = 60 * Date.SECOND;
Date.HOUR = 60 * Date.MINUTE;
Date.DAY = 24 * Date.HOUR;
Date.WEEK = 7 * Date.DAY;
Date.prototype.getMonthDays(month) — returns the number of days of the given month, or of the current date object if no month was given.
Date.prototype.getWeekNumber() — returns the week number of the date in the current object.
Date.prototype.equalsTo(other_date) — compare the current date object with other_date and returns true if the dates are equal. It ignores time.
Date.prototype.print(format) — returns a string with the current date object represented in the given format. It implements the format specified in section 4.3.5.
The Zapatec DHTML Calendar is a commercial version of the open source calendar written by Mihai Bazon.