F.A.Q about FlatCalendarXP
License FAQ FlatCalendarXP FAQ PopCalendarXP FAQ

Here are all kinds of tips and tricks that will help you greatly in mastering and enjoying FlatCalendarXP.

How to add a FlatCalendar to my web page?

Simply insert the calendar tag to anywhere in your webpage, like a common HTML tag(NN4 needs more care). It'll then turn into a beautiful calendar in your browser. Magic?!

How to use the themes?

Create an empty directory, put the engine files in. Then go inside the themes directory and pick up a theme you like, copy all files of the theme to the directory just created. Finally, if you want to add agendas, you may start with the agenda.js in the HelloWorld demo, using it as a template to create your own.

It's quite straightforward, please check out the Tutorials for more details and samples.

How to upgrade from the old version?

If you are upgrading from within the same major version, e.g. from 6.0 to 6.1, all you need is to copy the new engine files to overwrite the old ones. That's all, there is no need to change your production page or any theme options. It's quite easy and painless.

If you want to upgrade across major versions, e.g. from 5.2 to 6.0, then in addition to replacing the engine files you may also need to migrate the old theme options to the new theme if you want to keep your old theme working. Most of the time you don't need to change anything in your web page unless it is explicitly required by the new version in its release notes.

How to localize the calendar so that it shows in languages other than english?

FlatCalendarXP comes with great themes optimized for English environment. But it's quite simple to localize them since all text strings are stored externally in either the theme files or the agenda file. All you need is to open them with a text editor like notepad and replace the English strings with your own language strings, then modify the css file to use corresponding font families.

If your page was generated dynamically by ASP server and you saw rectangles instead of normal fonts in Netscape 4.x, please set the http charset header to "" by using Response.Charset="" in your asp page. This header has to be set before anything else.

If your page aims to support multiple languages(i18n), please follow the instructions in the i18n tutorials to create a simple i18n framework.

How can I retrieve daily agendas from the backend database?

Depending on the cgi service you are using the solution might be a little different. The basic idea is to make your cgi service produce the agenda.js dynamically, e.g. from a JSP or ASP. We had it detailed in the "Setting up agendas & holidays" tutorial.

How to set the initial month?

When first loaded, the calendar will show up with the month set by the default-month parameter in the name & id properties of the calendar tag. For example, you may set the name&id of the calendar tag to "[2002,10]:normal:agenda.js" and the calendar will then start on Oct 2002. Or you may choose "[gToday[0],gToday[1]+1]:normal:agenda.js" so that it will always show the next month at the beginning.

How to change colors, fonts and other options?

There are 2 files involved in a theme that control the look of the calendar - theme-name.js & theme-name.css. They are all self-documented and you may use any text editor to fulfill the change. Please refer to "Working with themes" tutorial for details.

How to align the date number within the calendar cell?

Go to the theme-name.css file and find the .CalCell class, change the value of ruletext-align to left, center or right. To align it vertically, you'll have to turn it into a table cell first by adding a CSS2 display rule to both .CalCell and .CellAnchor and specify a vertical-align rule afterwards:

.CalCell {...; text-align:center; display:table;}
.CellAnchor {...; display:table-cell; vertical-align:middle;}

How to perform a specific action when a date is clicked?

For example, you want to perform the alert() function.

  • If you want to perform it just before the date gets selected
    You need to put it into the fOnChange() callback plugin in the plugins.js file, as following:
    function fOnChange(y,m,d) {
      if (d>0) alert([y,m,d]+' will be selected.');
      return false; // return true to cancel the change.
    }
  • If you want to perform it just after the date gets selected
    You need to put it into the fAfterSelected() callback plugin in the plugins.js file, as following:
    function fAfterSelected(y,m,d) {
      alert([y,m,d]+' has been selected.');
    }
    Or, you may also choose to put it into the gsAction option in the theme-name.js file, as following:
    var gsAction="alert([y,m,d]+' has been selected.');";

Note you may also use pre-defined popup() function (in plugins.js) to open up any URL in the current window or a new window. e.g.

function fAfterSelected(y,m,d) {
  popup('http://www.calendarxp.net', '_top');
}

Or even startup your email client by using "mailto". e.g.

function fAfterSelected(y,m,d) {
  popup('mailto:who@email.address?subject=hello there', '_blank');
}

How can I change the style of the outside calendar border?

Simply change the #outerTable CSS style in the theme-name.css file. Since version 7.0 the style of iframe calendar tag no longer contains any border style properties.

Note: NN4 doesn't support outside border, it can only have the table border set by gsOuterTable in theme-name.js file.

The calendar doesn't show up in full or too large at first, but recovers after month switching. What's wrong?

The calendar panel size is set initially by the width and height properties of <iframe> tag. If these 2 values are not matching the actual size, the calendar engine will try to detect the real size after a short delay specified by giResizeDelay option. The incorrect initial size problem will happen when the browser is not rendering DHTML faster enough so that the document is not ready upon the size checking time.

If this is happening when using the calendar within tabstrip/multipage controls of asp.net, you may fix it by either setting the AutoPostBack property of the tabstrip control to true, or appending an onclick="if(gfFlat)gfFlat.fResize()" handler for the tabstrip to resize the calendar. e.g.

<ie:TabStrip runat="server" TargetID="mpage" onclick="if(gfFlat)gfFlat.fResize()" ...>
...

Of course you should name your calendar context to gfFlat for the latter solution.

If this is happening in other situations, try increasing giResizeDelay a bit. But don't set it too large because it will bring in visible delay. Another solution is to adjust the width and height of the calendar tag to be the correct initial sizes.

After configuring the theme, why all the calendar cells appear empty in Netscape 4.x?

Make sure the giCellWidth is set larger enough. Try increasing it 10 pixels a time until you see everything back normal. It's a NN4 bug triggered when extra stuff stretching the top or bottom section too much wider than the total width of date cells. Making the top and/or bottom sections shorter could be another solution.

Not all my agenda properties are working, why?

Please check the gAgendaMask option in your theme settings. Make sure the mask value is properly set. The agenda property will be masked out if the relevant bit value is not set to -1.

How to disable days, like weekends?

Quite simple, all you need is to put 2 lines of code to the top of fHoliday() function in agenda.js file so that it looks like:

function fHoliday(y,m,d) {
  var dayOfWeek=new Date(y,m-1,d).getDay();
  if (dayOfWeek==0||dayOfWeek==6) return ["Weekend is not selectable!",null];
...

It creates a "null" agenda template, null value in the action property, for the weekends so that they can't be selected. You may also disable other dates via the same way. A tip is to have other properties of agenda defined in the template in order to make the disabled dates in different colors, backgrounds or even images.

If you want more control on modifying the range dynamically from your page, you may follow the steps below:

  1. define your own function in your page that returns true if pass-in date is valid. e.g. you only want the user to select Jun 20, 24 and 27 of year 2004
    <body>
    <script>
    function myValidDate(y,m,d) {
      return (y==2004&&m==6&&(d==20||d==24||d==27));
    }
    </script>
    ...

  2. append the following line of code to agenda.js.
    fValidRange=gContainer.myValidRange;
Moreover, since the myValidDate function is in your page, you can even use ASP or JSP to generate it so as to define the available dates according to your server status.

I have many duplicate events occuring regularly, must I generate an agenda for each of them?

No, you don't need. Duplicate events can be treated as holidays. Instead of repeating the fAddEvent() calls, using fHoliday() to return a single agenda template is much more faster and efficient. The above FAQ for disabling weekends is a good example. Also please check the setup agenda tutorial for more detailed info.

How can I access the DOM objects of the webpage that contains the calendar from within the plugins?

The build-in gContainer reference, which points to the enclosing window object, is made for such purpose. Suppose you have a form named "testForm" with a <input> tag named "dateInput" laying in the same page as the calendar. And you want to put the selected date from the calendar into the "dateInput" field with the "y/m/d" date format. To achieve such purpose, you should use the following code in plugins.js file:

function fAfterSelected(y,m,d) {
  gContainer.document.testForm.dateInput.value=y+"/"+m+"/"+d;
}
Another example is that if you opened a new window that contains a FlatCalendar and wanted to return the selected date into a field in the original page.
function fAfterSelected(y,m,d) {
  gContainer.opener.document.testForm.dateInput.value=y+"/"+m+"/"+d;
}

How can I submit the form right after a date is picked?

To submit a static form named as "testForm", you may use:

function fAfterSelected(y,m,d) {
  gContainer.document.testForm.submit();
}

How can I reset the system defined "today" to a date specified in the server-end?

The calendar engine uses 2 system objects gd and gToday to control the date of today. You may override them in the plugins.js file with any date you like, you can even rename it to plugins.asp to take advantage of ASP generated date.

1st, you need to prepend the following lines of code to the top of plugins.js file.

gd=new Date(2003,3-1,11); // You may use any date you want.
gToday=[gd.getFullYear(),gd.getMonth()+1,gd.getDate()];
gCurMonth=eval(gTheme[0]); // re-init the gCurMonth in case it using gToday.

2nd, you need to search through the theme-name.js file, e.g. normal.js, for any references to gToday, and copy them to the plugins.js file and put them behind the above gCurMonth definition so that they can be re-initialized. e.g.

gd=new Date(2003,3-1,11); // You may use any date you want.
gToday=[gd.getFullYear(),gd.getMonth()+1,gd.getDate()];
gCurMonth=eval(gTheme[0]); // re-init the gCurMonth in case it using gToday.

gsBottom="..."; // re-init gsBottom if it contains reference to gToday. (optional)
gdSelect=gToday; // re-init gdSelect if it references to gToday. (optional)

Finally, you may want to rename the plugins file to plugins.asp and use a date generated from ASP variables to replace the static one:

gd=new Date(<%= year %>,<%= month %>-1,<%= day %>); // year, month, day are server-end variables
...

Remember to modify the name & id of the calendar iframe tag accordingly to reflect the above renaming - e.g. "gToday:normal:agenda.js::plugins.asp". You can also use path in the name & id, more details can be found in the HelloWorld tutorial.

Also note that all options in the theme-name.js can be reset dynamically in this manner.

How come the widths of calendar columns look different in size after I reconfigured the theme?

Please check whether the upper Navigation Section or lower Today Section is wider than the total width of date cells. The calendar panel will automatically get stretched if the outter table width becomes larger, and the streched part might not be evenly distributed among all columns.

You may either enlarge the giCellWidth or cut down the stuff in top/bottom sections to fix this problem.

How to set the date range to begin from today?

Simply set the gBegin option to gToday in theme-name.js file, as following:

...
var gBegin=gToday; // calendar date range begin from [Year,Month,Date]
var gEnd=[2030,12,31];
...

Why IE6 began to show strange white space along the right and bottom sides after I added a DOCTYPE! statement?

It's a bug of IE6 when setting the border style of <iframe> tag in standard mode. To workaround, you may remove the border style from the <iframe> tag and put it into the #outerTable class in theme-name.css file instead. All themes in version 7.0 and above have already been using this solution to create calendar borders.

#outerTable {border:2px ridge #808080;}

I would like to use images instead of the text numbers for the date numbers. Would this be easy to do?

Yes, easy. There is an option in the theme-name.js file called gsDays which will be evaluated upon each calendar cell. Simply name your image files as day1.gif, day2.gif, ... and create a function, named fGetDateCell(), in the plugins.js as following:

function fGetDateCell(dateStr) {
  var d=dateStr.split(",")[2];
  return "<IMG src='/images/day"+d+".gif' height=... width=... >";
}

and set the gsDays to:

var gsDays="fGetDateCell(sCellDate);";

Note the sCellDate above is an internal contextual variable that stores the current cell date in format "y,m,d".

How can I make Monday/Sunday the first day of week?

Easy. There is an option in the theme-name.js file called giFirstDOW. Set it to 0,1-6 will make Sunday, Monday-Saturday the first day of week.

How can I have a default tooltip message for every normal date?

Easy. Just need to add 1 line of code in fHoliday() to return a default agenda instead of null value for every normal day. e.g.

function fHoliday(y,m,d) {
...
if (r==null) return ["A message for everyday", gsAction];
return r; // if r is null, the engine will just render it as a normal day.
}

How can I organize theme files in a different directory other than the default engine directory?

In the calendar tag, you need to change the value of name & id properties to include the absolute/relative path to the theme directory. e.g.

<iframe name="gToday:/theme1/normal:agenda.js:gfFlat:./plugins.js" id="gToday:/theme1/normal:agenda.js:gfFlat:./plugins.js" src="/engine/iflateng.htm" ... > </iframe>

The above tag will load the normal theme from absolute web path /theme1/, while loading agenda.js and plugins.js from /engine/. This may be confusing because paths in the name & id are relative to the src, not the containing page. Therefore we always recommend you put all calendar related files together within the same directory with the iflateng.htm and use path in src ONLY.

How come the calendar stops working in NN4 once I add in the Thawte certificate seal?

It's a bug of the Thawte seal script and can be easily fixed by appending a line of script right behind it. i.e.

<script src="https://siteseal.thawte.com/cgi/server/thawte_seal_generator.exe"></script>
<script>if (document.layers) document.releaseEvents(Event.MOUSEDOWN);</script>

The 1st <script> is the Thawte seal script, and the 2nd one is the fix.

Where can I find a working example for the calendar working with asp.net tabstrip/multipage controls?

Please try the following one. Note the form id must be set to the same as the one passed in to gfPop.fPopCalendar(), otherwise the calendar will not be able to find the date input field.

TabStripDemo.aspx

<%@ Register TagPrefix="ie" Namespace="Microsoft.Web.UI.WebControls" Assembly="Microsoft.Web.UI.WebControls" %>
<html>
<body>
<form id="demoform" runat="server">

<ie:TabStrip runat="server" TargetID="mpage" AutoPostBack="true"
TabDefaultStyle="background-color:#000000;font-family:verdana;font-weight:bold;font-size:8pt;color:#ffffff;width:100px;height:21px;text-align:center"
TabHoverStyle="background-color:#777777"
TabSelectedStyle="background-color:#ffffff;color:#000000">
<ie:Tab Text="PopCalendar" />
<ie:TabSeparator/>
<ie:Tab Text="FlatCalendar" />
<ie:TabSeparator/>
<ie:Tab Text="About"/>
</ie:TabStrip>

<ie:MultiPage id="mpage" SelectedIndex="1" runat="server">
<ie:PageView>
&nbsp;Date Field: <input name="dc" value="" size="11"><a href="javascript:void(0)" onclick="gfPop.fPopCalendar(document.demoform.dc);return false;" HIDEFOCUS><img class="PopcalTrigger" align="absbottom" src="calbtn.gif" width="34" height="22" border="0" alt=""></a>
</ie:PageView>

<ie:PageView>
<iframe name="gToday:normal:agenda.js:gfFlat" id="gToday:normal:agenda.js:gfFlat" src="iflateng.htm" scrolling="no" frameborder="0">
</iframe>
</ie:PageView>

<ie:PageView>
Copyright (C)2003-2007 Idemfactor Solutions, Inc.
</ie:PageView>
</ie:MultiPage>
</form>

<iframe name="gToday:supermini:agenda.js" id="gToday:supermini:agenda.js" src="ipopeng.htm" scrolling="no" frameborder="0" style="visibility:visible; z-index:999; position:absolute; left:-500px; top:0px;">
</iframe>
</body>
</html>

Put the above TabStripDemo.aspx into a virtual directory on your IIS with the supermini theme for PopCalendarXP and normal theme for FlatCalendarXP.

Note: If you don't want to set the AutoPostBack of tabstrip control, you should append the following onclick code to workaround a bug in the tab/multipage control. (To workaround a bug that messes the calendar in IE and only in IE.)

<ie:TabStrip runat="server" TargetID="mpage" onclick="if(gfFlat)gfFlat.fResize()" ...>

How can I use the functions defined inside the calendar engine?

You can reference anything inside the calendar engine by prefixing it with the engine's context name (more on this in the Hello World tutorial). e.g.

<ContextName>.fGetWeekNo(y,m,d)

NOTE: the context name (e.g. gfPop or gfFlat) will be only available after the engine is fully loaded. You may want to check it before calling by adding "if(self.<ContextName>)" to the above statement, otherwise you may get an "object not found" error upon an inmature loading.

How to pass parameters to the scripts that generate the agenda file?

If you want to create a calendar that belongs to a user, you may need to pass the user id to the scripts that generate the agenda file so that the calendar only shows up the events related to that specific user.

CalendarXP has already taken it into account and all you need is set the url in the name & id of the calendar tag, as following:

<iframe name="gToday:normal:agenda.jsp?userId=<%=obj.getUserID()%>" id="gToday:normal:agenda.jsp?userId=<%=obj.getUserID()%>"
...></iframe>

The above example is using JSP to generate the agenda file, of course you may use Perl, ASP, PHP or whatever else instead.

Note: you must escape any non-alphabetical chars in the URL, especially the colon char. Running the parameter string through an URL encoding filter and using the transformed string in the name & id of the calendar tag is always a safe way to go.

Can I use the week number to launch an action, like the day number does?

Yes, any actions can be associated with the week numbers, e.g. popup windows, change url or even update calendar events. There is a plugin in the plugins.js file:

function fOnWeekNo(year, weekNo) {
...put your code here...
}

Now you may do whatever you like in the fOnWeekNo() function. It'll be called every time when you click on the week numbers of the calendar.

How to change the size of the calendar?

The calendar size is determined by the calendar cell size and the padding and spacing size of the panel table. They can be adjusted easily by editing the following options in the theme-name.js file: giCellWidth, giCellHeight, gsInnerTable, gsOuterTable.

The calendar panel looks like being squeezed in Konqueror sometimes. What's wrong?

It's because sometimes the Konqueror has difficulty in expanding the calendar panel to the correct size. Currently it can be worked around by giving the iframe tag a larger-than-usual width value since it appears to have no problem in shrinking automatically. e.g. <iframe width=600 ...>

Why the prev/next month links only respond to the first click in Konqueror?

It's a bug of certain Konqueror version. This bug exists outside the calendar engine and you may test it with any simply link on a blank page - the onclick event will not be fired after your first click unless you move the mouse out of the link and back in again. Currently it can be worked around by using onmousedown event handler instead of onclick. (Modify gsNavPrev/gsNavNext options accordingly)

It looks like this bug only occurs on anchor links, it's not affecting buttons.

How to prevent the calendar from being switched to prev/next months when a day of them is selected?

You need to put 4 lines of code into the fOnChange() plugin function. e.g.

function fOnChange(y,m,d,e) {
...

if (m!=gCurMonth[1]&&[y,m,d]+''!=gToday+'') { // cancel the auto month switching
  fRepaint();
  return true;
}

return false; // return true to cancel the change.
}

So afterwards, clicking the dimmed days that belongs to prev/next months will no longer automatically switch the calendar.

How to select multiple dates in one calendar?

There is a new call-back function in the plugins.js called fIsSelected(y,m,d), which determines whether to mark the passed-in date as a selected date. If this function returns true, the specific date passed in will be marked as selected using theme options giMarkSelected, gcFGSelected, gcBGSelected and guSelectedBGImg. Please refer to the Plugins SDK tutorial for details.

To select multiple dates, you just need to create an array in the plugins.js to store either the selected dates or the selected date range. The array takes values via fOnChange() or fAfterSelected(), then it's checked from within the fIsSelected() function. You may find a good example in the MultiPicker demo in FlatCalendarXP or the WeekPicker demo in PopCalendarXP.

How to create a holiday for Easter Day?

Please have a look at the setup agenda and holidays tutorial, it's detailed there.

Why the fOnChange() and fAfterSelected() plugin functions not working?

Please check the fOnDrag() plugin call and make sure it returns false. If it returns true, the "set date" action will be cancelled and hence the fOnChange() and fAfterSelected() will not be called.

Why the month navigators created in my new theme don't do auto-traverse?

You just need to give your month navigator tags an id of "navPrev" or "navNext" and the calendar engine will then find them and start auto-traverse when you holding down the mouse button on them. Take a look at the existing themes for a sample.

How to disable the dates-out-of-range alert message boxes?

In the theme-name.js file you may find an option called gsOutOfRange, setting it to an empty string "" will disable such alerts.

How to skip the focus on the calendar when TAB-keying through the form fields?

There is a HTML 4.0 tag attribute called tabindex which can be used to determined the sequence of focusing when pressing TAB key on a page. In IE you may set the tabindex of the <iframe> tag to -1 to prevent the calendar from getting focused during the process.

How to set the calendar to fill the width of the page?

Since verion 9.0.195, when the giCellWidth option is set to -1, the calendar engine will smartly pick up a value at its best effort to make sure the total width of the entire calendar fit in with the direct parent tag (the one enclosing the calendar tag). However, the minimum width of the calendar is still guarded by the width property of the <iframe> calendar tag, which means the total width will never be less than it.

So, to implement a calendar that has a minimum width of 50 and fits in with the page width otherwise, you just need the following code:

<div style="width:100%">
<iframe width="50" ... ></iframe>
</div>

Of course, you may use table tag instead of div tag to enclose the calendar.

How come in Safari the calendar events text rides on top of day number instead of underneath?

It's a CSS bug of Safari, and doesn't exist in other browsers. It's related to the way how Safari handles the CSS rule of "display:table-row".

To work around, you'll have to wrap another <div style='display:table-row'> tag to the html contents of the event if running inside Safari. e.g.

fAddEvent(2004,3,20,"test", ... ,(SA?"<div style='display:table-row'>":"")+"<div class='MsgBoard'>test</div>"+(SA?"</div>":""));

NOTE: You may ask why wrapping it conditionally(only when Safari is detected)? The answer is IE6 doesn't like such wrapping for some reason and will choke on it.

How to set the date range to start from today and end 7 days later?

Check for gBegin and gEnd options in the theme-name.js file and replace them with the following code:

var gBegin=gToday;
var _dEnd=new Date(gToday[0],gToday[1]-1,gToday[2]+7);
var gEnd=[_dEnd.getFullYear(),_dEnd.getMonth()+1,_dEnd.getDate()];

NOTE: The month number used in the javascript Date object is ranged from 0 to 11.

How to display all events of the selected date in a new page?

Taking the MockupSibling as an example:

1st, in plugins_s.js set the fAfterSelect() as following:

function fAfterSelect(y,m,d,e){
  popup("showOneDay.htm","_blank");
}

2nd, create a blank html file named as "showOneDay.htm".

3rd, put the following into the <body> of the newly created html file:

<script>
var sd=opener.gfFlat_s.gdSelect;
var htm="Selected Date is: "+sd+"<BR>";
htm+="Events:<BR>";

var evt=opener.gfFlat_s.fGetEvent(sd[0],sd[1],sd[2]);
htm+=evt==null?"No events.":evt[6];

document.write(htm);
document.close();
</script>

That's all. Now click on the small calendar for a test. Of course you may give it a much better looking.

Note: This only works if you popup a new browser window to show the events. If you want to replace the contents of the current window, then replace the above scripts with the following:

<script>
var sd=opener.gfFlat_s.gdSelect;
var htm="Selected Date is: "+sd+"<BR>";
htm+="Events:<BR>";

var evt=opener.gfFlat_s.fGetEvent(sd[0],sd[1],sd[2]);
htm+=evt==null?"No events.":evt[6];

opener.document.write(htm);
opener.document.close();
opener.focus();
self.close();
</script>

How to set the disabled or out-of-range dates in a special style other than line-through?

To get rid of the line-through effect on disabled or out-of-range dates, you just need to append the following line to the plugins.js file:

_lineThru=false;

By default the engine only provides 2 theme options to config the tooltip and background image of the out-of-range dates - gsOutOfRange & guOutOfRange. If you want more varied look-and-feel, you just have to code a bit more with the help of agenda.js - for example adding the following line of code in fHoliday will give the out-of-range dates a red font color and a green boxed background:

function fHoliday(y,m,d) {
  if (!fValidRange(y,m,d)) return [gsOutOfRange,null,"green","red",guOutOfRange,true];
  ...
}

Make sure you have set the gAgendaMask option properly beforehand, otherwise you may get nothing changed in the look since the corresponding bit may be masked.

How to adjust the algorithm of week numbers?

The default algorithm employed is ISO8601 standard, which means Jan 1st will belong to the last week of last year if it falls in the last 3 days of a week. To make it more flexible, now you may re-define the fWeekOffset function in plugins.js to return an offset of 1 or 0, which will be used to adjust the week number.

The day-of-week location of Jan 1st will be passed in as the only parameter. This location is a number of between 0 and 6 that denotes one of the 7 day-of-week columns of the calendar from left to right. Say you want that Jan 1st should be taken into the week no.1 of the current year only when it falls between Monday-Friday, and the giFirstDOW is set to 0 (means week column 0 is Sunday), then you should add the following code to plugins.js:

function fWeekOffset(dow) {
  return 1<=dow&&dow<=5?1:0;
}

If the giFirstDOW is set to 1 (means week column 0 is Monday), then the following code should be used instead (because Monday - Friday is 0 - 4 now):

function fWeekOffset(dow) {
  return dow<=4?1:0;
}

How to toggle the day between 3 different states when being clicked?

It's easy. Taking the HelloWorld demo as example, all you need is to add the following to the fAfterSelected in plugins.js:

function fAfterSelected(y,m,d,e) {
var evt=fGetEvent(y,m,d);
if (evt==null)
fAddEvent(y,m,d,"select-am","","green",null,null,null,null,1);
else if (evt[7]==1)
fAddEvent(y,m,d,"select-pm","","blue",null,null,null,null,2);
else if (evt[7]==2)
fAddEvent(y,m,d,"select-wholeday","","gold",null,null,null,null,3);
else if (evt[7]==3)
fRemoveEvent(y,m,d);
// put your own code here to store the status of each selection
fRepaint();
}

Note that the above code only makes the calendar in your browser cycle through 3 different states, you'll still need to add your own code in between to record the change (e.g. in a hidden form field) so ast to submit to backend server later.

How can I use overlib within the calendar to show event tooltips?

First you need to load the overlib script from within the engine, which can be done by appending the following line to plugins.js file.

fLoadScript("overlib.js");

Next, there is an option in the theme file called giFreeDiv that needs to be changed. Setting it to 1 (default is 0) will create 2 internal <div> tags whose
id are "freeDiv0" and "freeDiv1". Since "freeDiv0" has been referenced by most other plugins, you may use "freeDiv1" for the overlib -
simply go into the overlib.js, find all "overDiv" strings and replace them with "freeDiv1".

Now you may use overlib in your agenda.js freely, such as:

fAppendEvent(2002,12,14,"","",null,null,null,null,"<div><a href='javascript:void(0);' onmouseover='return overlib(\"This is an ordinary popup.\");' onmouseout='return nd();'>here</a></div>");

How can I de-select a date?

In most themes, all you need is to clear the gdSelect variable and repaint the calendar. e.g. create a de-select function in the plugins.js:

function fDeselect() {
fUpdSelect(0,0,0); // clear gdSelect
fRepaint();
}

Then call it whenever you want to remove the selected date from the calendar. Note, some themes may use additional variable to store multiple selected dates, and you just need to clear them in the same call.

How can I create the calendar iframe tag dynamically using javascript?

Some of our customers are interested in creating the calendar tag dynamically instead of having it written statically at the page bottom. The following code can do the trick on IE5+, Opera 7.54 and most Mozilla based browsers:

<script>
var html = '<ifr'+'ame name="gToday:normal:agenda.js" id="gToday:normal:agenda.js" src="iflateng.htm" scrolling="no" frameborder="0"></ifr'+'ame>';
if (document.all)
  document.body.insertAdjacentHTML('beforeEnd', html);
else {
  var range = document.createRange();
  range.setStartAfter(document.body.lastChild);
  var docFrag = range.createContextualFragment(html);
  document.body.appendChild(docFrag);
}
</script>

It's not fully tested on every platform, but you got the idea on how to do it.

IE 6 on WinXP SP2 raised an alert and blocked the calendar when I tried to view the demo, what's wrong?

Relax, that's the new script blocker introduced in IE6 of WinXP SP2. The alert will show up whenever you try to access a javascript page from local file explorer. However, it doesn't seem to affect the page on a real website. We've tested the calendars on different websites and haven't seen any alert. Please take a look at our online demos to get a peace of mind.

How to enable the user type-in box for the year in themes other than the contrast theme?

Since version 9.2 a new feature has been added to the contrast theme which allows the user to type-in the year quickly. You can easily apply it to other themes by appending the following code snippet to the plugins.js: (You may remove the previous definition of gsCalTitle, if any)

gsCalTitle="fGetCalTitle()";
function fGetCalTitle() {
return "&nbsp;<a class='PopAnchor' href='javascript:void(0);' onclick='if(this.blur)this.blur();fPopMenu(this,event);return false;'>"+gMonths[gCurMonth[1]-1]
+(NN4?" ":"</a> <a id='yearAnchor' class='PopAnchor' href='javascript:void(0)' onclick='fToggleLayer(1,true);fGetById(document,\"yearInput\").focus();return false;'>")+gCurMonth[0]+"</a>";
}
if(NN4)_nn4_css.push("YearBox"); // work around NN4 bug
giFreeDiv=2;
function fInitLayer() { // gets called from within fOnload()
if (NN4) return;
var lyr=fGetById(document,"freeDiv1");
lyr.style.top=(SA?2:IE&&!MAC?0:6)+"px"; lyr.style.left=(SA?63:65)+"px"; lyr.style.border=0;
fDrawLayer(1,"<input class='YearBox' id='yearInput' value='' maxlength=4 size=4 onkeyup='if(this.value.length==4){if(!isNaN(this.value))fSetCal(this.value,gCurMonth[1],0,true,event);this.select();this.blur()}' onblur='fToggleLayer(1,false);if(SA)this.blur()' onfocus='this.value=gCurMonth[0];this.select()' onclick='this.select()' onselectstart='event.cancelBubble=true'>");
}

Then append the following to the css file of the corresponding theme:

.YearBox {border:0px solid; height:12px; text-align:center; font:7.5pt verdana; color:black; background-color:white;}

Finally, call the fInitLayer() from within the fOnload() event handler in plugins.js: (fOnload is available only after version 9.2)

function fOnload() {
fInitLayer();
}

Of course you may change the size or color to match you local theme .


Copyright© 2003-2007 Idemfactor Solutions, Inc. All rights reserved.