javascript - 如何在 fullCalendar 中隐藏事件?
问题描述
使用最新版本的 fullCalendar (5.3.2) 我想隐藏一些与我现在不想在给定视图中显示的资源相对应的事件。执行此操作的标准方法是使用一个eventClassNames
函数来检查它并添加一个“隐藏”类。像这样的东西:
eventClassNames: function(arg) {
my_class = "";
if (arg.view.type != 'resourceTimeGridDay') {
if (arg.event.extendedProps.real_rc != "1") {
my_class = 'hidden';
}
}
return my_class;
}
使用简单的 CSS:
.fc-event.hidden {
display: none;
}
这可以正常工作,但是当隐藏事件和显示事件之间存在重叠时会出现问题。例如在这种情况下:
events: [
{
title: 'Resource 1',
real_rc: '1',
start: '2020-12-22 16:00',
end: '2020-12-22 17:00'
},
{
title: 'Resource 2',
real_rc: '2',
start: '2020-12-22 15:00',
end: '2020-12-22 17:00'
}
]
应该只显示带有的事件,real_rc == 1
实际上它是正确的,但是隐藏事件使用的空间被保留,如下图所示:
如果列表real_rc: 2
中省略了带有 的事件,则event
结果是预期的:
我已经使用 Chrome DevTools 试图弄清楚发生了什么,我认为问题在于“隐藏”类没有像fullCalendar 状态那样设置在“最外层事件元素”上,而是设置在内部一个:
(第一个 DIV 是第一个事件,如您所见,hidden
该类已设置但不是设置为 DIV,而是设置为a
标签)
恕我直言,这是一个完整的日历错误,但现在我遇到了一个问题,我需要一个解决方案。我的选择是:
- 为父级使用 CSS 选择器 <--不可能:它不存在(尚)
- (1) 使用 jquery <--我不知道怎么做?我知道我需要在
$(".fc-event.hidden").parent().remove()
加载和显示事件时执行类似的操作,但由于 v3 不存在这样的 更新,即使它存在,当前 v5 删除 DOM 元素也不会调整其他事件框的大小。 - 尝试修复库的代码<--问题:如果下一个版本的库没有解决方案,我不想担心补丁
- 加载时过滤事件 <-- 慢:我使用回调函数通过 Ajax 加载事件,我可以在那里进行快速过滤,但在这种情况下,我会失去性能,因为我每次需要时都必须重新获取事件显示事件
real_rc != 1
- 自定义视图 <-- 我不想重新发明轮子。正如@saqibkafeel 在评论中所建议的,自定义视图可用于创建新视图,但我喜欢当前视图并且不需要新视图,只需默认视图按预期工作即可。
有没有办法在不创建新问题的情况下绕过这个问题?(我觉得最简单的选择是找到一个可以让我做选项2的钩子,但是我花了一整天都没有找到任何东西)。
解决方案
正如您已经注意到的,CSS 和 JS 在这里无法提供帮助,因为事件是使用放置的,position:absolute
因此删除一个事件(甚至完全从 DOM 中)不会影响其他事件的显示。唯一的方法是在渲染之前从日历中删除事件。
所以删除事件而不是添加一个类:
eventClassNames: function(arg) { /* you can also use "eventDidMount" */
if (arg.view.type != 'resourceTimeGridDay') {
if (arg.event.extendedProps.real_rc != "1") {
arg.event.remove(); /* HERE */
}
}
},
完整代码:
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'timeGridWeek',
initialDate: '2020-12-22',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
height: 'auto',
eventClassNames: function(arg) {
if (arg.view.type != 'resourceTimeGridDay') {
if (arg.event.extendedProps.real_rc != "1") {
arg.event.remove();
}
}
},
events: [
{
title: 'Test Resource 1',
real_rc: '1',
start: '2020-12-22 13:00',
end: '2020-12-22 14:00'
},
{
title: 'Also resource 1',
real_rc: '1',
start: '2020-12-22 13:30',
end: '2020-12-22 14:30'
},
{
title: 'Resource 1',
real_rc: '1',
start: '2020-12-22 16:00',
end: '2020-12-22 17:00'
},
{
title: 'Resource 2',
real_rc: '2',
start: '2020-12-22 15:00',
end: '2020-12-22 17:00'
}
]
});
calendar.render();
});
html, body {
margin: 0;
padding: 0;
font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
font-size: 14px;
}
#calendar {
max-width: 1100px;
margin: 40px auto;
}
<link rel="stylesheet" href="https://unpkg.com/fullcalendar@5.1.0/main.min.css">
<script src="https://unpkg.com/fullcalendar@5.1.0/main.min.js"></script>
<div id='calendar'></div>
另一个想法是控制display
事件的发生,如下所示:
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'timeGridWeek',
initialDate: '2020-12-22',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
height: 'auto',
eventDidMount: function(arg) {
if (arg.view.type != 'resourceTimeGridDay') {
if (arg.event.extendedProps.real_rc != "1") {
arg.event.setProp( 'display', 'none' );
}
}
},
events: [
{
title: 'Test Resource 1',
real_rc: '1',
start: '2020-12-22 13:00',
end: '2020-12-22 14:00'
},
{
title: 'Also resource 1',
real_rc: '1',
start: '2020-12-22 13:30',
end: '2020-12-22 14:30'
},
{
title: 'Resource 1',
real_rc: '1',
start: '2020-12-22 16:00',
end: '2020-12-22 17:00'
},
{
title: 'Resource 2',
real_rc: '2',
start: '2020-12-22 15:00',
end: '2020-12-22 17:00'
}
]
});
calendar.render();
});
html, body {
margin: 0;
padding: 0;
font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
font-size: 14px;
}
#calendar {
max-width: 1100px;
margin: 40px auto;
}
<link rel="stylesheet" href="https://unpkg.com/fullcalendar@5.1.0/main.min.css">
<script src="https://unpkg.com/fullcalendar@5.1.0/main.min.js"></script>
<div id='calendar'></div>
一个交互式演示,您可以在其中切换显示:
var rc = "1";
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'timeGridWeek',
initialDate: '2020-12-22',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
height: 'auto',
eventDidMount: function(arg) {
if (arg.view.type != 'resourceTimeGridDay') {
if (arg.event.extendedProps.real_rc != rc) {
arg.event.setProp( 'display', 'none' );
}
}
},
viewDidMount: function(arg) {
var es = calendar.getEvents();
for(var i=0;i<es.length;i++)
es[i].setProp( 'display', 'auto' )
},
events: [
{
title: 'Test Resource 1',
real_rc: '1',
start: '2020-12-22 13:00',
end: '2020-12-22 14:00'
},
{
title: 'Also resource 1',
real_rc: '1',
start: '2020-12-22 13:30',
end: '2020-12-22 14:30'
},
{
title: 'Resource 1',
real_rc: '1',
start: '2020-12-22 16:00',
end: '2020-12-22 17:00'
},
{
title: 'Resource 2',
real_rc: '2',
start: '2020-12-22 15:00',
end: '2020-12-22 17:00'
}
]
});
calendar.render();
document.querySelector("#toggle").addEventListener('click',function() {
if (rc=="1") rc="2"; else rc = "1";
/* trigger view change */
calendar.changeView('dayGridMonth');
calendar.changeView('timeGridWeek');
});
});
html, body {
margin: 0;
padding: 0;
font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
font-size: 14px;
}
#calendar {
max-width: 1100px;
margin: 40px auto;
}
<link rel="stylesheet" href="https://unpkg.com/fullcalendar@5.1.0/main.min.css">
<script src="https://unpkg.com/fullcalendar@5.1.0/main.min.js"></script>
<button id="toggle">toggle</button>
<div id='calendar'></div>
推荐阅读
- php - 通过functions.php在菜单中使用自定义字段默认图像
- java - Kafka 流异常:org.apache.kafka.streams.errors.StreamsException - 反序列化异常处理程序
- javascript - 在 React 中为列表分页
- python - 使用 groupby 选择行,对列求和并使用所有 groupby 元素的总和创建新列
- swift - Xcode 获取命令 CodeSign 失败,退出代码非零:APP 是一个目录
- flutter - 在未来的 gridView 中更改按钮颜色和图标
- javascript - 通过页面分离 wix 图像数据库
- windows - 如何在日志文件中捕获tomcat控制台输出
- java - 在android中将数据从第一个选项卡传递到第三个选项卡活动时获取空对象引用
- c# - EF Core 在映射到 Select 中的对象时查询 SQL 中的所有列