Search code examples
javascriptphpfullcalendarfullcalendar-schedulerfullcalendar-5

Fullcalender V5 RefetchEvents issue


I am using Fullcalender Scheduler V5. I added calendar.refetchEvents(); at the end of eventDrop, eventResize, eventClick also. It is working well. But when I use it in other functions to add /edit the events, it is not working.Here is my code:

    <!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />

  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>

    <script src='moment-timezone.js'></script>
    <script src='lib/locales-all.js'></script>
    <link href='fullcalender_scheduler/main.css' rel='stylesheet' />
    <script src='fullcalender_scheduler/main.js'></script>
    <script src='fullcalender_scheduler/ja.js'></script>

  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
  var calendarEl = document.getElementById('calendar');

  var calendar = new FullCalendar.Calendar(calendarEl, {
    schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',   
    eventTimeFormat: { hour: 'numeric', minute: '2-digit' }, 
    businessHours: true,  
    height: '100%',
    aspectRatio: 1.8,
    editable: true, // enable draggable events
    now: new Date(),
    scrollTime: '00:00', // undo default 6am scrollTime
    headerToolbar: {
      left: 'today prev,next',
      center: 'title',
      right: 'resourceTimelineDay,resourceTimelineTenDays,timeGridWeek,dayGridMonth,listWeek'
    },
    initialView: 'resourceTimelineDay',
    views: {
      resourceTimelineTenDays: {
        type: 'resourceTimeline',
        duration: { days: 10 },
        buttonText: '10 days'
      }
    },
    expandRows: true,
    resourceAreaWidth: '10%',
    resourceAreaHeaderContent: 'Rooms',
    resourceOrder: 'type1', // to set the displayorder of resources
    resources: [
      { id: '1', title: 'R1' , eventColor: 'blue', type1:10},
      { id: '2', title: 'R2', eventColor: 'green',type1:13 },
      { id: '3', title: 'R3', eventColor: '#F39C12',type1:14 },
      { id: '4', title: 'R4', eventColor: 'red' ,type1:11 },
      { id: '5', title: 'R5', eventColor: '#8E44AD',type1:12 },
    ],

    events :'load.php',
    selectable:true,
    selectHelper:true,
//---------------------------ADD EVENTS----------------------------------------///
    select: function(info) {
        var st_time = info.startStr;
        var start =st_time.split("T").join(" ");
        var end_time = info.endStr;
        var end =end_time.split("T").join(" ");
        var resourc =info.event._def.resourceIds;  
        var resourceId = resourc.toString();
        
        
      $('#ModalAdd').modal('show');
      $('#ModalAdd #Room').val(resourceId);
      $('#ModalAdd #start').val(start);
      $('#ModalAdd #end').val(end);
    },
    
eventResize:function(info)
    {
     var resourc =info.event._def.resourceIds; 
     var resourceId = resourc.toString(); 
     var title = info.event.title;
     var start =info.event.start;
             var end =info.event.end;    
     var id = info.event.id;
     
     var scriptUrl = "DragEvent.php";
     
     $.ajax({
      url:scriptUrl,
      type:"POST",
      data:{title:title, start:start, end:end, id:id, resourceId:resourceId},
      
      success: function(data){
        alert('Event updated');
        calendar.refetchEvents();---------Here, its working well
      }
     })
    },

  });
  
  calendar.render();
  
});

function saveData()
   {
 var Room= document.getElementById("Room").value;      
 var EventName= document.getElementById("EventName").value;
 var start=document.getElementById("start").value;
 var end=document.getElementById("end").value;

 var ScriptUrl="addEvent.php";  
    $.ajax({
       url:ScriptUrl,
       type:"POST",
       data:{EventName:EventName, start:start, end:end},
       
      success: function(data){
        alert("Added successfully");
        // calendar.refetchEvents();-----------------------tried here. Not working
       }
 
       });
     
     $('#ModalAdd').modal('hide');
        calendar.refetchEvents();----------Here also, Not working
   }

</script>
<style>

  html, body {
    overflow: hidden; /* don't do scrollbars */
    font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
    font-size: 14px;
  }

  #calendar-container {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
  }

  .fc-header-toolbar {
    padding-top: 1em;
    padding-left: 1em;
    padding-right: 1em;
  }

</style>
</head>
<body>
   
   <!-- Modal -->
        <div class="modal fade" id="ModalAdd" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
          <div class="modal-dialog" role="document">
            <div class="modal-content">
            <form class="form-horizontal" method="POST" action="pages/calenderpages/addEvent.php" name="add_item" id ="add_item">
            
              <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                <h4 class="modal-title" id="myModalLabel"><b>Add events</b></h4>
              </div>
              <div class="modal-body">
                  <div class="form-group">
                   <input type="hidden" name="Room" class="form-control" id="Room" value="">
                    <label for="genryo" class="col-sm-4 control-label">Event name</label>
                    <div class="col-sm-8">
                      <input type="text" name="EventName" class="form-control" id="EventName" value="">
                    </div>
                  </div>              
                  <div class="form-group">
                    <label for="start" class="col-sm-4 control-label">Start</label>
                    <div class="col-sm-8">
                      <input type="text" name="start" class="form-control" id="start" readonly>
                    </div>
                  </div>
                  <div class="form-group">
                    <label for="end" class="col-sm-4 control-label">End</label>
                    <div class="col-sm-8">
                      <input type="text" name="end" class="form-control" id="end" readonly>
                    </div>
                  </div>
                
              </div>
              <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">CLOSE</button>
                <button type="button" class="btn btn-primary" onclick="saveData()">SAVE</button>
              </div>
            </form>
            </div>
          </div>
        </div>

 <!------------------------------------------>

  <div id='calendar-container'>
    <div id='calendar'></div>
  </div>
</body>
</html>

Here is my other codes:

/-----------------------Load.php------------------------------//

    <?php
require_once('../../common/conn_check.php');
require_once('../../common/common.php');

$data=array();

$query ="SELECT * FROM event_schedule "; 


$statement = pg_query($conn,$query);
$result = pg_fetch_all($statement);


foreach($result as $row)
{
    
 $data[] = array(
  'id' => $row["id"],
  'resourceId' => $row["Room"],
  'title' =>$row["EventName"],
  'start'   => $row["StartTime"],
  'end'   => $row["EndTime"]
 );
}


echo json_encode($data);
?>

/---------------AddEvents.php-------------------//


   <?php
    require_once('../../common/conn_check.php');//for using the mysql connection
    require_once('../../common/common.php');//common function
    
    
    
    if (isset($_POST['start']) && isset($_POST['end'])){
        $EventName = $_POST['EventName'];
        $Room = $_POST['Room'];
        $start = $_POST['start'];
        $end = $_POST['end']; 
     
    $sql="INSERT INTO event_schedule
           (Room,EventName, StartTime,EndTime)
           VALUES 
           ('$EventName','$Room','$start', '$end')"; 
           
           
    $result = pg_query($conn,$sql);
        
    echo json_encode(array('success'=>true));
    }
    
    ?>

I have been trying this for weeks, I lost my confidence due to this. As a beginner, I couldn't figure out what's going wrong. Someone, please help.


Solution

  • The simplest option here is to make calendar global so it's accessible in all scopes.

    e.g.

    <script>
    var calendar; //global variable
    
    document.addEventListener('DOMContentLoaded', function() {
      var calendarEl = document.getElementById('calendar');
    
      calendar = new FullCalendar.Calendar(calendarEl, { //don't re-declare it here, just assign it
    
    ///...etc
    

    But global variables are usually not best practice - it can lead to other issues if you're not careful. So another option is to stop using an inline event handler to trigger saveData, and instead add an event handler inside the DOMContentLoaded block, where of course calendar is already in scope. You make saveData return a Promise from the AJAX call, and then in the event handler you attach a .done() callback to it, and in there you can call refetchEvents.

    So in this version, your button would become

    <button type="button" class="btn btn-primary" id="savedata">SAVE</button>
    

    and saveData() would become:

    function saveData()
    {
      var Room = document.getElementById("Room").value;      
      var EventName = document.getElementById("EventName").value;
      var start = document.getElementById("start").value;
      var end = document.getElementById("end").value;
    
      var promise = $.ajax({
        url: "addEvent.php",
        type:"POST",
        data:{ EventName: EventName, start:start, end: end },
      });
     
      $('#ModalAdd').modal('hide');
      return promise;
    }
    

    And lastly in the DOMContentLoaded area:

    document.addEventListener('DOMContentLoaded', function() {
    
       //....everything which is already there....and then...
    
       $("#savedata").click(function() {
         var promise = saveData();
    
         promise.done(function(data) {
           calendar.refetchEvents();
         });
       });
    });
    

    Although it looks like more work, this is a much better structured version than using a global variable.