Events in jQuery UI Datepicker with json data source
I want to display events in the jQuery UI Datepicker. I want the days that have events to be styled differently from days that don't have events, and I want to display a custom tooltip with the event details when hovering dates with events.
The solution to the question "jQuery UI Datepicker with jQuery tipsy" gets very close, but doesn't work with the Datepicker configuration I use. I use the "showOtherMonths" option, and it throws the date link calculation off.
The event data is available at http://mydomain.com/events.json
Mockup of what I want:
This is the code I use for creating the Datepicker:
$('#dateDiv').datepicker({
altField: '#dateInput',
altFormat: 'yy-mm-dd',
dateFormat: 'yy-mm-dd',
firstDay: '1',
showOtherMonths: 'true',
});
I'm not concerned about the CSS part of the solution at this time, just the javascript part. How do I make my custom tooltip appear when hovering the dates with events attached to them? And how do I attach the events (calendar events, not java开发者_如何学JAVAscript/DOM events ;) )?
This is not a very elegant solution, but it does seem to work. Can someone please come up with something better?
EDIT: Here's a jsFiddle with the code running: http://jsfiddle.net/Tobbe/JrkSN/3/
EDIT2: It works until I click on a date, then all the events disappears because the beforeShowDay
callback isn't called in that case. How do I work around that?
getEvents();
$(function() {
$('#dateDiv').datepicker({
altField: '#dateInput',
altFormat: 'yy-mm-dd',
dateFormat: 'yy-mm-dd',
firstDay: '1',
showOtherMonths: 'true',
beforeShowDay: beforeShowDay,
onChangeMonthYear: getEvents
});
});
var enqueuedDates = [];
var tryCounter = 0;
var events = [];
function getEvents() {
events = [];
enqueuedDates = [];
$.getJSON('events.json', function(json) {
events = json;
});
}
function beforeShowDay(date) {
enqueuedDates.push(new Date(date));
if (enqueuedDates.length == 35) {
processEnqueuedDates();
}
return [true, '', ''];
}
function processEnqueuedDates() {
if (!events || events.length === 0) {
tryCounter++;
if (tryCounter < 100) {
setTimeout(processEnqueuedDates, 10);
} else {
tryCounter = 0;
}
return;
}
tryCounter = 0;
for (var i = 0; i < enqueuedDates.length; ++i) {
var event = getEvent(events, enqueuedDates[i]);
if (event) {
var theDateCells = $('#dateDiv .ui-datepicker-calendar td');
var hideTimeoutID;
theDateCells.eq(i).addClass('eventPlanned').
bind('mouseenter', function(eventText) {
return function() {
if (hideTimeoutID) {
clearTimeout(hideTimeoutID);
hideTimeoutID = null;
}
var popup = $('#eventPopup');
if (popup.size() == 0) {
popup = $('<div></div>').attr('id', 'eventPopup');
$('body').append(popup);
}
var pos = $(this).offset();
popup.html('<p>' + eventText + '</p>').
css('left', pos.left + 5 + 'px').
css('top', (pos.top - popup.height() - 2) + 'px').
bind('mouseenter', function() {
clearTimeout(hideTimeoutID);
hideTimeoutID = null;
}).
bind('mouseleave', function() {
$(this).hide();
}).
show();
}
}(event.text)).
bind('mouseleave', function(eventObject) {
hideTimeoutID = setTimeout(function() {
$('#eventPopup').hide();
}, 200);
});
}
}
}
function getEvent(events, date) {
return events.filter(function(event, index, arr) {
return date - $.datepicker.parseDate('yy-mm-dd', event.date) === 0;
})[0];
}
精彩评论