Here are all kinds of tips and tricks that will help you greatly in mastering and enjoying PopCalendarXP. Please come to visit our web site http://www.calendarxp.net from time to time and you will find more interesting stuff.
Simply append the calendar engine tag to the bottom of your webpage and call
gfPop.fPopCalendar(dateCtrl)
from your script, which will pop-up
a beautiful picker under the "dateCtrl".
Please check out the HelloWorld Tutorial for more details.
Create an empty directory, put the engine files in. Then go to pick up a
theme you like, copy all files of the theme to the same directory. Finally,
if you want to add agendas, you may start with the agenda.js
from the HelloWorld demo as a template.
It's quite straightforward, please check out the Tutorials for more details and samples.
If you are upgrading from within the same major version, e.g. from 6.0 to 6.1, all you need to do 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 theme options. So 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 files if you want to keep your old theme working. But usually you don't need to change anything already in your production web page unless it is explicitly required by the new version in its release notes.
PopCalendarXP comes with great themes optimized for English environment. 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.
Simply set the following options in the theme-name.js file.
var gsSplit=" "; // separator of date string, AT LEAST one char.
var giDatePos=1; // date format sequence 0: D-M-Y ; 1: M-D-Y; 2: Y-M-D
var gbPadZero=true; // whether to pad the digits with 0 in the left when less than 10.
var giMonthMode=1; // month format 0: digits ; 1: full name from gMonths; >2: abbreviated name
var gbShortYear=false; // year format true: 2-digits; false: 4-digits
If you need more complex format, you can always build a plugin function by
your own. e.g. myFormat(y,m,d)
, and set it in fAfterSelected()
like:
function fAfterSelected(y,m,d) {
gdCtrl.value=myFormat(y,m,d);
}
gdCtrl
is an internal global reference to the current form date
object.
Add the following script snippet to your page, it'll do the trick. Note, you must set the name of popup button or image to "popcal" when using it, otherwise the calendar won't show up.
<script language="JavaScript">
// The following script is used to hide the calendar whenever you click the document.
document.onmousedown=function(e){
var n=!e?self.event.srcElement.name:e.target.name;
if (document.layers) {
with (gfPop) var l=pageX, t=pageY, r=l+clip.width, b=t+clip.height;
if (n!="popcal"&&(e.pageX>r||e.pageX<l||e.pageY>b||e.pageY<t)) gfPop.fHideCal();
return routeEvent(e); // must use return here.
} else if (n!="popcal") gfPop.fHideCal();
}
if (document.layers) document.captureEvents(Event.MOUSEDOWN);
</script>
This is just an example, you may use your own better solution.
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.
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.
Go to the theme-name.css
file and find the .CalCell
class, change the value of text-align
to left
, center
or right
.
For example, you want to perform the alert() function.
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.
}
fAfterSelected()
callback
plugin in the plugins.js
file, as following: function fAfterSelected(y,m,d) {
alert([y,m,d]+' has been selected.');
}
gsAction
option
in the theme-name.js
file, as following:
var gsAction="alert([y,m,d]+' has been
selected.');";
It's a bug of IE on Mac. To workaround, you may set the margin and padding of the <body> tag in your page to 0. For example,
<style type="text/css">BODY {margin:0; padding:0}</style>
Another way is to take advantage of the gPosOffset
theme option,
set it as following:
var gPosOffset=(IE&&MAC)?[12,14]:[0,0];
So if the browser is IE on Mac, the calendar engine will offset the popup position 12 pixels righter and 14 pixels lower.
There is an option in the theme-name.js file called gPosOffset
that controls the offset. Say if you want to adjust the pop-up position by
10 pixels higher in browsers other than Netscape 4.x, you need to set it as
var gPosOffset=[0, NN4?0:-10];
There is an option in the theme-name.js file called gbFixedPos
.
Simply set it to true
and then set the value of gPosOffset
to the static coordinates of the popup position.
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 agenda event is set per day. If you have 2 more events in the same day,
you need to code your own functions to merge them into 1 agenda. And you may
take advantage of the html
parameter of the agenda to stuff in
more messages and even images into the calendar cell.
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.
Increasing giResizeDelay
will help to eliminate this problem
by telling the engine to check the size later. But also note that a larger
value may bring in visible delay when switching between months with the gbShrink2fit
set to true.
Another solution is to adjust the width
and height
to be the correct initial size.
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.
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
.
There are 3 factors that determine which month will be shown when the calendar pops up for the very first time.
1st, if the associated form date object's value is a valid date, then that date will be selected and shown up.
2nd, otherwise if the gdSelect
option is set to a valid date,
then the calendar will come up with it.
3rd, if none of the above applies, the calendar will show up with the month
set by the default-month
parameter in the name & id properties
of the calendar tag. No date gets selected.
In the 3rd situation, for example, if you set the name&id of the calendar
tag to "[2002,10]:normal:agenda.js"
, 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 up.
After the first pop-up, the calendar will remember the selected date.
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, for the weekends so that they can't be selected. You may also
disable other dates via the same way. Another tip is to define more properties
in the template so that the disabled dates can have different color, background
or even images.
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.
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;
}
To submit the form associated with the current date field (the one you passed
in as a parameter of fPopCalendar), you should use the following code in plugins.js
file:
function fAfterSelected(y,m,d) {
gdCtrl.form.submit();
}
To submit a static form named as "testForm", you may use:
function fAfterSelected(y,m,d) {
gContainer.document.testForm.submit();
}
The calendar engine has 2 system objects "gd
" and
"gToday
" which can be overriden in agenda.js
file. You may exploit this feature when you want the calendar to mark a server-end
"today" instead of a client-side "today".
1st, you need to prepend the following lines of code to the top of agenda.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 do a search in the theme-name.js file that your theme is using,
e.g. normal.js
, for any references to gToday
. And
copy those options definition to agenda.js file and put them just below the
above lines. 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)
And that's it. Of course, you may use ASP/JSP to generate the agenda.js
so that you can specify a server-end date, like:
gd=new Date(<%= year %>,<%= month %>-1,<%= day %>);
// year, month, day are server-end variables
...
Also note that all options in the theme-name.js can be reset dynamically in this manner.
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.
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];
...
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 are using this solution to create calendar
borders.
#outerTable {border:2px ridge #808080;}
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".
Opera 7 seems to have a z-index bug and layer the iframe objects only by loading sequence. To work around, simply move the calendar iframe tag from the page bottom to page top, as following:
<BODY>
<iframe width=174 height=189 name="gToday:normal:agenda.js" id="gToday:normal:agenda.js"
src="ipopeng.htm" scrolling="no" frameborder="0"
style="visibility:visible; z-index:999; position:absolute; left:-500px;
top:0px;">
</iframe>
...
... your html page contents ...
...
<LAYER name="gToday:normal:agenda.js" src="npopeng.htm">
</LAYER>
</BODY>
NOTE that you mustn't move the <LAYER>
calendar tag, otherwise
NN4 will fail.