如何根据 FullCalendar V5 上的选择值过滤事件?

Posted

技术标签:

【中文标题】如何根据 FullCalendar V5 上的选择值过滤事件?【英文标题】:How to filter events based on select value on FullCalendar V5? 【发布时间】:2021-12-21 04:15:09 【问题描述】:

我第一次尝试了 FullCalendar 插件,所以我选择了版本 5。

我只想通过在选择下拉列表中选择值来过滤可见事件。

我似乎找不到使用 V5 的简单有效的方法。

我在互联网上找到的许多资源都在谈论使用 rererenderEvents 或 refetchEvents 但它指的是以前版本的插件,这在这里不起作用。

我通过循环遍历事件并使用 setProp 更改可见性找到了一种解决方法,但它看起来不太好。我有很多事件,for 循环需要几秒钟(sn-p 中的注释代码)

非常感谢您的建议和帮助

document.addEventListener('DOMContentLoaded', function() 

  let currentDayDate = new Date().toISOString().slice(0, 10);

  let calendarEl = document.getElementById('calendar');

  let calendar = new FullCalendar.Calendar(calendarEl, 
    initialView: 'timeGridWeek',
    firstDay: 1,
    hiddenDays: [ 0, 6 ],
    slotMinTime: '07:00',
    slotMaxTime: '20:00',
        allDaySlot: false,
    headerToolbar: 
      left: 'prev,today,next',
      center: 'title',
      right: 'timeGridDay,timeGridWeek'
    ,
    views: 
      timeGridWeek: 
        type: 'timeGrid',
        duration:  days: 2 ,
        buttonText: '2 day'
      
    ,
   events: [
      "title": "Marc",
      "start": currentDayDate + " 07:30",
      "end": currentDayDate + " 08:30",
      "userId": "1"
    , 
      "title": "Tom",
      "start": currentDayDate + " 09:30",
      "end": currentDayDate + " 10:30",
      "userId": "2"
    , 
      "title": "David",
      "start": currentDayDate + " 11:30",
      "end": currentDayDate + " 12:30",
      "userId": "3"
    ]
);
  calendar.render();
  
//  $( document ).ready(function() 
//   $('#selector').on('change',function()            
//     var events = calendar.getEvents();
//     for (var i = events.length - 1; i >= 0; i--) 
//       if ($("#selector").val() == events[i].extendedProps.userId || $("#selector").val() == "all") 
//         events[i].setProp("display", "block");
//       
//       else 
//         events[i].setProp("display", "none");
//       
//     
//   );
// );
  
);
<link href="https://cdn.jsdelivr.net/npm/fullcalendar@5.10.1/main.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.10.1/main.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="selector">
    <option value="all">All</option>
    <option value="1">Marc</option>
  <option value="2">Tom</option>
  <option value="3">David</option>
</select>
<div id="calendar">

</div>

【问题讨论】:

下面的答案是否解决了您的问题,或者以任何方式帮助您?如果是这样,请记得返回 *** 和 mark it as accepted - 如果仍有问题,请添加评论 【参考方案1】:

有几种方法可以使用 fullCalendar 进行过滤:

    在渲染事件时过滤掉它们

    在数据到达 fullCalendar 之前从源头过滤数据。

您在以前版本的 fullCalendar 中看到的过滤事件的方法仍然适用 - 这就是我将在此处演示的内容。但是,由于 v5 中没有 rerenderEvents 等效项,因此您需要使用 refetchEvents 来获取 fullCalendar 并再次绘制事件。 render 函数也无法实现。

但是,除非您有动态事件源,否则refetchEvents 将不起作用。目前,您有一个静态的事件列表。因此有

因此,我编写了一个带有标称 function-based 事件源的版本——它每次都返回完全相同的事件,但实际上你当然不会这样做——你会编写代码来让它请求/根据提供的日期生成一组动态事件,或者您可以使用 JSON event source 直接从 URL 获取事件数据,并由服务器控制返回的内容。

同样在 v5 中,eventRender 回调被 event render hooks 取代 - 出于我们的目的,eventDidMount 回调将适合我们想要做的事情。您可以在呈现每个事件时将其过滤掉(与您尝试获取所有事件并更新其属性的示例代码相反。)

注意我在这里根本没有使用过 jQuery,但当然欢迎您在任何需要的地方使用它来代替原生 DOM 函数。

document.addEventListener('DOMContentLoaded', function() 

  let currentDayDate = new Date().toISOString().slice(0, 10);
  let selector = document.querySelector("#selector");
  let calendarEl = document.getElementById('calendar');

  let calendar = new FullCalendar.Calendar(calendarEl, 
    initialView: 'timeGridWeek',
    firstDay: 1,
    hiddenDays: [0, 6],
    slotMinTime: '07:00',
    slotMaxTime: '20:00',
    allDaySlot: false,
    headerToolbar: 
      left: 'prev,today,next',
      center: 'title',
      right: 'timeGridDay,timeGridWeek'
    ,
    views: 
      timeGridWeek: 
        type: 'timeGrid',
        duration: 
          days: 2
        ,
        buttonText: '2 day'
      
    ,
    eventDidMount: function(arg) 
      let val = selector.value;
      if (!(val == arg.event.extendedProps.userId || val == "all")) 
        arg.el.style.display = "none";
      
    ,
    events: function (fetchInfo, successCallback, failureCallback) 
      successCallback([
        "title": "Marc",
        "start": currentDayDate + " 07:30",
        "end": currentDayDate + " 08:30",
        "userId": "1"
      , 
        "title": "Tom",
        "start": currentDayDate + " 09:30",
        "end": currentDayDate + " 10:30",
        "userId": "2"
      , 
        "title": "David",
        "start": currentDayDate + " 11:30",
        "end": currentDayDate + " 12:30",
        "userId": "3"
      ]);
    
  );
  calendar.render();

  selector.addEventListener('change', function() 
    calendar.refetchEvents();
  );
);
<link href="https://cdn.jsdelivr.net/npm/fullcalendar@5.10.1/main.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.10.1/main.min.js"></script>
<select id="selector">
  <option value="all">All</option>
  <option value="1">Marc</option>
  <option value="2">Tom</option>
  <option value="3">David</option>
</select>
<div id="calendar">

</div>

【讨论】:

你能在这个演示中添加复选框和下拉菜单吗? @ADyson @SarveshPatel 你是什么意思?一个复选框和下拉菜单做什么,究竟是什么?演示已经有一个下拉菜单...你想要一个不同的吗?附言一般来说,如果你有一个新问题,你应该问一个新的 *** 问题,展示你在实现你的要求方面所做的尝试,以及你遇到的问题。我不会改变这个演示来做一些不能解决原始问题中所述问题的事情。 谢谢,是的,我有新要求,是的,我可以提出新问题,但 *** 不允许提出问题。这就是我问你的原因。请检查我在问什么prntscr.com/22ypz7o。 实际上,两者都是分开工作的,但我想将它们结合起来作为一个过滤器工作。这是我的问题。 这还是太模糊了。无论如何,“我想要”不是一个问题。如果您有问题,请按下按钮并写出一个完整的问题,并附上您想要的正确说明,包括您解决问题的尝试,以及您尝试时出现的问题的描述。您的问题(您将需要其中一个!)应该基于您在实施规范时遇到的问题。您当然可以在帖子中提供指向此答案的链接,作为背景,但这不能替代发布您自己修改的代码。另见How to Ask。

以上是关于如何根据 FullCalendar V5 上的选择值过滤事件?的主要内容,如果未能解决你的问题,请参考以下文章

FullCalendar v5 通过切换按钮显示/隐藏周末

FullCalendar - 如何根据逗号分隔的日期从日历上的数据库(mysql)表行显示事件

Fullcalendar v5 仅呈现一个事件提示

Fullcalendar 语言环境不更改 v5 中的标题栏

编辑事件渲染()后的fullcalendar v5不刷新

使用 FullCalendar 和 SlickGrid 时如何选择文本