jQuery UI datepicker
There are a lot a options, more than I think a widget ought to have. I may want to simplify things in the future, and move some of these options to subclasses.
boxbuttonscalendarschangeMonthchangeYear'class'currentdurationfilterhidehideOnOutsideClickhidetabsl10npositionrepositionshowstructuretabtransitiontriggerThese are the meat of the widget.
calendars{Array (String|Object|Array)}
Array of calendars to display. Each item is a localization object or string, or an array of those that are to be joined together with $.extend to create the final localization object, which is then $.extended with the l10n option, and the default $.bililite.flexcal.prototype.options.l10n.
See the complete documentation on localization objects.
Of note, the dateFormat for the first calendar (calendars[0]) will be used to read and write to the attached input element.
['en']
['en', 'fr']: two calendar tabs, English and French, with their default names displayed('English' for the first, 'flexcal' for the second if we are using the jQuery UI datepicker localization, since it does not define a name).
['en', ['fr', 'French'] ]: two calendar tabs, English and French, with the second name set to 'French' (if a string does not correspond to a localization, it is assumed to be a calendar name).
[ ['en', {dateFormat: 'yyyy-mm-dd', dayNamesMin: ['S','M','T','W','T','F','S']} ]]: one calendar, using the ISO notation for dates and one-letter abbreviations for days of the week.
l10n{Object}
The default localization, to be used if any of the elements of calendars are missing. Again, see the localization documentation for the meaning of these items.
When used with option to get the value, returns the actual current localization object, not the default object that was passed in.
{
name: 'flexcal',
calendar: $.bililite.flexcal.calendars.gregorian,
monthNames: ['January','February','March','April','May','June',
'July','August','September','October','November','December'],
monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'],
prevText: 'Previous',
nextText: 'Next',
isRTL: false,
firstDay: 0,
years: function(n) {return n.toString()},
fromYears: undefined,
dates: function(n) {return n.toString()},
fromDates: undefined,
dateFormat: 'm/d/yyyy'
}
See the localization documentation.
See current for use of l10n with option; i.e. $(element).flexcal('option', 'l10n').
current{Date|String}
The date to display on the calendar. The attached element's value will override this when the calendar is first shown, if it represents a valid date. If undefined, use today's date. Strings are interpreted according to calendars[0].dateFormat.
undefined
$(element).flexcal({current: new Date('Dec 25 2015')}): start the calendar on Christmas.
Live updating (see the set event and format method):
$(element).flexcal('option', 'current', new Date('Jan 01 2015')): change the displayed date on an existing calendar. Note that it does not set the date in the text box; use commit for that.
var d = $(element).flexcal('option', 'current'): get the displayed date and listen to the set event to keep the text updated:
filter{undefined|Function}
Function to filter dates. Function is of the form f(d) where d is a Date object; it should return true to enable that date or false to disable it. this is set to the <a> element that contains the date number. That allows filter to modify the appearance of the calendar.
undefined
function(d){ return d.getDay() != 0 && d.getDay() != 6; }: disable weekends.
function(d){
// is it Thursday and is it an even numbered week since the epoch?
if (d.getDay() == 4 && Math.floor(d.getTime()/(1000*60*60*24*7)) %2 == 0){
$(this).css('border', '2px solid purple'); // put a nice border on it
}
return true; // don't disable anything
} highlight every other Thursday (it's payday!).
'class'{undefined|String}
Class name[s] to be applied to the calendar container. One class is defined in the flexcal.css file: fontawesome uses FontAwesome icons instead of the jQuery UI images for the next/previous chevrons.
undefined
hidetabs{true|false|'conditional'}
Whether to show the tab bar to select calendars. true to always show, false to never show, and 'conditional' to only show it if there is more than one calendar (calendars.length > 1).
'conditional'
position{'tl'|'lt|'bl'|'lb'|'tr'|'rt'|'br'|'rb'|Object}
String that indicates where to position the calendar
relative to the textbox. 'tl' means on top of the input box, aligned to the left edge;
'lt' means on the left of the input box aligned to the top edge; similarly 'b' for bottom
and 'r' for right. If an object is passed, it will be passed to position (after $.extending with the defaults).
For an inline calendar (using the box option) this option is ignored. Just position the box where you want it.
'tl', which means:
{
my: 'left bottom',
at: 'left top',
of: this.element, // the input element that flexcal was called on
collision: 'none',
using: function(to) { $(this).stop(true, false).animate(to) } // animate the repositioning
}
tab{Number}
Index of the calendar to show.
0
$(element).flexcal({calendars: ['First', 'Second'], tab: 1}): the calendar 'Second' should be active when initially shown.
$(element).flexcal('option', 'tab', 1): switch to the second calendar. See the example for hidetabs.
duration{String|Number|Array}
Argument[s] to pass to hide and show. If not an array, turned into and array (as [duration]) so Function.apply can be used.
'slow' (I like drama)
0: just show and hide with no animation.
['clip', {direction: 'vertical'}, 'slow']: use jQuery UI effects.
hide{Function}
Called to hide the calendar; this is set to the calendar container (box). The duration is interpreted as the argument[s] to the function. Called basically as this.options.hide.apply(this.options.box, this.options.duration).
Usually if you want some special effect, you can leave this alone and just change duration.
$.fn.hide
$.fn.slideUp: hide the calendar with jQuery's slideUp function.
function () {
this.find('table a').css('background', 'green');
$.fn.hide.apply(this, arguments);
} turn the calendar days green before hiding (no, I don't know why you would want to do that).
hideOnOutsideClick{true|false}
If true, attaches a click event handler to automatically hide the calendar if the mouse is clicked outside the calendar or the attached textbox. If the box option is set, then this is an inline calendar, and hideOnOutsideClick is always set to false during initialization.
true (but reset to false for inline calendars)
See the hide method.
reposition{true|false}
If true, repositions the calendar with every transition; useful if the calendar is above the text element and transitions to months with more weeks obscures the box. Some may find the constant repositioning distracting.
For an inline calendar (using the box option) this option is ignored. If the calendar height changes are distracting, give the box and absolute height.
true
See the second example for transition.
show{Function}
Called to show the calendar; this is set to the calendar container (box). The duration is interpreted as the argument[s] to the function. Called basically as this.options.show.apply(this.options.box, this.options.duration).
Usually if you want some special effect, you can leave this alone and just change duration.
$.fn.show
See hide.
transition{Function}
Function to animate the transition between months or between calendars. Arguments are oldCalendar, the <div> that contains the calendar to hide, newCalendar, the <div> that contains the calendar to show, and rev, a Boolean that is true if the animation should show a "reverse" transition, going to a previous month.
function(oldCalendar, newCalendar, rev){
oldCalendar.hide();
newCalendar.show();
}
See the Transition page.
Sliding transition
Slow transition. Note that any arbitrary value can be passed to the widget constructor and retrieved with option.
box{undefined|jQuery object|DOM object|String}
The element to contain the calendar. If undefined, then the a new, absolutely-positioned <div> is created and the calendar is a pop-up calendar. Otherwise, the calendar is contained in $(this.options.box). This container should shrink to fit its contents, so it should use display: inline-block or float: left/right or other techniques.
undefined
For inline calendars, see the 'class' and hidetabs examples.
buttons{Array (String)}
List of buttons to be added to the button pane at the bottom of the calendar. See the full documentation.
[]
changeMonth{Boolean}
Set true to insert a drop-down menu of months in the calendar header. The name comes from the equivalent option in jQuery UI datepicker.
false
changeYear{Boolean}
Set true to insert a drop-down menu of years in the calendar header. The name comes from the equivalent option in jQuery UI datepicker.
false
See changeMonth.
trigger{'self'|null|String|jQuery object|DOM element}
Element(s) to use as the trigger to show the popup. basically uses the code
if (trigger == 'self') trigger = self.element;
if (trigger) $(trigger).click(self.show)
'self'
structure{String}
HTML of the underlying structure of the calendar..
<div class="ui-tabs ui-widget ui-widget-content ui-corner-all ui-datepicker ui-flexcal ui-helper-clearfix">
<ul dir=auto class="ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"></ul>
<div class="ui-flexcal-container">
<div class="ui-flexcal-pane"></div>
<div class="ui-flexcal-pane"></div>
</div>
<div dir=auto class="ui-datepicker-buttonpane ui-widget-content"></div>
</div>
The two <div>s with class="ui-flexcal-pane" will contain the calendar; one is shown and the other is hidden to allow animated transitions.
The <div> with class="ui-datepicker-buttonpane" is generally invisible but is available for adding buttons like a "Today" button"; see the buttons option.
As with all widgets, event handlers can be attached with callbacks when flexcal is created: $(element).flexcal({ shown: function() {console.log('calendar shown')} }), or with real event attachment: $(element).on('flexcalshown', function() {console.log('calendar shown')}). Note the difference in naming.
Note that the naming here is inconsistent. Events should be named as the verb in the present (click, submit), but I already have options named show and hide so I named the corresponding events shown and hidden.
commitEvent handler: function (Event e, Date d).
Triggered when a date is committed (clicked on and copied to the attached text box). d is the new date.
See format.
createhiddenTriggered after the calendar is hidden. The event is queued with the animation, so it is triggered after the animation is complete.
See hide.
setEvent handler: function (Event e, Date d, Date oldd).
Triggered when the focused date changes (when changing months, or using the arrow keys). This is the "current" date. Note that this is different from the commit event, which happens with a click or enter key. The committed date is reflected in the attached text box, and gets the ui-state-active class. It may not be showing on the current calendar. The current date gets the ui-state-focus class and determines which month is showing.
See current.
setL10nEvent handler: function (Event e, Object l10n).
Triggered when the localization object is changed; usually when a tab is clicked but can be from programmatically changing the calendars.
See current.
shownTriggered after the calendar is shown. The event is queued with the animation, so it is triggered after the animation is complete.
See hide.
Methods listed here can be called in two ways, as with any jQuery widget. The usual way is with $(element).flexcal(methodname, arguments ...). You can also get the widget instance and call the method directly: var instance = $(element).flexcal('instance'); instance.methodname(arguments);.
The usual widget methods are available, option to set and get options, widget to get the associated element (for flexcal, the <input> element), instance to get the widget instance itself, and destroy to remove the widget from the element. enable and disable are not implemented.
formatfunction (Date d, [String format], [Object l10n])
With only one argument, returns a string with d formatted according to the dateFormat field of the first calendar (options.calendars[0].dateFormat). Otherwise, uses the localization object specified in l10n, with the default being the localization object of the currently visible calendar (what is returned by the l10n option. If format is not specified, uses l10n.dateFormat.
Uses $.bililite.flexcal.format. If d is an invalid Date, the result is undefined (but probably involves a lot of 'NaN's).
localizefunction (String s, [Object l10n])
Returns a string localized to the given localization object, l10n (defaults to the currently visible calendar). Uses $.bililite.flexcal.localize to return l10n[s+'Text'], or a blank string if that is undefined. For example, $(...).flexcal('localize', 'next') returns the title text for the "Next" button, nextText, and $(...).flexcal('localize', 'today') returns the text for the "Today" button. Mostly used for localizing buttons; see the examples there.
See the localization documentation for more information on localization objects.
parsefunction (String s, [String format], [Object l10n])
The inverse of format. With only one argument, returns date parsed from s formatted according to the dateFormat field of the first calendar (options.calendars[0].dateFormat). Otherwise, uses the localization object specified in l10n, with the default being the localization object of the currently visible calendar (what is returned by the l10n option. If format is not specified, uses l10n.dateFormat.
Uses $.bililite.flexcal.parse.
If s does not represent a valid date, then parse returns an invalid Date; test it with isNaN(parseDate.getTime()).
Note that no matter what dateFormat is, ISO 8601 dates ('yyyy-mm-dd') are always parsed, since that is used internally.
widgetInherited from $.Widget. Returns the jQuery set containing the <div> containing the calendar.
$(element).flexcal('widget').draggable(): Using the value of box to get the calendar container to make it draggable.
commitfunction (Date d)
Sets the calendar and the attached text box to d, and triggers the commit event.
Note the difference to setting the current option, which only sets the visible date.
hideHide the calendar without setting the date (commit does that). Takes no parameters.
positionRestore the calendar to the position described by the position parameter. Does nothing for inline calendars.
showShows the calendar and sets the active date to the date represented by the value of the attached text box. Takes no parameters.
See hide.
Plus, setting the options with option changes the calendar on the fly (except for url and box, which are evaluated only at creation; if you need to reset the HTML or container of the calendar, destroy it and instantiate a new one). Thus, $('input.date').flexcal('option', 'current', '1/1/2011') sets the highlighted date (displaying the appropriate month).