Scal is a simple, javascript calendar/date picker based on the Prototype js library.
scriptaculous is a nifty effect library for javascript (and a whole lot more). Previous versions of scal required you to include scriptaculous when calling up the calendar. This dependency does not exist in v0.2. However, scal still supports scriptaculous Effects (see scal options for more information).
It's easy to use, just include the javascript and the css file.
<script type="text/javascript" src="/javascripts/prototype.js"> </script>
<script type="text/javascript" src="/javascripts/scal.js"> </script>
<link href="/styles/scal.css" rel="stylesheet" type="text/css"/>To create a calendar, just create an instance of scal with your base element and the update callback, along with optional parameters.
<div id="samplecal" class="scal"></div>
<div id="scalupdate"> </div>
var samplecal = new scal('samplecal', 'scalupdate');Test It
Ian Tyndall - Lead Developer v0.2
Jamie Grove - Project Founder (and general layabout)
Andrew Reutter
Thomas Walpole
Kangax
DMenT
New! jPint Scal is part of the stack for Journyx's web-based iPhone development kit. Thanks to Andrew Reutter!
Ajaxian Thanks, Dion!
script.aculo.us samplr Thanks, Leonardo!
Scripteka: Prototype Extensions Library Thanks, Scripteka Dudes!
del.icio.us popular links Thanks, well, everyone! :)
This open-source library is licensed under a MIT-style license, so you can use it for anything you like, as long as you include the copyright notice.
As members of an all-volunteer project, we encourage you to contribute any changes to the further development of the control and think about other code contributions you can make to the general open-source community.
Scal is available free of charge. Any donations received are dispersed to other projects in the open source community (see PayPal link below).
javascripts/scal.js - The meat of the project.
styles/scal.css - Styles used by scal when using divs instead of tables to build the control.
styles/scaltable.css - Styles used by scal when using tables instead of divs to build the control.
** Note ** Only include one of the css files. The two modes (div/tables) are not compatible style-wise.
javascripts/scalplanner.js - Adds a basic planner to scal. This functionality was included in scal.js under v0.1. It was separated for v0.2 as not everyone needs a planner. (Major feature additions will follow the same pattern from this point forward.)
scaltester_new.html - Provides a sample scal instance along with forms to set options on the fly. Consider it a live demo reel. (see it live here)
planner_test.html - Loads up the planner with events. A few of these tests are included in the scal_unittest.html file. (see it live here)
scal_unittest.html - Uses the script.aculo.us unittest framework to put scal through its paces. Very helpful if you are tweaking parts of scal and want to see if anything breaks.
slick_test.html - Uses the scal slick style to show off the tables version of the calendar display.(see it live here)
This method changes the current date and redraws the calendar. By default, will execute the update callback.
This methods required parameter can be a String or a Date object.
If the parameter is a date object, the current date will be set to new the parameter date.
As a String, the allowed paramater values are:
This method accepts a second optional parameter. When passed as boolean true, this method will not execute the update callback.
This method returns the modified current date.
var options = ({
month:11,
year:2009,
day: 1
});
var Cal = new scal('samplecal',updateelement,options);
Cal.setCurrentDate('monthup'); // Changes the current date from 11-01-2009 to 12-01-2009
Cal.setCurrentDate('yearup'); // Changes the the current date from 12-01-2009 12-01-2010
Cal.setCurrentDate('init'); // Changes the current date to the original date: 11-01-2009
Cal.setCurrentDate('monthdown'); // Changes the current date from 11-01-2009 to 10-01-2009
Cal.setCurrentDate('yeardown'); // Changes the current date from 10-01-2009 to 10-01-2008
var d = new Date(2007,10,1);
Cal.setCurrentDate(d); // Changes the current date to 11-01-2007Stops event observations related to scal, obliterates the scal instance, removes elements created by scal, and generally frees up memory.
None
None
Cal.destroy();If the calendar is visible, calling this function makes it invisible. Amazingly, the reverse is also true.
None
None
Cal.toggleCalendar();Retrieves the calendar day element for the specified date.
Date object of the the specified element to retrieve.
The calendar element for the specified date.
var dayElement = Cal.getElementByDate(new Date('December 12, 2008'));Retrieves the calendar day elements for the specified week.
Number of the week to retrieve elements for.
Array of calendar day elements for the specified week.
var weekElements = Cal.getElementsByWeek(1);Retrieves the selected day for the current calendar.
None
The calendar element for the selected day.
var selected = Cal.getSelectedElement();Retrieves the today element for the current calendar.
None
The calendar element for today's element.
var today = Cal.getTodaysElement();Retrieves the date object for the specified calendar day element.
Extended element in the current calendar view.
Date object for the specified element.
var dayTwo = Cal.getDateByElement(weekElements[1]); Displays the calendar.
None
None
Hides the calendar.
None
None
Returns boolean indicating the display status of the calendar.
None
true/false
element
A handle for the container where scal lives on the page.
updateelement
A handle for the element that is updated by a click on the calendar.
cells
A handle to all of the cells in the calendar.
startdate
The first date provided when the calendar was created. Defaults to the current date
currentdate
This is the date currently selected.
daterange
An array of all dates currently displayed. Includes dates that fall outside the active month but are visible to round out the weeks.
firstofmonth/lastofmonth
The first and last months of the active month being displayed.
options
Options for the control expressed as a dictionary object. (see scal options for more information),
When you create an instance of scal, you can pass in a dictionary object containing a variety of display settings. These settings control the way certain fields display in scal and how they react to user interaction (i.e. clicks).
Below you can see the default settings for scal as defined in the scal.js file:
this.options = Object.extend({
oncalchange: Prototype.emptyFunction,
daypadding: false,
titleformat: 'mmmm yyyy',
updateformat: 'yyyy-mm-dd',
closebutton: 'X',
prevbutton: '«',
nextbutton: '»',
yearnext: '»»',
yearprev: '««',
openeffect: type == 'Effect' ? Effect.Appear : Element.show,
closeeffect: type == 'Effect' ? Effect.Fade : Element.hide,
exactweeks: false,
dayheadlength: 2,
weekdaystart: 0,
planner: false,
tabular: false,
year: this.startdate.getFullYear(),
month: 1,
day: 1
})You can override these settings by passing in your own options dictionary when you instantiate scal.
The purpose of each option is described below:
oncalchange
Call back function when one of the calendar controls is selected.
Defaults to empty function.
var Cal = new scal('samplecal',updateelement, {
oncalchange: function(d) {
alert('Calendar Change: ' + d.format('yyyy-mm-dd'));
}
});daypadding
Pad the day digits to two digit length. Defaults to false.
titleformat
Text format for the header of the calendar. Defaults to mmmm yyyy (Full month name and year)
updateformat
Default format used when updating the update element. Defaults to yyyy-mm-dd.
closebutton
Defines the innerHTML for the calendar's close button. Defaults to 'X' (you can pass in elements or strings)
prevbutton
Defines the innerHTML for the calendar's previous month button. Defaults to '«' (you can pass in elements or strings)
nextbutton
Defines the innerHTML for the calendar's next month button. Defaults to '»' (you can pass in elements or strings)
yearnext
Defines the innerHTML for the calendar's next year button. Defaults to '»»' (you can pass in elements or strings)
yearprev
Defines the innerHTML for the calendar's previous year button. Defaults to '««' (you can pass in elements or strings)
openeffect
Defines the 'Effect' used when opening the calendar. Defaults to Effect.Appear if scriptaculous is available. Otherwise it is Element.show
closeeffect
Defines the 'Effect' used when closing the calendar. Defaults to Effect.Fade if scriptaculous is available. Otherwise it is Element.hide
exactweeks
Used to determine whether the calendar should show the 'exact' number of weeks in a month. By default, the calendar shows 6 weeks which will give you a nice, consistent view. However, if you want the control to show a variable number of weeks based on the true length of the month, set this to true. Defaults to false
dayheadlength
How many characters to use for the days of the week. Defaults to 2 (ex. Mo = Monday)
weekdaystart
Day of the week to start the calendar. Numeric, defaults to 0 (Sunday).
planner
Used only when you are going to call the mini-planner add-on (see the planner documentation).
tabular
Tells the control to draw with tables or divs. true means use tables. false means use divs. Defaults to false.
year, month, day
Regular calendar fields. The initial value for the calendar defaults to the current date. You can override elements of the date individually.
formatPadding
Date format defaults padding enabled (two digit length). To disable format padding, set this variable to false.
Date.formatPadding = false;Scal is designed to be a basic javascript calendar, a date picker. However, if you have a calendar it is only inevitable that someone will want to turn it into a planner. Adding a mini-planner to scal was fairly simple, just add a dictionary to hold all the planner events and then load the relevant events when a particular month is displayed.
In version v0.1, the planner was part of the main scal.js file. For the sake of performance and extensibility, v0.2 separates the planner from the the main scal.js file. The planner is now in its own js: scalplanner.js. In addition to the structural changes, v0.2 planner events are far more robust and flexible than v0.1.
Calling up the planner under v0.2 is simple. Just include scalplanner.js after scal.js in your html.
<script type="text/javascript" src="/javascripts/prototype.js"> </script>
<script type="text/javascript" src="/javascripts/scal.js"> </script>
<script type="text/javascript" src="/javascripts/scalplanner.js"> </script>When you instantiate an scal instance pass along a planner array with the rest of the options:
var myplanner = [
{ period: 'December 17, 2007', label: ["Mom's Birthday", "Julie's Birthday"], cls: 'celebration'},
{ period: 'November 10, 2007', label: ['renew license','pickup mom'], cls: 'reminders'},
{ period: $A($R(new Date('November 5, 2007'),new Date('November 9, 2007'))), label: ['dragon days'], cls: 'dragons'}
];
var samplecal = new scal('samplecal',updateyear,{titleformat:'mmmm yyyy',closebutton:'X',dayheadlength:2,weekdaystart:0,planner: myplanner});For more on event styles, see planner_test.html in the scal distribution. planner_test contains the css styles for 'celebration', 'reminders', and 'dragons'.
A live example of the planner is also available here on the documentation site.
The example above creates an scal instance with a few events. But what if you don't have events to fill in right away?
Simple enough, just pass in an empty array with options.planner, like so:
samplecal = new scal('samplecal',updateyear,{titleformat:'mmmm yyyy',closebutton:'X',dayheadlength:2,weekdaystart:0,planner: []});Adds an event to the planner with a class of dayboxevent.
iscal is the only included style that has a dayboxevent style
year,month,day should be self-explanatory. Val is the text that will appear on said date.
cls is the css class that will be applied to the new planner event (along with the dayboxevent class).
Returns the element that the planner events were added to.
samplecal.setPlannerValue(2007,11,29,"Remove dragons!", 'dragonremove');Changes the value of a particular cell on the calendar grid.
week and day map to row and column as opposed to a true javascript Date. Val is the text that will appear on said date.
cls is the css class that will be applied to the new planner event (along with the dayboxevent class).
Returns the element that the planner events were added to.
samplecal.updateDayValue(2,1, "Pepper Fest!", 'pepperfest');Returns an array of all planner event elements for a specified date.
Date object of the the specified element to retrieve.
None
An array of planner event elements for the specified date
var evts = samplecal.getElementsByDate(new Date('December 17, 2007'));Retrieves the planner event elements for the specified week.
Number of the week to retrieve planner event elements for.
None
AOA- Array of arrays containing the planner event elements for days of the given week
// will return an array containing the dates from November 5, 2007 to November 9, 2007
samplecal.getDatesByEvent('dragon days');Removes the planner events elements for a specified date.
By defaults, it removes all planner events elements for the specified date.
Date object of the the specified planner event elements to remove.
index paramter is the index of the planner event for the date to remove from.
If the index parameter is given, only one planner event element will be removed.
Returns false if a planner date is not set for the given date.
// remove Mom's birthday (sorry Mom)
samplecal.removeEventsByDate(new Date('December 17, 2007'), 0);
// remove all events for December 17, 2007
samplecal.removeEventsByDate(new Date('December 17, 2007'));Returns an array of objects for each event for the current month.
None
When given a parameter of true value, this method will only return the events for the current month. The default behavior is to return all events that are displayed, and not just the current month's events.
Array of planner event objects
Each object in the returned array has the following properties:
// get all events for the current view
samplecal.getCurrentEvents();
// get all events for the current month
samplecal.getCurrentEvents(true);Returns an array of all planner events set for the given planner date.
Date object of the the specified planner event elements to retrieve.
None
Array of planner event label string that are set for the given planner date.
// will return ["Mom's Birthday", "Julie's Birthday"]
samplecal.getEventsByDate(new Date('December 17, 2007'));Returns an array of dates that the given planner event falls on.
The label string of the planner event to retrieve the date objects for.
None
Array of date objects that the give planner events falls on.
// will return an array containing the dates from November 5, 2007 to November 9, 2007
samplecal.getDatesByEvent('dragon days');Retrieves the selected planner day event elements for the current calendar.
None
Array of planner event elements for the selected day.
var selectedEvents = samplecal.getSelectedEvents();Retrieves the today planner day event elements for the current calendar.
None
Array of planner event elements for today.
var todayEvents = samplecal.getTodaysEvents();This demo is a modified version of the code in scaltester_new.html.
Included Styles: (click names to change style of the sample calendar below)
To use it, just click the calendar icon to get a pop-up calendar. You can download the full archive (styles, sample code, etc) here - floating-calendar.zip
This demo is a modified version of the code in slick_test.html.
A functional test of the oncalchange function. The SELECT for month, day, and year are updated when you click on the calendar. In addition, if you change dates using the SELECT elements, the calendar changes accordingly. (demo uses the "slick" scal skin, though any of the styles will work)
This demo is a modified version of the code in planner_test.html. To learn more about the planner, read the online documentation.
Get the calendar on the screen!
Under v0.1 you needed to build and get the calendar and then show it. All of those methods have been replaced by simply instantiating the calendar class.
var Cal = new scal('samplecal',updateelement,options);
If the samplecal element is visible, your calendar will be visible. If it is hidden, you need to toggleCalendar to show it. Just that simple. This method also makes it possible to show multiple calendars at the same time which was a bit dicey under v0.1.
Calendar elements
Many helper functions have been provided in order to ease the retrieval of specific calendar elements.
However, they are those few times when you have to get dirty.
Here is a map of the class formats given throughout scal's elements(every bulleted item is a class name):
calheader
- the container element of the calendar controls
calcontrol
- all calheader elements have this base class with the exception of the calendar title
calprevmonth
- element for the previous month control
calnextmonth
- element for the next month control
calprevyear
- element for the previous year control
calnextyear
- element for the next year control
caltitle
- element for the calendar title
calclose
- element for the close control
cal_wrapper
- the container element for all the calendar elements
weekbox
- the default class for the element that contains a weeks day elements
weekboxname
- the class of the elements indicating the day of the week at the top of the calendar
cal_week_#{WEEKNUMBER}
WEEKNUMBER - the digit that indicates the week number that it corresponds to for the given calendar
var firstWeek = $('samplescal').select('.cal_week_0');daybox
- every day element in the scal structure has this default class
general classes given dependent upon day how the day falls in the current calendar:
dayboxname
- the dayboxes in the weekboxname element have this default class, and individual class formats of:
cal_day_name_#{DAYNUMBER}
DAYNUMBER - the digit that indicates the day daynumber that it corresponds to for the given week
var sundayIndicator = $('samplecal').select('.weekboxname .cal_day_name_0');
var allIndicators = $('samplecal').select('.weekboxname .dayboxname');daybox#{DAYNAME}
DAYNAME - day name as defined in Date.prototype.daynames
var allSundays = $('samplecal').select('.weekbox .dayboxsunday');cal_day_#{WEEKNUMBER}_#{DAYNUMBER}
WEEKNUMBER - the digit that indicates the week number that it corresponds to for the given calendar
DAYNUMBER - the digit that indicates the day daynumber that it corresponds to for the given week
var firstSunday = $('samplecal').select('.weekbox .cal_day_1_0');dayboxdate
- child element of daybox, container of the day number value
dayboxvalue
- child element of daybox, container of the
planner event elements
Language Translation Support
The language can easily be changed prior to creating the instance of scal.
Prior to initiating scal:
Object.extend(Date.prototype, {
monthnames: ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"],
daynames: ["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"]
});