data tables are going to need some work yet, but the other stuff seems to be working 100%
368 lines
13 KiB
HTML
368 lines
13 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
|
<title>Interval Selection Calendar</title>
|
|
|
|
<style type="text/css">
|
|
/*margin and padding on body element
|
|
can introduce errors in determining
|
|
element position and are not recommended;
|
|
we turn them off as a foundation for YUI
|
|
CSS treatments. */
|
|
body {
|
|
margin:0;
|
|
padding:0;
|
|
}
|
|
</style>
|
|
|
|
<link rel="stylesheet" type="text/css" href="../../build/fonts/fonts-min.css" />
|
|
<link rel="stylesheet" type="text/css" href="../../build/calendar/assets/skins/sam/calendar.css" />
|
|
<script type="text/javascript" src="../../build/yahoo-dom-event/yahoo-dom-event.js"></script>
|
|
<script type="text/javascript" src="../../build/calendar/calendar-min.js"></script>
|
|
|
|
|
|
<!--begin custom header content for this example-->
|
|
<style type="text/css">
|
|
#dates {
|
|
float:left;
|
|
border: 1px solid #000;
|
|
background-color: #ccc;
|
|
padding:10px;
|
|
margin:10px;
|
|
}
|
|
|
|
#dates p {
|
|
clear:both;
|
|
}
|
|
|
|
#dates label {
|
|
float:left;
|
|
display:block;
|
|
width:7em;
|
|
font-weight:bold;
|
|
}
|
|
</style>
|
|
|
|
<!--end custom header content for this example-->
|
|
|
|
</head>
|
|
|
|
<body class=" yui-skin-sam">
|
|
|
|
<cite class="byline">The <code>IntervalCalendar</code> class and example is based on the <a target="_blank" href="http://blogs.whardy.com/john/2008/05/27/interval-calendar-control/"><code>iCalendarGroup</code></a> class, graciously contributed to YUI by John Peloquin, of <a target="_blank" href="http://www.whardy.com/">W. Hardy Interactive, Inc.</a>.</cite>
|
|
|
|
<h1>Interval Selection Calendar</h1>
|
|
|
|
<div class="exampleIntro">
|
|
<p>The Calendar widget is commonly used to select pairs of dates, representing the start and end dates of an interval, for example flight departure and return dates, or hotel check-in and check-out dates.</p>
|
|
|
|
<p>This example defines a custom <code>IntervalCalendar</code> class, based on CalendarGroup, which is designed specifically for this use case.</p>
|
|
|
|
</div>
|
|
|
|
<!--BEGIN SOURCE CODE FOR EXAMPLE =============================== -->
|
|
|
|
<div id="cal1Container"></div>
|
|
<div id="dates">
|
|
<p><label for="in">Check In:</label><input type="text" name="in" id="in"></p>
|
|
<p><label for="out">Check Out:</label><input type="text" name="out" id="out"></p>
|
|
</div>
|
|
|
|
<script type="text/javascript">
|
|
|
|
(function() {
|
|
|
|
/**
|
|
* IntervalCalendar is an extension of the CalendarGroup designed specifically
|
|
* for the selection of an interval of dates.
|
|
*
|
|
* @namespace YAHOO.example.calendar
|
|
* @module calendar
|
|
* @since 2.5.2
|
|
* @requires yahoo, dom, event, calendar
|
|
*/
|
|
|
|
/**
|
|
* IntervalCalendar is an extension of the CalendarGroup designed specifically
|
|
* for the selection of an interval of dates, as opposed to a single date or
|
|
* an arbitrary collection of dates.
|
|
* <p>
|
|
* <b>Note:</b> When using IntervalCalendar, dates should not be selected or
|
|
* deselected using the 'selected' configuration property or any of the
|
|
* CalendarGroup select/deselect methods. Doing so will corrupt the internal
|
|
* state of the control. Instead, use the provided methods setInterval and
|
|
* resetInterval.
|
|
* </p>
|
|
* <p>
|
|
* Similarly, when handling select/deselect/etc. events, do not use the
|
|
* dates passed in the arguments to attempt to keep track of the currently
|
|
* selected interval. Instead, use getInterval.
|
|
* </p>
|
|
*
|
|
* @namespace YAHOO.example.calendar
|
|
* @class IntervalCalendar
|
|
* @extends YAHOO.widget.CalendarGroup
|
|
* @constructor
|
|
* @param {String | HTMLElement} container The id of, or reference to, an HTML DIV element which will contain the control.
|
|
* @param {Object} cfg optional The initial configuration options for the control.
|
|
*/
|
|
function IntervalCalendar(container, cfg) {
|
|
/**
|
|
* The interval state, which counts the number of interval endpoints that have
|
|
* been selected (0 to 2).
|
|
*
|
|
* @private
|
|
* @type Number
|
|
*/
|
|
this._iState = 0;
|
|
|
|
// Must be a multi-select CalendarGroup
|
|
cfg = cfg || {};
|
|
cfg.multi_select = true;
|
|
|
|
// Call parent constructor
|
|
IntervalCalendar.superclass.constructor.call(this, container, cfg);
|
|
|
|
// Subscribe internal event handlers
|
|
this.beforeSelectEvent.subscribe(this._intervalOnBeforeSelect, this, true);
|
|
this.selectEvent.subscribe(this._intervalOnSelect, this, true);
|
|
this.beforeDeselectEvent.subscribe(this._intervalOnBeforeDeselect, this, true);
|
|
this.deselectEvent.subscribe(this._intervalOnDeselect, this, true);
|
|
}
|
|
|
|
/**
|
|
* Default configuration parameters.
|
|
*
|
|
* @property IntervalCalendar._DEFAULT_CONFIG
|
|
* @final
|
|
* @static
|
|
* @private
|
|
* @type Object
|
|
*/
|
|
IntervalCalendar._DEFAULT_CONFIG = YAHOO.widget.CalendarGroup._DEFAULT_CONFIG;
|
|
|
|
YAHOO.lang.extend(IntervalCalendar, YAHOO.widget.CalendarGroup, {
|
|
|
|
/**
|
|
* Returns a string representation of a date which takes into account
|
|
* relevant localization settings and is suitable for use with
|
|
* YAHOO.widget.CalendarGroup and YAHOO.widget.Calendar methods.
|
|
*
|
|
* @method _dateString
|
|
* @private
|
|
* @param {Date} d The JavaScript Date object of which to obtain a string representation.
|
|
* @return {String} The string representation of the JavaScript Date object.
|
|
*/
|
|
_dateString : function(d) {
|
|
var a = [];
|
|
a[this.cfg.getProperty(IntervalCalendar._DEFAULT_CONFIG.MDY_MONTH_POSITION.key)-1] = (d.getMonth() + 1);
|
|
a[this.cfg.getProperty(IntervalCalendar._DEFAULT_CONFIG.MDY_DAY_POSITION.key)-1] = d.getDate();
|
|
a[this.cfg.getProperty(IntervalCalendar._DEFAULT_CONFIG.MDY_YEAR_POSITION.key)-1] = d.getFullYear();
|
|
var s = this.cfg.getProperty(IntervalCalendar._DEFAULT_CONFIG.DATE_FIELD_DELIMITER.key);
|
|
return a.join(s);
|
|
},
|
|
|
|
/**
|
|
* Given a lower and upper date, returns a string representing the interval
|
|
* of dates between and including them, which takes into account relevant
|
|
* localization settings and is suitable for use with
|
|
* YAHOO.widget.CalendarGroup and YAHOO.widget.Calendar methods.
|
|
* <p>
|
|
* <b>Note:</b> No internal checking is done to ensure that the lower date
|
|
* is in fact less than or equal to the upper date.
|
|
* </p>
|
|
*
|
|
* @method _dateIntervalString
|
|
* @private
|
|
* @param {Date} l The lower date of the interval, as a JavaScript Date object.
|
|
* @param {Date} u The upper date of the interval, as a JavaScript Date object.
|
|
* @return {String} The string representing the interval of dates between and
|
|
* including the lower and upper dates.
|
|
*/
|
|
_dateIntervalString : function(l, u) {
|
|
var s = this.cfg.getProperty(IntervalCalendar._DEFAULT_CONFIG.DATE_RANGE_DELIMITER.key);
|
|
return (this._dateString(l)
|
|
+ s + this._dateString(u));
|
|
},
|
|
|
|
/**
|
|
* Returns the lower and upper dates of the currently selected interval, if an
|
|
* interval is selected.
|
|
*
|
|
* @method getInterval
|
|
* @return {Array} An empty array if no interval is selected; otherwise an array
|
|
* consisting of two JavaScript Date objects, the first being the
|
|
* lower date of the interval and the second being the upper date.
|
|
*/
|
|
getInterval : function() {
|
|
// Get selected dates
|
|
var dates = this.getSelectedDates();
|
|
if(dates.length > 0) {
|
|
// Return lower and upper date in array
|
|
var l = dates[0];
|
|
var u = dates[dates.length - 1];
|
|
return [l, u];
|
|
}
|
|
else {
|
|
// No dates selected, return empty array
|
|
return [];
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Sets the currently selected interval by specifying the lower and upper
|
|
* dates of the interval (in either order).
|
|
* <p>
|
|
* <b>Note:</b> The render method must be called after setting the interval
|
|
* for any changes to be seen.
|
|
* </p>
|
|
*
|
|
* @method setInterval
|
|
* @param {Date} d1 A JavaScript Date object.
|
|
* @param {Date} d2 A JavaScript Date object.
|
|
*/
|
|
setInterval : function(d1, d2) {
|
|
// Determine lower and upper dates
|
|
var b = (d1 <= d2);
|
|
var l = b ? d1 : d2;
|
|
var u = b ? d2 : d1;
|
|
// Update configuration
|
|
this.cfg.setProperty('selected', this._dateIntervalString(l, u), false);
|
|
this._iState = 2;
|
|
},
|
|
|
|
/**
|
|
* Resets the currently selected interval.
|
|
* <p>
|
|
* <b>Note:</b> The render method must be called after resetting the interval
|
|
* for any changes to be seen.
|
|
* </p>
|
|
*
|
|
* @method resetInterval
|
|
*/
|
|
resetInterval : function() {
|
|
// Update configuration
|
|
this.cfg.setProperty('selected', [], false);
|
|
this._iState = 0;
|
|
},
|
|
|
|
/**
|
|
* Handles beforeSelect event.
|
|
*
|
|
* @method _intervalOnBeforeSelect
|
|
* @private
|
|
*/
|
|
_intervalOnBeforeSelect : function(t,a,o) {
|
|
// Update interval state
|
|
this._iState = (this._iState + 1) % 3;
|
|
if(this._iState == 0) {
|
|
// If starting over with upcoming selection, first deselect all
|
|
this.deselectAll();
|
|
this._iState++;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Handles selectEvent event.
|
|
*
|
|
* @method _intervalOnSelect
|
|
* @private
|
|
*/
|
|
_intervalOnSelect : function(t,a,o) {
|
|
// Get selected dates
|
|
var dates = this.getSelectedDates();
|
|
if(dates.length > 1) {
|
|
/* If more than one date is selected, ensure that the entire interval
|
|
between and including them is selected */
|
|
var l = dates[0];
|
|
var u = dates[dates.length - 1];
|
|
this.cfg.setProperty('selected', this._dateIntervalString(l, u), false);
|
|
}
|
|
// Render changes
|
|
this.render();
|
|
},
|
|
|
|
/**
|
|
* Handles beforeDeselect event.
|
|
*
|
|
* @method _intervalOnBeforeDeselect
|
|
* @private
|
|
*/
|
|
_intervalOnBeforeDeselect : function(t,a,o) {
|
|
if(this._iState != 0) {
|
|
/* If part of an interval is already selected, then swallow up
|
|
this event because it is superfluous (see _intervalOnDeselect) */
|
|
return false;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Handles deselectEvent event.
|
|
*
|
|
* @method _intervalOnDeselect
|
|
* @private
|
|
*/
|
|
_intervalOnDeselect : function(t,a,o) {
|
|
if(this._iState != 0) {
|
|
// If part of an interval is already selected, then first deselect all
|
|
this._iState = 0;
|
|
this.deselectAll();
|
|
|
|
// Get individual date deselected and page containing it
|
|
var d = a[0];
|
|
var date = YAHOO.widget.DateMath.getDate(d[0], d[1] - 1, d[2]);
|
|
var page = this.getCalendarPage(date);
|
|
if(page) {
|
|
// Now (re)select the individual date
|
|
page.beforeSelectEvent.fire();
|
|
this.cfg.setProperty('selected', this._dateString(date), false);
|
|
page.selectEvent.fire([d]);
|
|
}
|
|
// Swallow up since we called deselectAll above
|
|
return false;
|
|
}
|
|
}
|
|
});
|
|
|
|
YAHOO.namespace("example.calendar");
|
|
YAHOO.example.calendar.IntervalCalendar = IntervalCalendar;
|
|
})();
|
|
|
|
YAHOO.util.Event.onDOMReady(function() {
|
|
|
|
var inTxt = YAHOO.util.Dom.get("in"),
|
|
outTxt = YAHOO.util.Dom.get("out"),
|
|
inDate, outDate, interval;
|
|
|
|
inTxt.value = "";
|
|
outTxt.value = "";
|
|
|
|
var cal = new YAHOO.example.calendar.IntervalCalendar("cal1Container", {pages:2});
|
|
|
|
cal.selectEvent.subscribe(function() {
|
|
interval = this.getInterval();
|
|
|
|
if (interval.length == 2) {
|
|
inDate = interval[0];
|
|
inTxt.value = (inDate.getMonth() + 1) + "/" + inDate.getDate() + "/" + inDate.getFullYear();
|
|
|
|
if (interval[0].getTime() != interval[1].getTime()) {
|
|
outDate = interval[1];
|
|
outTxt.value = (outDate.getMonth() + 1) + "/" + outDate.getDate() + "/" + outDate.getFullYear();
|
|
} else {
|
|
outTxt.value = "";
|
|
}
|
|
}
|
|
}, cal, true);
|
|
|
|
cal.render();
|
|
});
|
|
</script>
|
|
|
|
<div style="clear:both" ></div>
|
|
|
|
<!--END SOURCE CODE FOR EXAMPLE =============================== -->
|
|
|
|
</body>
|
|
</html>
|