#jquery #css #fullcalendar
#jquery #css #полный календарь
Вопрос:
В fullcalendar вы можете выбрать событие (которое запускает) функцию eventClick / обратного вызова. Что я хотел бы сделать, так это выделить день события при нажатии на событие (в режиме просмотра месяца).
Например, если событие назначено на 30 октября, и я выбираю событие, я бы хотел, чтобы был выделен цвет фона дня. Это очень похоже на то, как fullcalendar обрабатывает «сегодня», где он выделяет сегодняшний день желтоватым цветом.
Кажется, я не могу понять, как связать класс fc-event или сам объект event с фактическим днем div в календаре. Мое событие 30 октября появляется в следующем div (который является полем 30 октября):
<div class="fc-sun fc-widget-content fc-day35 fc-first">
Как я могу найти этот div (чтобы я мог его выделить) на основе объекта события?
Ответ №1:
Вы можете просто использовать метод выбора в полном календаре.
Например:
$('#calendar').fullCalendar('select', date);
Откуда date
берется event.start
:
eventClick: function( event, jsEvent, view ) {
//pass event.start to select method
}
Комментарии:
1. Отличное решение, если событие длится всего один день .
Ответ №2:
Извините, это грубое решение, в основном из памяти, поскольку я не настроен на какие-либо инструменты разработки на этом компьютере.
Надеюсь, это то, что вы ищете!
//create fullCalendar:
$("#calendar").fullCalendar({
/* options */
eventClick: function(event, jsEvent){
//use the passed-in javascript event to get a jQuery-wrapped reference
//to the DOM element we clicked on.
//i can never remember if this is .target, .currentTarget, or .originalTarget
//... jquery has spoiled me
var $clickedEvent = $(jsEvent.target);
//tell the "selectionManager" to find the day this event belongs to,
//and add the "selected" css class to it
selectionManager.select($clickedEvent);
}
});
//define an object that handles the adding-removing of the 'selectedDay' css class
var selectionManager = (function(){
//i like making private variables :-)
var $curSelectedDay = null
//define a "select" method for switching 'selected' state
return {
select: function($newEvent) {
if ($curSelectedDay){
//if we already had a day chosen, let's get rid of its CSS 'selectedDay' class
$curSelectedDay.removeClass("selectedDay");
}
//find the parent div that has a class matching the pattern 'fc-day', and add the "selectedDay" class to it
$curSelectedDay = $thisEvent.closest('div[class~="fc-day"]').addClass("selectedDay");
}
};
})();
Комментарии:
1. Это не совсем то, что я хотел, но вы указали мне правильное направление своим кодом. Спасибо, что нашли время.
Ответ №3:
Вот немного более простое решение, которое сработало для меня:
$(".fc-state-highlight").removeClass("fc-state-highlight");
$(jsEvent.currentTarget).addClass("fc-state-highlight");
… это происходит внутри вашего обработчика кликов, например:
$('#eventCalendar').fullCalendar({
dayClick: function(date, allDay, jsEvent, view) {
$(".fc-state-highlight").removeClass("fc-state-highlight");
$(jsEvent.currentTarget).addClass("fc-state-highlight");
}
});
Обратите внимание, что при этом используется dayClick
обработчик вместо eventClick
обработчика. Я не понимаю, почему это не должно работать eventClick
, но я еще не проверял это.
Редактировать:
Использование сопоставимого подхода для eventClick
обработчика оказалось более сложным, чем я думал. Проблема в том, что с точки зрения иерархии DOM нет отношения родитель / потомок между содержащим td
элементом для «дня» и содержащими div
элементами для событий, которые отображаются как происходящие в этот день.
Поэтому мне пришлось написать функцию для поиска правильного td
элемента для заданной даты. В итоге я получил что-то вроде:
function findContainerForDate(date) {
var firstDayFound = false;
var lastDayFound = false;
var calDate = $('#eventCalendar').fullCalendar('getDate');
var allDates = $('td[class*="fc-day"]')
for (var index = 0; index < allDates.length; index ) {
var container = allDates[index];
var month = calDate.getMonth();
var dayNumber = $(container).find(".fc-day-number").html();
if (dayNumber == 1 amp;amp; ! firstDayFound) {
firstDayFound = true;
}
else if (dayNumber == 1) {
lastDayFound = true;
}
if (! firstDayFound) {
month--;
}
if (lastDayFound) {
month ;
}
if (month == date.getMonth() amp;amp; dayNumber == date.getDate()) {
return container;
}
}
}
… и тогда я мог бы реализовать eventClick
так:
eventClick: function(calEvent, jsEvent, view) {
var selectedContainer = findContainerForDate(calEvent.start);
$(".fc-state-highlight").removeClass("fc-state-highlight");
$(selectedContainer).addClass("fc-state-highlight");
}
Ответ №4:
eventRender: function (event, element, view) {
// like that
var dateString = $.fullCalendar.formatDate(event.start, 'yyyy-MM-dd');
view.element.find('.fc-day[data-date="' dateString '"]').css('background-color', '#FAA732');
// or that
var cell = view.dateToCell(event.start);
view.element.find('tr:eq(' (cell.row 1) ') td:eq(' cell.col ')').css('background-color', '#FAA732');
}
Есть ли лучшее решение?
Ответ №5:
Мой взгляд на функцию поиска aroth
// based on the given event date return the full calendar day jquery object (<td ...>)
// matching day and month
//
// assumptions:
// - the event date is if for the same year as the current viewable month
// - the fc-day* TD's are in chronological order
// - the fc-day* TD's not for the current month have a class of fc-other-month
//
findFullCalendarDayForClickedEvent : function( eventDate ) {
var foundDay;
var $theCalendar = $( '#myCalendar' );
var currentDate = $theCalendar.fullCalendar( 'getDate' );
var fullCalendarDayContainers = $theCalendar.find( 'td[class*="fc-day"]' );
for( var i = 0; i < fullCalendarDayContainers.length; i ) {
var $currentContainer = $( fullCalendarDayContainers[ i ] );
var dayNumber = $currentContainer.find( '.fc-day-number' ).html();
// first find the matching day
if ( eventDate.getDate() == dayNumber ) {
// now month check, if our current container has fc-other-month
// then the event month and the current month needs to mismatch,
// otherwise container is missing fc-other-month then the event
// month and current month need to match
if( $currentContainer.hasClass( 'fc-other-month' ) ) {
if( eventDate.getMonth() != currentDate.getMonth() ) {
foundDay = $currentContainer;
break;
}
}
else {
if ( eventDate.getMonth() == currentDate.getMonth() ) {
foundDay = $currentContainer;
break;
}
}
}
}
return foundDay;
}
Ответ №6:
Благодаря ответу Фитца Агарда о существовании метода выбора полного календаря, вот версия, которая работает даже для многодневных событий.
В основном он пытается найти день, в который находятся координаты щелчка мыши, затем он передает свою дату методу выбора полного календаря.
function findClickedDay(e) {
var days = $('#calendar .fc-day');
for(var i = 0 ; i < days.length ; i ) {
var day = $(days[i]);
var mouseX = e.pageX;
var mouseY = e.pageY;
var offset = day.offset();
var width = day.width();
var height = day.height();
if ( mouseX > offset.left amp;amp; mouseX < offset.left width
amp;amp; mouseY > offset.top amp;amp; mouseY < offset.top height )
return day;
}
}
function myDayClick(date) { ... } // Optional
$('#calendar').fullCalendar({
dayClick: function(date) { myDayClick(date); }, // Optional
eventClick: function(event, jsEvent, view) {
clickedDay = findClickedDay(jsEvent);
var date = new Date(clickedDay.data('date'));
$('#calendar').fullCalendar('select', date);
myDayClick(date); // Optional
}
});
Редактировать:
Я только что понял, что метод выбора полного календаря не запускает обратный вызов dayClick. Итак, если вы установили обратный вызов dayClick, вы должны обернуть его в функцию (называемую здесь myDayClick ) и вызвать ее в обратном вызове eventClick . Если у вас нет обратного вызова dayClick, вы можете удалить необязательные части.
Ответ №7:
Не уверен, помогает ли это, но я обнаружил, что это работает довольно хорошо, подобно решению kayz1…
$("[data-date='" $.datepicker.formatDate('yy-mm-dd', new Date(calEvent.start)) "']").addClass("fc-state-highlight");
Ответ №8:
Так много ответов. Небольшие исследования дают мне более понятный код: fullcalendar v2.1.1
onDayClick = function( date, jsEvent, view ){
var cell = view.dateToCell(date);
var el = view.dayGrid.getCellDayEl(cell);
var $clickedEvent = $(el);
$clickedEvent.addClass("SelectedDay");
};
Ответ №9:
Если вы обновитесь до fullcalendar версии v2 или выше, это очень просто:
$('#calendar').fullCalendar({
eventClick: function(calEvent, jsEvent, view) {
// change the border color just for fun
$(this).css('border-color', 'red');
}
});
Вот ссылка для eventClick.
Комментарии:
1. Посмотрите на вопрос OP: что я хотел бы сделать, это выделить ДЕНЬ события при нажатии на событие. Ваш ответ выделяет СОБЫТИЕ, а не ДЕНЬ