Reputation: 14440
I'm struggling to retrieve the day clicked when clicking on a multi-days (period) event (eventClick).
Whe clicking on the background cell, it's easy :
function dayClick(date, jsEvent, view) {
//todo: store related day
$scope.selectedDay = date;
}
But when clicking on an event (which is on a period of days), I can't retrieve which day exactly the user was on. (I need to perform a different action depending on the background day) :
function alertEventOnClick(event, jsEvent, view) {
// "event" stores only start and end date without any reference to the current day
// "jsEvent" retrieve the "td" element but fullcalendar HTML structure is complex and it's impossible to go-up to find the day-cell
// $scope.selectedDay = ??
};
I tried playing with "selectable" but "eventClick" JS Event doesn't propagate, and doesn't "select" the day
Thanks
Upvotes: 3
Views: 2647
Reputation: 21
I updated Dane Iracleous's solution slightly to make it work with 1. click on multi-day events when there is more than one on the same day. and 2. this works in month/week/day views.
Using visibility/z-index solved my issue of the 'all day' container shrinking temporarily when the event layer was hidden.
getClickedDate(event) {
//used to get specific date clicked on multiple day event
let topLayer = $(event.el).closest(".fc-row");
let eventLayer = topLayer.find(".fc-content-skeleton");
let initialZIndex = $(eventLayer).css('z-index')
$(eventLayer).css({ 'visibility': 'hidden', 'z-index': '-1'});
let dayElement = $(document.elementFromPoint(event.jsEvent.pageX - window.pageXOffset, event.jsEvent.pageY - window.pageYOffset));
$(eventLayer).css({ 'visibility': 'visible', 'z-index': initialZIndex });
let clickedDate = dayElement.attr("data-date");
console.log('clicked date', clickedDate)
return clickedDate;
}
Upvotes: 0
Reputation: 1759
Here is slicedtoad's solution modified to work with v4 of fullcalendar and also taking into account the window's current scroll position:
eventClick: function(ev) {
var topLayer = $(ev.el).closest(".fc-row");
var eventLayer = topLayer.find(".fc-content-skeleton");
eventLayer.hide();
var dayElement = $(document.elementFromPoint(ev.jsEvent.pageX - window.pageXOffset, ev.jsEvent.pageY - window.pageYOffset));
eventLayer.show();
var current_day = dayElement.attr("data-date");
console.log(current_day);
}
Upvotes: 0
Reputation: 1
Here is my solution:
eventClick: function(event, jsEvent, view) {
var day=$(this).closest('.'+(view.type=='month'?'fc-row':'fc-time-grid')).find('.fc-bg td:eq('+$(this).closest('td').index()+')').data('date');
console.log(day);
}
Upvotes: 0
Reputation: 14133
If you don't need to catch event clicks at all, you can just add a class to all events with pointer-events: none;
eventRender: function (event, element) {
$(element).addClass('clickThrough');
},
Bleh. There is a hacky method to simulate pointer-events: none;
on IE8 but while trying to implement it I found a simpler way to achieve the goal. (The simulated pointer-events
hack is described here.)
To get the date at the cursor:
eventClick: function (calEvent, jsEvent, view) {
var topLayer = $(jsEvent.currentTarget).closest("tbody");
topLayer.hide(); //hide the entire event layer (makes it work with multiple events)
var dayElement = document.elementFromPoint(jsEvent.pageX, jsEvent.pageY); //get the element under the cursor (should be a day cell)
topLayer.show();
alert($(dayElement).data("date"));
}
(this doesn't seem to work)
So it turns out that anchor tags have a better pointer-events: none;
workaround. https://stackoverflow.com/a/18118092/728393
You simply add the attribute disabled="disabled"
to the <a>
and it can be clicked through.
eventRender: function (event, element) {
$(element).addClass('clickThrough').attr("disabled","disabled"); //disabled attribute is a IE workaround for pointer-events
},
Upvotes: 3
Reputation: 14440
So I finally found a quick(&dirty ?) solution relying on parsing close DOM Table elements.
From eventClick
js event, I can retrieve the currentTarget
clicked and go back in the table
headers : the first row contains thead
headers definition containing cell date mapping.
$scope.alertEventOnClick = function(event, jsEvent, view) {
var columnIndex = $(jsEvent.currentTarget).parent('td').get(0).cellIndex + 1;
var parentTable = $(jsEvent.currentTarget).closest('table');
var dateString = $('thead td:nth-child('+ columnIndex +')', parentTable).attr('data-date');
$scope.selectedDay = moment(dateString);
};
edit: solution OK for 1 event by day. but KO for more than one event by day ...
Another solution can be to determine x/y position of the clicked cell (by counting div/td childs) and map it with view.coordMap.grid.cellDates[position]
Upvotes: 1