### Plugins SDK

The `plugins.js` is a place to extend the behaviors of the calendar. The plugin file name is defined in the name & id of the calendar tag. If nothing specified, it will use the default value `plugins.js`. Some themes need special plugin functions to create customized behaviors like artificial internal selectors and so on. Therefore, we also treat it as part of the theme.

#### Build-in event handlers

1st, the `fOnChange()` callback function. Once defined, it will be invoked every time the calendar about to get changed or selected. Moreover, return a `true` value from it will cancel the current action causing the change, as if there were nothing happened. The reference to the `event` object is passed in as the `e` parameter. Since it could be null value, you should check before using.

> `///////////// Calendar Onchange Handler ////////////////////////////
> // It's triggered whenever the calendar gets changed to y(ear),m(onth),d(ay)
> // d = 0 means the calendar is about to switch to the month of (y,m);
> // d > 0 means a specific date [y,m,d] is about to be selected.
> // e is a reference to the triggering event object
> // Return a true value will cancel the change action.
> // NOTE: DO NOT define this handler unless you really need to use it.
> ////////////////////////////////////////////////////////////////////
> function fOnChange(y,m,d,e) {
> .... put your code here ....
> return false; // return true to cancel the change.
> }`

Another callback function is the `fAfterSelected()`, which is triggered only after the date gets selected. The reference to the `event` object is passed in as the `e` parameter. Since it could be null value, you should check before using.

> `///////////// Calendar AfterSelected Handler ///////////////////////
> // It's triggered whenever a date gets fully selected.
> // The selected date is passed in as y(ear),m(onth),d(ay)
> // e is a reference to the triggering event object
> // NOTE: DO NOT define this handler unless you really need to use it.
> ////////////////////////////////////////////////////////////////////
> function fAfterSelected(y,m,d,e) {
> .... put your code here ....
> }`

The 3rd one is the `fOnDrag()`, which is triggered during mousedown and mousemove. It tries to utilize mousedown and mouseover events to create a cross-browser drag event. Note it's not a guaranteed callback and not work in all browsers. The reference to the `event` object is passed in as the `e` parameter. Since it could be `null` value, you should check before using.

The other things need to be mentioned is the aStat parameter. Since different browsers have different way or capability in supporting mouse dragging event, we set up a common way here to simulate it:

1. Whenever a mousedown is detected on a calendar cell, the fOnDrag will be called with `aStat` set to 0. At this stage, you could prepare a dragging start.
2. Later, if the left mouse-button is not released and a mouseover is detected on another calendar cell, the fOnDrag will be called with `aStat` set to 1. At this stage, you know the user is dragging the mouse.
3. Finally, if any mouseup is detected within or outside the calendar panel, the fOnDrag will again be called with `aStat` set to 2. The (y,m,d) will all be 0 if mouseup is not happened on a calendar cell. However, chances are that the user releases the mouse button outside the browser and certain browsers don't report such out-of-bound mouseup event at all. In such case there will be no callback upon fOnDrag with `aStat` of 2.

> `///////////// Calendar Cell OnDrag Handler ///////////////////////
> // It triggered when you try to drag a calendar cell. (y,m,d) is the cell date.
> // aStat = 0 means a mousedown is detected (dragstart)
> // aStat = 1 means a mouseover between dragstart and dragend is detected (dragover)
> // aStat = 2 means a mouseup is detected (dragend)
> // e is a reference to the triggering event object
> // NOTE: DO NOT define this handler unless you really need to use it.
> ////////////////////////////////////////////////////////////////////
> function fOnDrag(y,m,d,aStat,e) {
> .... put your code here ....
> }`

The 4th one is the `fOnResize()`, which is triggered after a short delay when the calendar finished drawing and before resizing itself to fit the change. You may add some code here to re-adjust the contents of the calendar.

> `////////////////// Calendar OnResize Handler ///////////////////////
> // It's triggered after the calendar panel has finished drawing.
> // NOTE: DO NOT define this handler unless you really need to use it.
> ////////////////////////////////////////////////////////////////////
> // function fOnResize() {
> .... put your code here ....
> }`

The 5th one is the `fOnWeekClick()`, which is triggered when the week number is clicked. You may use it to arrange specific actions when user clicks on the week number. Of course, you should first set the `giWeekCol` option to 0 so that the week numbers can be displayed.

> `////////////////// Calendar fOnWeekClick Handler ///////////////////////
> // It's triggered when the week number is clicked.
> // NOTE: DO NOT define this handler unless you really need to use it.
> ////////////////////////////////////////////////////////////////////
> function fOnWeekClick(year, weekNo) {
> .... put your code here ....
> }`

The 6th one is the `fIsSelected()` call-back, which is triggered for every date passed in as y(ear) m(onth) d(ay). When it returns a `true` value, the engine will render that specific date using the "select series" theme options, like giMarkSelected, gcFGSelected, gcBGSelected and guSelectedBGImg. If not defined here, the engine will automatically create one that checks the `gdSelect` only. Therefore, you can always bank on using it.

> `////////////////// Calendar fIsSelected Callback ///////////////////////
> // It's triggered for every date passed in as y(ear) m(onth) d(ay). And if
> // the return value is true, that date will be rendered using the giMarkSelected,
> // gcFGSelected, gcBGSelected and guSelectedBGImg theme options.
> // NOTE: If NOT defined here, the engine will create one that checks the gdSelect only.
> ////////////////////////////////////////////////////////////////////
> function fIsSelected(y,m,d) {
> return gdSelect[2]==d&&gdSelect[1]==m&&gdSelect[0]==y;
> }`

The 7th one is the fParseInput(), which is used to parse the input string stored in the `value` property of gdCtrl. It's expected to return an array of [y,m,d] to indicate the parsed date or `null` if the input str can't be parsed as a date. If not defined, the engine will automatically create one that is equivalent to the fParseDate(). Therefore, you can always bank on the fParseInput() instead of using fParseDate().

> `////////////////// Calendar fParseInput Handler ///////////////////////
> // Once defined, it'll be used to parse the input string stored in gdCtrl.value.
> // It's expected to return an array of [y,m,d] to indicate the parsed date,
> // or null if the input str can't be parsed as a date.
> // NOTE: If NOT defined here, the engine will create one matching fFormatDate().
> ////////////////////////////////////////////////////////////////////
> function fParseInput(str) {
> `.... you may parse with your extra format here and then delegate the rest to the built-in fParseDate() ....`
> }`

The 8th one is the fFormatInput(), which is used to format the selected date y(ear) m(onth) d(ay) into the `value` property of gdCtrl. It's expected to return a formated date string. If not defined, the engine will automatically create one that is equivalent to the fFormatDate(). Therefore, you can always bank on the fFormatInput() instead of using fFormatDate().

> `////////////////// Calendar fFormatInput Handler ///////////////////////
> // Once defined, it'll be used to format the selected date - y(ear) m(onth) d(ay)
> // into gdCtrl.value.
> // It's expected to return a formated date string.
> // NOTE: If NOT defined here, the engine will create one matching fFormatDate().
> ////////////////////////////////////////////////////////////////////
> function fFormatInput(y,m,d) {
> ``.... you may call the built-in fFormatDate() first and then apply your own format to the return value ....``
> }`

The 9th one is the `fOnDoWClick()` call-back, which is triggered when the week title (day of week) is clicked. It may be useful if you want to select dates by day-of-week (per column).

> `////////////////// Calendar fOnDoWClick Handler ///////////////////////
> // It's triggered when the week head (day of week) is clicked.
> // dow ranged from 0-6 while 0 denotes Sunday, 6 denotes Saturday.
> // NOTE: DO NOT define this handler unless you really need to use it.
> ////////////////////////////////////////////////////////////////////
> function fOnDoWClick(year, month, dow) {
> `.... put your code here ....`
> }`

The 10th one is the `fOnload()` call-back, which is triggered when the calendar engine (iframe) is fully loaded. It may be useful if you want to perform certain action only after the calendar is fully rendered.

> `////////////////// Calendar fOnload Handler ///////////////////////
> // It's triggered when the calendar engine is fully loaded by the browser.
> // NOTE: DO NOT define this handler unless you really need to use it.
> ////////////////////////////////////////////////////////////////////
> function fOnload() {
> `.... put your code here ....`
> }`

These are very useful features. Please check out the demos for good examples.

#### Some predefined objects can be used in plugins/themes to aid your customization

- gContainer is a global reference to the parent window that contains the calendar engine. It can be used to access objects outside the engine context, e.g form fields or frames in your web page.
- gfSelf is a reference of the calendar engine frame itself.
- gToday is a 3-element array containing the current date of the operating system, in the format of [year, month, day].
- gCurMonth is a 2-element array controls the month to be shown in the calendar panel, in the format of [year, month].
- gTheme is actually the whole parameter array parsed from the name&id of the calendar tag.
- ua is the navigator.userAgent string in all lower-case.
- gdSelect is an array that stores the current selected date in format [year, month, day]. NOTE that if you want to update it programatically, you should better do it via the fUpdSelect() function to avoiding potential inconsistency.
- gbCacheAgenda is a boolean that is by default set to `true`, which means the calendar engine will employ certain approach to prevent the browser from caching the agenda file.
- gdCtrl is a reference to the outside `dateCtrl` object. It's passed in via the fPopCalendar() function.
- giShowInterval is a value that determines the speed of auto-traversing when you holding down the month navigation button. It's by default set to delay 250ms.

#### Some system functions may also be much helpful

- fShowCal(x,y) is used to show the calendar panel at designated location.
- fHideCal() is used to hide (close) the calendar panel. It's needed to program a "close" button.
- fGetXY(tag,offset) will return the position [x,y] of the tag with the offset adjustment.
- fRepaint() is used to refresh the calendar panel so that the latest update of agenda can be revealed.
- fUpdSelect(y,m,d) marks the (y,m,d) as the selected date.
- fAddEvent(), fGetEvent() and fRemoveEvent() are used to set, get and delete disparate agenda events.
- fGetAgenda(y,m,d,taint) will return the constrained agenda & holiday events if taint is true; or non-constrained if taint is false. Constrained means that for all dates outside the current panel view a null value or modified event will be returned according to the `giShowOther` option. Non-constrained means simply return the result from `fHoliday()` excluding the dates out of theme range.
- fSetCal(y,m,d,bTriggerOnChg,e) will set selected date to the specific date. If d is 0, the calendar will be switched to the specific month only. bTriggerOnChg determines whether the`fOnchange()` plugin will be called or not. It's very userful to avoid looping calls when coordinating among multiple calendars. e is optional but should be set to the reference of an event object if any event property were to be used by specific plugins. It'll return false if designated date is out of selectable range.
- fSetDate(y,m,d,taint,e) is somewhat like fSetCal(), but it will check against agenda (agenda range determined by taint flag) to activate the associated actions if applicable. taint and event are optional and usually omitted. It'll return false if designated date is out-of-range or has a `null` agenda action.
- fPrevMonth(e) and fNextMonth(e) are used to switch the calendar to previous or next month. e is optional but should be set to the reference of event object if any event property were to be accessed in the plugins.
- showPrevMon(), showNextMon() and stopShowMon() are set to trigger/stop the auto-traverse feature. Generally speaking, set the first two in onmousedown event to start auto-traversing at the speed determined by giShowInterval, and set the last one in onmouseup and onmouseout to stop. NOTE that you also need to set the id of the tag, used in theme option gsNavPrev or gsNavNext, to be "navPrev" or "navNext" respectively.
- fDate2W(y,m,d) converts the specific date to [year, weekOfYear, Nth-dayOfWeek]. weekOfYear is ranged from 1 to 53; Nth-dayOfWeek is ranged from 1 to 7. fW2Date(y,w,wd) is the reverse function.
- fGetDateByDOW(y,m,q,dow) returns the date of the month (y,m), which is the q-th day-of-week of month (y,m). e.g. fGetDateByDOW(2004,1,1,0) means to get the first Sunday of January 2004. q ranges from 1 to 5, 5 meaning the last dow of the month. dow ranges from 0 to 6 and the return value ranges from 1 to 31.
- fLoadScript(url) loads a javascript file from the designated URL dynamically and execute it within the calendar context. Note currently it's only supported by IE5+(except Mac), NS6+, Mozilla and Opera7+.
- fParseDate(str) will parse the string and return a [y,m,d] array or `null` if it can't be parsed according to the date format options in the employed theme. You should always use `fParseInput(str)`, which will call the fParseDate() by default, in your code whenever you want to parse the input string complying with the theme settings, unless you are programming the `fParseInput(str)` plugin itself.
- fFormatDate(y,m,d) will return a formated date string according to the date format options in the employed theme. You should instead use `fFormatInput(y,m,d)`, which will call the fFormatDate() by default, in your code whenever you want to format a date string complying with the theme settings, unless you are programming the fFormatInput() plugin itself.

#### Override theme options in plugins.js

Because theme options are loaded before the plugins, you may re-define any option of `theme-name.js` from within `plugins.js`. The benefit is that you can add additional features or make small changes without touching the standard theme. The bundled demos are using this approach to share themes.

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