Created
March 1, 2013 21:11
-
-
Save tilomitra/5067803 to your computer and use it in GitHub Desktop.
A custom calendar that lets you select multiple calendar without clicking on any keyboard keys
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title></title> | |
</head> | |
<body class="yui3-skin-sam"> | |
<div id="myCal"></div> | |
<script src="http://yui.yahooapis.com/3.8.1/build/yui/yui-debug.js"></script> | |
<script> | |
YUI({ | |
filter: 'raw' | |
}).use('calendar', 'widget', function (Y) { | |
var getCN = Y.ClassNameManager.getClassName, | |
CALENDAR = 'calendar', | |
KEY_DOWN = 40, | |
KEY_UP = 38, | |
KEY_LEFT = 37, | |
KEY_RIGHT = 39, | |
KEY_ENTER = 13, | |
KEY_SPACE = 32, | |
CAL_DAY_SELECTED = getCN(CALENDAR, 'day-selected'), | |
CAL_DAY_HILITED = getCN(CALENDAR, 'day-highlighted'), | |
CAL_DAY = getCN(CALENDAR, 'day'), | |
CAL_PREVMONTH_DAY = getCN(CALENDAR, 'prevmonth-day'), | |
CAL_NEXTMONTH_DAY = getCN(CALENDAR, 'nextmonth-day'), | |
CAL_GRID = getCN(CALENDAR, 'grid'), | |
ydate = Y.DataType.Date, | |
CAL_PANE = getCN(CALENDAR, 'pane'), | |
os = Y.UA.os; | |
function CustomCalendar() { | |
CustomCalendar.CSS_PREFIX = 'yui3'; | |
CustomCalendar.superclass.constructor.apply ( this, arguments ); | |
} | |
Y.CustomCalendar = Y.extend(CustomCalendar, Y.Calendar, { | |
_clickCalendar : function (ev) { | |
var clickedCell = ev.currentTarget, | |
clickedCellIsDay = clickedCell.hasClass(CAL_DAY) && | |
!clickedCell.hasClass(CAL_PREVMONTH_DAY) && | |
!clickedCell.hasClass(CAL_NEXTMONTH_DAY), | |
clickedCellIsSelected = clickedCell.hasClass(CAL_DAY_SELECTED), | |
selectedDate, | |
initialSelectedDate = false; | |
switch (this.get("selectionMode")) { | |
case("single"): | |
if (clickedCellIsDay) { | |
if (!clickedCellIsSelected) { | |
this._clearSelection(true); | |
this._addDateToSelection(this._nodeToDate(clickedCell)); | |
} | |
} | |
break; | |
case("multiple-sticky"): | |
if (clickedCellIsDay) { | |
if (clickedCellIsSelected) { | |
this._removeDateFromSelection(this._nodeToDate(clickedCell)); | |
} else { | |
this._addDateToSelection(this._nodeToDate(clickedCell)); | |
} | |
} | |
break; | |
case("multiple"): | |
if (clickedCellIsDay) { | |
if (!ev.metaKey && !ev.ctrlKey && !ev.shiftKey) { | |
if (this._lastSelectedDate && !clickedCellIsSelected) { | |
//a previous date has been selected | |
selectedDate = this._nodeToDate(clickedCell); | |
this._addDateRangeToSelection(selectedDate, this._lastSelectedDate); | |
this._lastSelectedDate = selectedDate; | |
} | |
else if (clickedCellIsSelected) { | |
this._clearSelection(true); | |
this._lastSelectedDate = null; | |
} | |
else { | |
this._clearSelection(true); | |
this._lastSelectedDate = this._nodeToDate(clickedCell); | |
this._addDateToSelection(this._lastSelectedDate); | |
initialSelectedDate = this._lastSelectedDate; | |
} | |
} else if (((os === 'macintosh' && ev.metaKey) || (os !== 'macintosh' && ev.ctrlKey)) && !ev.shiftKey) { | |
if (clickedCellIsSelected) { | |
this._removeDateFromSelection(this._nodeToDate(clickedCell)); | |
this._lastSelectedDate = null; | |
} else { | |
this._lastSelectedDate = this._nodeToDate(clickedCell); | |
this._addDateToSelection(this._lastSelectedDate); | |
} | |
} else if (((os === 'macintosh' && ev.metaKey) || (os !== 'macintosh' && ev.ctrlKey)) && ev.shiftKey) { | |
if (this._lastSelectedDate) { | |
selectedDate = this._nodeToDate(clickedCell); | |
this._addDateRangeToSelection(selectedDate, this._lastSelectedDate); | |
this._lastSelectedDate = selectedDate; | |
} else { | |
this._lastSelectedDate = this._nodeToDate(clickedCell); | |
this._addDateToSelection(this._lastSelectedDate); | |
} | |
} else if (!ev.shiftKey && this._lastSelectedDate) { | |
if (this._lastSelectedDate) { | |
selectedDate = this._nodeToDate(clickedCell); | |
this._clearSelection(true); | |
this._addDateRangeToSelection(selectedDate, this._lastSelectedDate); | |
this._lastSelectedDate = selectedDate; | |
} else { | |
this._clearSelection(true); | |
this._lastSelectedDate = this._nodeToDate(clickedCell); | |
this._addDateToSelection(this._lastSelectedDate); | |
} | |
} | |
} | |
break; | |
} | |
if (clickedCellIsDay) { | |
/** | |
* Fired when a specific date cell in the calendar is clicked. The event carries a | |
* payload which includes a `cell` property corresponding to the node of the actual | |
* date cell, and a `date` property, with the `Date` that was clicked. | |
* | |
* @event dateClick | |
*/ | |
this.fire("dateClick", {cell: clickedCell, date: this._nodeToDate(clickedCell)}); | |
} else if (clickedCell.hasClass(CAL_PREVMONTH_DAY)) { | |
/** | |
* Fired when any of the previous month's days displayed before the calendar grid | |
* are clicked. | |
* | |
* @event prevMonthClick | |
*/ | |
this.fire("prevMonthClick"); | |
} else if (clickedCell.hasClass(CAL_NEXTMONTH_DAY)) { | |
/** | |
* Fired when any of the next month's days displayed after the calendar grid | |
* are clicked. | |
* | |
* @event nextMonthClick | |
*/ | |
this.fire("nextMonthClick"); | |
} | |
} | |
}); | |
var calendar = new Y.CustomCalendar({ | |
contentBox: "#myCal", | |
width: "700px", | |
showPrevMonth: true, | |
showNextMonth: true, | |
selectionMode: 'multiple' | |
}).render(); | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A simple
Y.extend()
does the trick. Minor modifications toY.Calendar
's_clickCalendar
method.