如何使用ajax在更改事件对象后刷新fullcalendar v4 [英] how to refresh fullcalendar v4 after change events object using ajax

查看:182
本文介绍了如何使用ajax在更改事件对象后刷新fullcalendar v4的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用fullcalendar v4来显示事件. 事件在负载中正常显示,但是我需要使用多个复选框添加过滤器,并在使用ajax的onchange复选框之后刷新全日历事件.

i use fullcalendar v4 to show events. events shows in load normally ,but i need to add a filter using multiple checkboxes and refresh fullcalendar events after onchange checkbox with ajax .

更改后,我得到了新的对象事件,但是我需要刷新fullcalendar 我尝试使用calendar.render();但不起作用

after change i get the new object events but i need to refresh fullcalendar i try with calendar.render(); but not working

fullcalendar V4 !!

全日历脚本

fullcalendar script

 var taskEvents = JSON.parse($("input[name=tasks_events]").val());
        var calendarEl = document.getElementById('tasks_calendar');
        var  calendar = new FullCalendar.Calendar(calendarEl, {
            locale: 'fr',
            plugins: [ 'interaction', 'dayGrid', 'timeGrid' ],
            header: {
                left: 'prev,next today',
                center: 'title',
                right: 'dayGridMonth,timeGridWeek'
            },
            defaultDate: new Date(),
            defaultView: 'timeGridWeek',
            minTime: "09:00:00",
            maxTime: "20:00:00",
            weekends:false,
            businessHours: true, // display business hours
            editable: true,
            selectable: true,
            droppable: true,
            //events:taskEvents ,
            select: function(info) {
                $('#newTaskFormLabel').html('Commence à '+"<b> " + moment(info.startStr).format('DD-MM-YYYY HH:mm') + "</b> "+" fin à " +"<b> " + moment(info.endStr).format('DD-MM-YYYY HH:m:m')) +"</b>"
                $('#newTaskForm').modal('show');
                $('#newTaskForm input[name=start_at]').val(info.startStr);
                $('#newTaskForm input[name=end_at]').val(info.endStr);
            },
            eventClick: function(info) {
                $('#editTaskForm').modal('show');
                console.log(info);
                editTask(info.event);
            },
            // dateClick: function(info) {
            //     alert('clicked ' + info.dateStr);
            // },
            eventResize: function(info) {    
                $('.popover.in').remove();     
                if (confirm("Êtes-vous sûr de vouloir appliquer ces modifications?")) {
                    submitTimeChanges(info.event);
                }else{
                    info.revert();
                }
            },   
            eventDrop : function(info){
                $('.popover.in').remove(); 
                // $(info.el).removeAttr('aria-describedby');
                if (confirm("Êtes-vous sûr de vouloir appliquer ces modifications?")) {
                    submitTimeChanges(info.event);
                }else{
                    info.revert();
                }
            },
            eventRender: function(info) {

                $(info.el).append('<img src="'+document.location.origin+'/'+info.event.extendedProps.user_avatar+'" class="img-circle event-avatar" alt="User Image">');
                let state = function (state) { 
                    if(state =="not_started") return "Pas encore commencé";
                    if(state =="started") return "Commencé";
                    if(state =="finish") return "Terminer";
                }
                $(info.el).popover({
                    title: info.event.title,
                    content: function () {
                        let html ="<p>"+moment(info.event.start).format('DD-MM-YYYY HH:mm')+' / '+moment(info.event.end).format('DD-MM-YYYY HH:mm')+"</P>"
                        +"<p>"+info.event.extendedProps.description+"</p>"
                        +"<p>"+"Utilisateur : "+info.event.extendedProps.user+"</p>"
                        +"<p>"+"Projet : "+info.event.extendedProps.project+"</p>"
                        +"<p>"+"Fonction : "+info.event.extendedProps.activity+"</p>"
                        +"<a class='btn btn-primary btn-xs'>"+state(info.event.extendedProps.state)+"</a>";
                        return html;
                    },
                    trigger: 'hover',
                    placement: 'top',
                    html: 'true',
                    container: 'body'
                    });
            },

        });
        calendar.addEventSource( taskEvents );
        calendar.render();
//--------------------------------------------------------

ajax脚本

ajax script

var getTasks = function (data){
            $.ajax({
                url:"/admin/get-users-tasks",
                type:"POST",
                data :{
                    users:data,
                },
                headers: {
                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                },
                success: function (response) {
                    calendar.addEventSource( response );
                    calendar.refetchEvents();
                },
                error: function(response) {
                    new PNotify({
                        title: "Opération échoué",
                        text: response.message,
                        type: "error"
                      });
                }
              });
        }

更改复选框功能

on change checkbox function

 function onChangeUserCheckbox() {  
        $("input[name*=selected_user]").on('change',function () {
            var selectedUsers = [];
            $.each($("input[name*='selected_user']:checked"), function(){            
                selectedUsers.push($(this).val());
            });
            getTasks(selectedUsers);
            // getTasks(JSON.stringify(selectedUsers));
        })
    }

推荐答案

您尚未确切说明代码出了什么问题,但是我可以看到,当您从AJAX调用中获得响应时,您将添加一个新的每次事件源.我还可以看到,尽管您从未删除任何先前的事件源,所以您将继续获得越来越多的事件.我将假设这是您要问的问题.

You haven't explained precisely what is going wrong with your code, but I can see that when you get the response from the AJAX call, you add a new event source each time. I can also see that you never remove any previous event source though, so you will just keep getting more and more events. I'm going to assume this is the problem you're asking about.

但是,与其始终添加/删除事件源,不如将其声明为可以刷新和更新的单个事件源会更简单.您可以使用文档中此处所述的"events-as-a-function"模式来声明此来源.

But, rather than adding/removing event sources all the time, it would be simpler to declare this as a single event source which can be refreshed and updated. You would use the "events-as-a-function" pattern described here in the documentation to declare this source.

这是一些经过修改的代码,这些代码会更有意义:

Here's some revised code which would make a bit more sense:

var calendarEl = document.getElementById('tasks_calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
  eventSources: [
    JSON.parse($("input[name=tasks_events]").val()), //static event source
    getTasks //pass a reference to a function, so we have a dynamic, updateable event source
  ]
  ///....all your other options go here as well....
});

$("input[name*=selected_user]").on('change',function () {
  calendar.refetchEvents(); //this will automatically cause the "getTasks" function to run, because it's associated with an event source in the calendar
});

var getTasks = function(fetchInfo, successCallback, failureCallback) { //the input parameters are the ones shown in the fullCalendar documentation
  //find the currently selected users
  var selectedUsers = [];
  $.each($("input[name*='selected_user']:checked"), function(){            
    selectedUsers.push($(this).val());
  });

  //run the ajax call
  $.ajax({
    url: "/admin/get-users-tasks",
    type: "POST",
    data: {
      users: selectedUsers,
    },
    headers: {
      'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    },
    success: function (response) {
      successCallback(response); //pass the event data to fullCalendar via the provided callback function
    },
    error: function(response) {
      new PNotify({
        title: "Opération échoué",
        text: response.message,
        type: "error"
      });

      failureCallback(response); //inform fullCalendar of the error via the provided callback function
    }
  });
}

一些注意事项:

1)在此版本中,当日历加载后,它将立即向服务器发出AJAX请求并尝试获取事件.但是,由于未选中任何复选框,因此不会将任何数据传递到服务器.在这种情况下,我不知道您的服务器代码目前正在做什么,或者您想要它做什么.我猜它应该返回所有可能的事件,或者根本不返回.无论哪种方式,您都需要确保已设置服务器代码来处理这种情况并返回有意义的数据.

1) In this version, when the calendar loads it will immediately make an AJAX request to the server and try to get events. However since no checkboxes are selected, no data will be passed to the server. I don't know what your server code currently does in that situation, or what you want it to do. I guess it should either return all the possible events, or none at all. Either way you need to make sure the server code is set up to handle this situation and return whatever data makes sense.

2)我也在这里添加了其他事件集(从隐藏字段中获取)作为事件源.无需通过"addEventSource"单独添加它,因为您可以在日历加载后立即添加它-您只需在选项中声明即可.

2) I've added your other set of events (taken from your hidden field) as an event source in here as well. There's no need to add it separately via "addEventSource", since you're adding it immediately when the calendar loads - you can just declare it in the options instead.

3)我这里没有使用提供的fetchInfo数据,但理想情况下,您应该从该对象获取开始日期和结束日期值,并将其作为参数发送到服务器,而服务器应该使用它们来过滤数据,仅返回开始日期在这两个日期之间的事件.这样会更有效率,因为这样一来,您将只返回实际上将要显示在日历上的数据,而不是返回用户曾经执行的所有任务-如果您考虑过,一旦您的应用程序已用于几个月后,它们将开始拥有大量过去的数据,每次下载都没有意义,因为几乎可以肯定不会看到这些数据. (请注意,如果用户确实导航到过去/将来的日期,而fullCalendar没有这些日期的事件数据,它将再次运行AJAX调用并要求服务器提供该日期.但是,如果用户从不查看这些日期,不会打扰,您可以节省一些带宽和处理时间.)

3) I haven't used the provided fetchInfo data here, but ideally you should be taking the start and end date values from that object and sending them to your server as parameters, and your server should be using them to filter the data and only return events whose start dates fall between those two dates. This will be more efficient, because then you'll only return data which is actually going to be displayed on the calendar, rather than all tasks the user has ever had - if you think about it, once your application has been in use for a few months, they will start to have a lot of past data, which there is no point in downloading every time, as almost certainly it will not be viewed. (Note that, if the user does navigate to past/future dates and fullCalendar doesn't have event data for those dates, it will run the AJAX call again and ask the server to provide it. But if the user never views those dates, it won't bother, and you save some bandwidth and processing time.)

有关在以下位置配置事件源的文档,请参见 https://fullcalendar.io/docs/eventSources .日历选项.

See https://fullcalendar.io/docs/eventSources for documentation about configuring Event Sources in the calendar options.

这篇关于如何使用ajax在更改事件对象后刷新fullcalendar v4的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆