2007-03-30 04:36:52 +00:00
/* Copyright Mihai Bazon, 2002, 2003 | http:/ / dynarch . com / mishoo /
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
*
* The DHTML Calendar
*
* Details and latest version at :
* http : //dynarch.com/mishoo/calendar.epl
*
* This script is distributed under the GNU Lesser General Public License .
* Read the entire license text here : http : //www.gnu.org/licenses/lgpl.html
*
* This file defines helper functions for setting up the calendar . They are
* intended to help non - programmers get a working calendar on their site
* quickly . This script should not be seen as part of the calendar . It just
* shows you what one can do with the calendar , while in the same time
* providing a quick and simple method for setting it up . If you need
* exhaustive customization of the calendar creation process feel free to
* modify this code to suit your needs ( this is recommended and much better
* than modifying calendar . js itself ) .
* /
// $Id: calendar-setup.js,v 1.25 2005/03/07 09:51:33 mishoo Exp $
/ * *
* This function "patches" an input field ( or other element ) to use a calendar
* widget for date selection .
*
* The "params" is a single object that can have the following properties :
*
* prop . name | description
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
* inputField | the ID of an input field to store the date
* displayArea | the ID of a DIV or other element to show the date
* button | ID of a button or other element that will trigger the calendar
* eventName | event that will trigger the calendar , without the "on" prefix ( default : "click" )
* ifFormat | date format that will be stored in the input field
* daFormat | the date format that will be used to display the date in displayArea
* singleClick | ( true / false ) wether the calendar is in single click mode or not ( default : true )
* firstDay | numeric : 0 to 6. "0" means display Sunday first , "1" means display Monday first , etc .
* align | alignment ( default : "Br" ) ; if you don 't know what' s this see the calendar documentation
* range | array with 2 elements . Default : [ 1900 , 2999 ] -- the range of years available
* weekNumbers | ( true / false ) if it ' s true ( default ) the calendar will display week numbers
* flat | null or element ID ; if not null the calendar will be a flat calendar having the parent with the given ID
* flatCallback | function that receives a JS Date object and returns an URL to point the browser to ( for flat calendar )
* disableFunc | function that receives a JS Date object and should return true if that date has to be disabled in the calendar
* onSelect | function that gets called when a date is selected . You don ' t _have _ to supply this ( the default is generally okay )
* onClose | function that gets called when the calendar is closed . [ default ]
* onUpdate | function that gets called after the date is updated in the input field . Receives a reference to the calendar .
* date | the date that the calendar will be initially displayed to
* showsTime | default : false ; if true the calendar will include a time selector
* timeFormat | the time format ; can be "12" or "24" , default is "12"
* electric | if true ( default ) then given fields / date areas are updated for each move ; otherwise they ' re updated only on close
* step | configures the step of the years in drop - down boxes ; default : 2
* position | configures the calendar absolute position ; default : null
* cache | if "true" ( but default : "false" ) it will reuse the same calendar object , where possible
* showOthers | if "true" ( but default : "false" ) it will show days from other months too
*
* None of them is required , they all have default values . However , if you
* pass none of "inputField" , "displayArea" or "button" you ' ll get a warning
* saying "nothing to setup" .
* /
Calendar . setup = function ( params ) {
function param _default ( pname , def ) { if ( typeof params [ pname ] == "undefined" ) { params [ pname ] = def ; } } ;
param _default ( "inputField" , null ) ;
param _default ( "displayArea" , null ) ;
param _default ( "button" , null ) ;
param _default ( "eventName" , "click" ) ;
param _default ( "ifFormat" , "%Y/%m/%d" ) ;
param _default ( "daFormat" , "%Y/%m/%d" ) ;
param _default ( "singleClick" , true ) ;
param _default ( "disableFunc" , null ) ;
param _default ( "dateStatusFunc" , params [ "disableFunc" ] ) ; // takes precedence if both are defined
param _default ( "dateText" , null ) ;
param _default ( "firstDay" , null ) ;
param _default ( "align" , "Br" ) ;
param _default ( "range" , [ 1900 , 2999 ] ) ;
param _default ( "weekNumbers" , true ) ;
param _default ( "flat" , null ) ;
param _default ( "flatCallback" , null ) ;
param _default ( "onSelect" , null ) ;
param _default ( "onClose" , null ) ;
param _default ( "onUpdate" , null ) ;
param _default ( "date" , null ) ;
param _default ( "showsTime" , false ) ;
param _default ( "timeFormat" , "24" ) ;
param _default ( "electric" , true ) ;
param _default ( "step" , 2 ) ;
param _default ( "position" , null ) ;
param _default ( "cache" , false ) ;
param _default ( "showOthers" , false ) ;
param _default ( "multiple" , null ) ;
var tmp = [ "inputField" , "displayArea" , "button" ] ;
for ( var i in tmp ) {
if ( typeof params [ tmp [ i ] ] == "string" ) {
params [ tmp [ i ] ] = document . getElementById ( params [ tmp [ i ] ] ) ;
}
}
if ( ! ( params . flat || params . multiple || params . inputField || params . displayArea || params . button ) ) {
alert ( "Calendar.setup:\n Nothing to setup (no fields found). Please check your code" ) ;
return false ;
}
function onSelect ( cal ) {
var p = cal . params ;
var update = ( cal . dateClicked || p . electric ) ;
if ( update && p . inputField ) {
p . inputField . value = cal . date . print ( p . ifFormat ) ;
if ( typeof p . inputField . onchange == "function" )
p . inputField . onchange ( ) ;
}
if ( update && p . displayArea )
p . displayArea . innerHTML = cal . date . print ( p . daFormat ) ;
if ( update && typeof p . onUpdate == "function" )
p . onUpdate ( cal ) ;
if ( update && p . flat ) {
if ( typeof p . flatCallback == "function" )
p . flatCallback ( cal ) ;
}
if ( update && p . singleClick && cal . dateClicked )
cal . callCloseHandler ( ) ;
} ;
if ( params . flat != null ) {
if ( typeof params . flat == "string" )
params . flat = document . getElementById ( params . flat ) ;
if ( ! params . flat ) {
alert ( "Calendar.setup:\n Flat specified but can't find parent." ) ;
return false ;
}
var cal = new Calendar ( params . firstDay , params . date , params . onSelect || onSelect ) ;
cal . showsOtherMonths = params . showOthers ;
cal . showsTime = params . showsTime ;
cal . time24 = ( params . timeFormat == "24" ) ;
cal . params = params ;
cal . weekNumbers = params . weekNumbers ;
cal . setRange ( params . range [ 0 ] , params . range [ 1 ] ) ;
cal . setDateStatusHandler ( params . dateStatusFunc ) ;
cal . getDateText = params . dateText ;
if ( params . ifFormat ) {
cal . setDateFormat ( params . ifFormat ) ;
}
if ( params . inputField && typeof params . inputField . value == "string" ) {
cal . parseDate ( params . inputField . value ) ;
}
cal . create ( params . flat ) ;
cal . show ( ) ;
return false ;
}
var triggerEl = params . button || params . displayArea || params . inputField ;
triggerEl [ "on" + params . eventName ] = function ( ) {
var dateEl = params . inputField || params . displayArea ;
var dateFmt = params . inputField ? params . ifFormat : params . daFormat ;
var mustCreate = false ;
var cal = window . calendar ;
if ( dateEl )
params . date = Date . parseDate ( dateEl . value || dateEl . innerHTML , dateFmt ) ;
if ( ! ( cal && params . cache ) ) {
window . calendar = cal = new Calendar ( params . firstDay ,
params . date ,
params . onSelect || onSelect ,
params . onClose || function ( cal ) { cal . hide ( ) ; } ) ;
cal . showsTime = params . showsTime ;
cal . time24 = ( params . timeFormat == "24" ) ;
cal . weekNumbers = params . weekNumbers ;
mustCreate = true ;
} else {
if ( params . date )
cal . setDate ( params . date ) ;
cal . hide ( ) ;
}
if ( params . multiple ) {
cal . multiple = { } ;
for ( var i = params . multiple . length ; -- i >= 0 ; ) {
var d = params . multiple [ i ] ;
var ds = d . print ( "%Y%m%d" ) ;
cal . multiple [ ds ] = d ;
}
}
cal . showsOtherMonths = params . showOthers ;
cal . yearStep = params . step ;
cal . setRange ( params . range [ 0 ] , params . range [ 1 ] ) ;
cal . params = params ;
cal . setDateStatusHandler ( params . dateStatusFunc ) ;
cal . getDateText = params . dateText ;
cal . setDateFormat ( dateFmt ) ;
if ( mustCreate )
cal . create ( ) ;
cal . refresh ( ) ;
if ( ! params . position )
cal . showAtElement ( params . button || params . displayArea || params . inputField , params . align ) ;
else
cal . showAt ( params . position [ 0 ] , params . position [ 1 ] ) ;
return false ;
} ;
if ( params . inputField ) {
new DateDueKeyboardShortcutSupport ( params . inputField , params . ifFormat , cal ) ;
}
return cal ;
} ;
/ * A d d s k e y b o a r d s h o r t c u t s t o t h e p a s s e d i n d a t e f i e l d :
*
* 't' input today ' s date
* '+' or '=' increment the date in the field by one day
* '-' decrement the date in the field by one day
*
* If the calendar is visible , the shortcuts play nicely with it . If not ,
* they still work properly . Pressing '+' when no date is entered in the
* field will set the date to tomorrow , and likewise '-' with no date
* entered will set the date to yesterday .
* /
DateDueKeyboardShortcutSupport = Class . create ( ) ;
DateDueKeyboardShortcutSupport . prototype = {
initialize : function ( element , dateFormat ) {
this . element = $ ( element ) ;
this . dateFormat = dateFormat || "%Y/%m/%d" ;
Event . observe ( this . element , 'keypress' , this . onkeypress . bindAsEventListener ( this ) ) ;
title = this . element . getAttributeNode ( "title" ) ;
2007-04-02 04:55:04 +00:00
tooltip = 'Shortcuts: (t) today; (-) or (<) previous day; (+) or (>) next day; ([) previous week; (]) next week; ({) previous month; (}) next month; Click to show calendar' ;
2007-03-30 04:36:52 +00:00
if ( title && title . value )
{
this . element . setAttribute ( "title" , title . value + ' (' + tooltip + ')' ) ;
}
else
{
this . element . setAttribute ( "title" , tooltip ) ;
}
} ,
onkeypress : function ( event ) {
handled = true ;
switch ( this . getCharFromKeyPressEvent ( event ) ) {
case "t" :
this . setTextBoxToTodaysDate ( ) ;
break ;
case "+" :
2007-04-02 04:55:04 +00:00
case ">" :
2007-03-30 04:36:52 +00:00
case "=" :
this . setTextBoxToNextDay ( ) ;
break ;
case "-" :
2007-04-02 04:55:04 +00:00
case "<" :
2007-03-30 04:36:52 +00:00
this . setTextBoxToPreviousDay ( ) ;
break ;
2007-04-02 04:55:04 +00:00
case "[" :
this . setTextBoxToPreviousWeek ( ) ;
break ;
case "]" :
this . setTextBoxToNextWeek ( ) ;
break ;
case "{" :
this . setTextBoxToPreviousMonth ( ) ;
break ;
case "}" :
this . setTextBoxToNextMonth ( ) ;
break ;
2007-03-30 04:36:52 +00:00
default :
handled = false ;
break ;
}
if ( handled ) {
this . cancel ( event ) ;
}
} ,
setTextBoxToChronicDate : function ( ) {
today = new Date ( ) ;
this . setDate ( today ) ;
} ,
setTextBoxToTodaysDate : function ( ) {
today = new Date ( ) ;
this . setDate ( today ) ;
} ,
setTextBoxToNextDay : function ( ) {
this . addDaysToTextBoxDate ( 1 ) ;
} ,
setTextBoxToPreviousDay : function ( ) {
this . addDaysToTextBoxDate ( - 1 ) ;
} ,
2007-04-02 04:55:04 +00:00
setTextBoxToNextWeek : function ( ) {
this . addDaysToTextBoxDate ( 7 ) ;
} ,
setTextBoxToPreviousWeek : function ( ) {
this . addDaysToTextBoxDate ( - 7 ) ;
} ,
2007-03-30 04:36:52 +00:00
addDaysToTextBoxDate : function ( numDays ) {
date = Date . parseDate ( this . element . value , this . dateFormat ) ;
date . setDate ( date . getDate ( ) + numDays ) ;
this . setDate ( date ) ;
} ,
2007-04-02 04:55:04 +00:00
setTextBoxToNextMonth : function ( ) {
date = Date . parseDate ( this . element . value , this . dateFormat ) ;
date . setMonth ( date . getMonth ( ) + 1 ) ;
this . setDate ( date ) ;
} ,
setTextBoxToPreviousMonth : function ( ) {
date = Date . parseDate ( this . element . value , this . dateFormat ) ;
date . setMonth ( date . getMonth ( ) - 1 ) ;
this . setDate ( date ) ;
} ,
2007-03-30 04:36:52 +00:00
setDate : function ( date ) {
this . element . value = date . print ( this . dateFormat ) ;
if ( window . calendar ) {
window . calendar . setDate ( date ) ;
}
} ,
cancel : function ( event ) {
if ( event . preventDefault ) {
event . preventDefault ( ) ;
}
event . returnValue = false ;
} ,
getCharFromKeyPressEvent : function ( event ) {
var charCode = ( event . charCode ) ? event . charCode :
( ( event . keyCode ) ? event . keyCode :
( ( event . which ) ? event . which : 0 ) ) ;
return String . fromCharCode ( charCode ) ;
}
} ;