how to refresh fullcalendar v4 after change events object using ajax

后端 未结 4 915
不知归路
不知归路 2021-01-03 10:47

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 che

相关标签:
4条回答
  • 2021-01-03 11:14

    What I do : destroy calendar and re render it

    1. do not load calendar as indicated in the doc, but :
    function LoadCalendar() {
            if (typeof calendar != "undefined") {
                document.getElementById("calendar").innerHTML = "";
            }
            var calendarEl = document.getElementById('calendar');
            calendar = new FullCalendar.Calendar(calendarEl, {
            //... parameters
            });
            calendar.render();
        }
    
    1. Then at load :
    function FirstCalendar() {
            MesEvents = "$events"; // Ajax script is executed and give $events
            LoadCalendar();
        }
            document.addEventListener('DOMContentLoaded', FirstCalendar);
    
    1. And finnaly, for Ajax update :
    function makeRequest(event) {
            //... ajax instructions
            httpRequest.onreadystatechange = function() { changeContents(httpRequest); };
            httpRequest.open('POST', 'url/ajax.php', true);
            httpRequest.send(oData);
        }
        function changeContents(httpRequest) {
            try {
                if (httpRequest.readyState == XMLHttpRequest.DONE) {
                    if (httpRequest.status == 200) {
                        reponse = JSON.parse(httpRequest.responseText);
                        MesEvents = JSON.parse(reponse.Events);
                        LoadCalendar();
                    } else {
                        alert('Un problème est survenu avec la requête : ' + httpRequest.status);
                    }
                }
            }
            catch( e ) {
                alert(\"Une exception s’est produite (changeContents) : \" + e.description);
            }
        }
    
    0 讨论(0)
  • 2021-01-03 11:26

    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.

    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
        }
      });
    }
    

    Some notes:

    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) 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) 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.)

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

    0 讨论(0)
  • 2021-01-03 11:27

    Please check below code:

     $.ajax({
            url:"/admin/get-users-tasks/"+data,
            type:"GET",
            success: function (response) {
                calendar.addEventSource( '/admin/get-users-tasks/'+data );
                var eventSource = calendar.getEventSources();
                eventSource[0].remove();
                eventSource[0].refetch();
            },
            error: function(response) {
                new PNotify({
                    title: "Opération échoué",
                    text: response.message,
                    type: "error"
                  });
            }
          });
    
    0 讨论(0)
  • 2021-01-03 11:28

    Full Calendar v4

    First, I would like to thank ADyson and Boutamente for the answers. it helped me in finding my solution. My code is as follows:

    <script>
    
      document.addEventListener('DOMContentLoaded', function() {
    
        var calendarEl = document.getElementById('calendar');
        var calendar = new FullCalendar.Calendar(calendarEl, {
    
        plugins: [ 'dayGrid','interaction','googleCalendar' ],
        editable: true,
        selectable: true,
    
        dateClick: function(info) {
    
          // open a modal form and submit using ajax
    
        },
    
        // eventClick is not required if you are using eventRender with bootstrap tooltip or popover. However it is up to you.
    
        // eventClick: function(info) {
    
        //   alert('Event: '+titleCase(info.event.title)+'\n'+'Start: '+info.event.start.toDateString()+' '+info.event.start.toLocaleTimeString()+'\n'+'End: '+info.event.end.toDateString()+' '+info.event.end.toLocaleTimeString());
    
        // },
    
        // there is no need to set a static event source if you are
        // fetching events using custom function
        // eventSources allow you to fetch events using fn,json,array
    
        eventSources: [
          {
            // FullCalendar will call this function whenever it needs new data
            // fetchInfo is auto populated with start and end dates of calendar
            // I manipulate the start and end data in my controller to search the db
            // for more info on fetchInfo Object, https://fullcalendar.io/docs/events-function
            // base_url() is a custom function
    
            events:function(fetchInfo, successCallback, failureCallback) {
    
              $.ajax({
                type:'GET',
                url: base_url() + "/fetchInfo",
                data:{"start":fetchInfo.start.toDateString(),"end":fetchInfo.end.toDateString()},
                success: function(response) {
    
                  successCallback(response.dates.map(function(event) {
    
                    return {
                      id:event.id,
                      title:event.title,
                      start:event.start,
                      end:event.end,
                    }
    
                  })
                  );
                },
                error: function(response){
                  console.log(response);
                  failureCallback(response);
                },
              }); 
            },
            color: 'yellow',
          }
        ],
    
        eventDrop: function(info) {
    
            if(!confirm("Are you sure about this change?")) {
              info.revert();
            }
            // call function to update event date with ajax
            modifyEvent(info.event);
    
        },
    
        eventRender: function(info) {
    
          $(info.el).popover(
            {
              title:titleCase(info.event.title),
              content:multiline('Start: ' + info.event.start.toDateString() + ' ' + info.event.start.toLocaleTimeString() + '\n' + 'End: ' + info.event.end.toDateString() + ' ' + info.event.end.toLocaleTimeString()),
              html:true,
              trigger:'hover',
              container:'body',
              placement:'top',
            });
        },
    
      });
    
      // refetch events once you close the modal form
    
      $('#createEventModal').on('hidden.bs.modal', function() {
    
          calendar.refetchEvents();
    
      });
    
      calendar.render();
    
      });
    
    
    </script>
    
    0 讨论(0)
提交回复
热议问题