FullCalendar $('td.fc-day').mouseover sometimes get wrong date on small month calendar

StackOverflow https://stackoverflow.com/questions/22494628

  •  17-06-2023
  •  | 
  •  

Question

To implement tooltips for my very small month calendar using fullCalendar, I used the following code to capture the mouse cursor entering a day on the calendar, and log to the console the date using data-date attribute for the fc-day class:

$('td.fc-day').mouseover(function () {
  var strDate = $(this).data('date');
  console.log(strDate);
});

As I move the cursor thru a date cell, the reported date in the log window consistently changes to the date one week prior to the date I'm on, when I'm clearly still in the same cell. The position in is the cell where the reported date is wrong is in the left middle.

When I make the calendar larger, I don't have the problem, only when its quite small (200px in width).

I get the same problem with dayClick

Here is the code boiled down:

$('#calendar').fullCalendar({
    header: false,
    aspectRatio: 1.5,
    weekMode: 'liquid',
    month: 7,
    year: 2013,
    dayClick: function (objDate, allDay, jsEvent, view) {
        var strDate = (objDate.getMonth() / 1 + 1) + '/' + objDate.getDate() + '/' + objDate.getFullYear();
        console.log(strDate);
    }
});
$('td.fc-day').mouseover(function () {
    var strDate = $(this).data('date');
    console.log(strDate);
});

<table>
    <tr>
        <td width="200px">
            <div id='calendar' style="font-size:small; cursor:default"></div>
        </td>
    </tr>
</table>

There is a jsFiddle example.

You need to have a console window open to view the 'output'.

Was it helpful?

Solution 2

Here is the solution I eventually used:

$('.fc-day-number').mouseover(function () {
    var sel = $(this).closest('.fc-day');
    var strDate_yyyy_mm_dd = sel.data('date');
    m_strDate_yyyy_mm_dd = strDate_yyyy_mm_dd;
    if (typeof strDate_yyyy_mm_dd === 'undefined') return;
    var position = sel.position();
    var offset = sel.offset();
    var objDate = new Date(strDate_yyyy_mm_dd.substring(0, 4),   strDate_yyyy_mm_dd.substr(5, 2) - 1, strDate_yyyy_mm_dd.substr(8,2))
    displayEventPopup(objDate, position, offset);
  });
  $('.fc-day').mouseover(function () {
    var strDate_yyyy_mm_dd = $(this).data('date');
    if (strDate_yyyy_mm_dd != m_strDate_yyyy_mm_dd)
        $('#calTooltip').hide();
  });

I only start showing the tooltip if hovering over the numbers (i.e. fc-day-number class), because the original problem still exists - hovering over the fc-day div still sometimes gives you the wrong date, but hovering over fc-day-number and getting the closest fc-day always gives you the right date. I hide my tooltips if I hover over an fc-day that has a different day than the last day that I display, and wait for the user to hover over another fc-day-number before showing the next tooltip. If the calendar were bigger, this would be a problem, but then again if the calendar were bigger, I wouldn't get the problem with fc-day giving the wrong date.

OTHER TIPS

I think it happens because you're not really hovering over a 'fc-day'. There's also another element on top of every day cell - a 'fc-day-number'. So basically you just don't have any mouseover action for this element. Try using this :

$('td.fc-day').mouseover(function() {
    var strDate = $(this).data('date');
    $(this).addClass('fc-highlight');
});
$('td.fc-day-number').mouseover(function() {
    var strDate = $(this).data('date');
    $("td.fc-day").filter("[data-date='" + strDate + "']").addClass('fc-highlight');
});
$('td.fc-day').mouseout(function() {
    $(this).removeClass('fc-highlight');
})
$('td.fc-day-number').mouseout(function() {
    var strDate = $(this).data('date');
    $("td.fc-day").filter("[data-date='" + strDate + "']").removeClass('fc-highlight');
})

Hope it helps, Andrey

I was just looking at the same problem, and I had some issues with the solutions presented here, namely that some areas of each day cell would not trigger the mouse over. (There's a small gap between the fc-day-number and fc-day, and bigger gaps where there are events in a different cell on the same row).

I came up with a different solution by adapting some code on this issue requesting this feature: https://github.com/fullcalendar/fullcalendar/issues/2718

This solution seems to be more robust without gaps when the mouse is within a day cell, and only triggers 1 enter and 1 exit event as expected as the mouse moves over a cell

let currentDay = undefined;

let dayFromCoordinates = (x, y) => {
    const days = $('.fc-day');
    for (let i = 0; i < days.length; i++) {
        const day = $(days[i]);
        const offset = day.offset();
        const width  = day.width();
        const height = day.height();
        const mouseOverDay = (
            x >= offset.left && x <= offset.left + width &&
            y >= offset.top && y <= offset.top + height
        );
        if (mouseOverDay) {
            return day;
        }
    }
};

$('.fc-view-container').mousemove(mouseEvent => {
    const newDay = dayFromCoordinates(mouseEvent.pageX, mouseEvent.pageY);
    if (currentDay && !currentDay.is(newDay)) {
        // remove styling/html from current day
    }
    if (newDay && !newDay.is(currentDay)) {
        // add styling/html to new day
    }
    currentDay = newDay;
});

Note that this code assumes there's only 1 calendar in the DOM

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top