title: how to refresh fullcalendar v4 after change events object using ajax
body: <p>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 .</p>
  
  <p>after change i get the new object events but i need to refresh fullcalendar
   i try with <code>calendar.render();</code> but not working</p>
  
  <pre><code>fullcalendar V4 !!
  </code></pre>
  
  <blockquote>
    <p>fullcalendar script</p>
  </blockquote>
  
  <pre><code> 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 à '+"&lt;b&gt; " + moment(info.startStr).format('DD-MM-YYYY HH:mm') + "&lt;/b&gt; "+" fin à " +"&lt;b&gt; " + moment(info.endStr).format('DD-MM-YYYY HH:m:m')) +"&lt;/b&gt;"
                  $('#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('&lt;img src="'+document.location.origin+'/'+info.event.extendedProps.user_avatar+'" class="img-circle event-avatar" alt="User Image"&gt;');
                  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 ="&lt;p&gt;"+moment(info.event.start).format('DD-MM-YYYY HH:mm')+' / '+moment(info.event.end).format('DD-MM-YYYY HH:mm')+"&lt;/P&gt;"
                          +"&lt;p&gt;"+info.event.extendedProps.description+"&lt;/p&gt;"
                          +"&lt;p&gt;"+"Utilisateur : "+info.event.extendedProps.user+"&lt;/p&gt;"
                          +"&lt;p&gt;"+"Projet : "+info.event.extendedProps.project+"&lt;/p&gt;"
                          +"&lt;p&gt;"+"Fonction : "+info.event.extendedProps.activity+"&lt;/p&gt;"
                          +"&lt;a class='btn btn-primary btn-xs'&gt;"+state(info.event.extendedProps.state)+"&lt;/a&gt;";
                          return html;
                      },
                      trigger: 'hover',
                      placement: 'top',
                      html: 'true',
                      container: 'body'
                      });
              },
  
          });
          calendar.addEventSource( taskEvents );
          calendar.render();
  //--------------------------------------------------------
  </code></pre>
  
  <blockquote>
    <p>ajax script</p>
  </blockquote>
  
  <pre><code>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"
                        });
                  }
                });
          }
  </code></pre>
  
  <blockquote>
    <p>on change checkbox function</p>
  </blockquote>
  
  <pre><code> 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));
          })
      }
  </code></pre>