События в jQuery UI Datepicker с источником данных json - PullRequest
4 голосов
/ 25 октября 2010

Я хочу отображать события в DateUpicker пользовательского интерфейса jQuery. Я хочу, чтобы дни с событиями были стилизованы иначе, чем дни, в которых нет событий, и я хочу отображать настраиваемую подсказку с подробными сведениями о событии при наведении указателя на даты с событиями.

Решение вопроса " jQuery UI Datepicker с jQuery tipsy " очень близко, но не работает с конфигурацией Datepicker, которую я использую. Я использую опцию "showOtherMonths", и она отключает вычисление ссылки на дату.

Данные о событии доступны в http://mydomain.com/events.json

Макет того, что я хочу:

Datepicker with events

Это код, который я использую для создания Datepicker:

$('#dateDiv').datepicker({
    altField: '#dateInput',
    altFormat: 'yy-mm-dd',
    dateFormat: 'yy-mm-dd',
    firstDay: '1',
    showOtherMonths: 'true',
});

В настоящее время я не беспокоюсь о CSS-части решения, только о javascript-части. Как сделать, чтобы моя настраиваемая всплывающая подсказка отображалась при наведении на них даты с прикрепленными к ним событиями? И как мне прикрепить события (события календаря, а не события Javascript / DOM;))?

1 Ответ

1 голос
/ 27 октября 2010

Это не очень элегантное решение, но, похоже, оно работает. Может кто-нибудь придумать что-нибудь получше?

РЕДАКТИРОВАТЬ: Вот jsFiddle с работающим кодом: http://jsfiddle.net/Tobbe/JrkSN/3/

EDIT2: Это работает, пока я не нажму на дату, тогда все события исчезнут, потому что обратный вызов beforeShowDay в этом случае не вызывается. Как мне обойти это?

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];
}
...