2

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.

Maya
  • 183
  • 1
  • 14
  • Please show us how you defined the `events:` option in your calendar. – ADyson Aug 17 '20 at 08:16
  • i loaded the events using php script. events: "calenderpages/LoadEvents.php", – Maya Aug 18 '20 at 02:27
  • Your php looks fine. It's not clear how/why you think refetchEvents would fail. Do you see any errors in the console when this happens? And have you looked in the Network tool in your browser to check the call to loadEvents is happening and is working, and returning the data you expected? Or do you see any PHP errors logged? We need these more specific details to be able to understand the precise scenario you are talking about – ADyson Aug 18 '20 at 12:28
  • Also, I can't really see what you're hoping to achieve anyway by calling refetchEvents within the "select" callback? There's no code in that callback which would do anything such as alter the event data in your database or anything like that. I don't know what getMname.php does, but even if it alters the event data in your database, the refetchEvents call would run before that script has finished so it wouldn't be able to detect any changes. – ADyson Aug 18 '20 at 12:32
  • I tried adding refetchevents inside the success loop of the ajax function that performs database edits. It never worked. Hence I tried adding it like this, which is atleast working on the next select action. All other places, it is not refetchign events after edits or add. – Maya Aug 18 '20 at 22:59
  • Ok. Well like I said, you need to find out why it isn't working the way you expect. Inspect the console and network data as I mentioned. Without that information there isn't much that anyone can do to help you – ADyson Aug 18 '20 at 23:11
  • I couldn't find any errors. But, Let me check it again. Thank you – Maya Aug 18 '20 at 23:19
  • When used inside ajax functions, CONSOLE LOG says : calendar.refetchEvents() is not a function. If I use it inside the calender function, no errors. – Maya Aug 19 '20 at 02:59
  • That probably means the calendar variable is not in scope somehow – ADyson Aug 19 '20 at 06:34
  • Thanks for your edit. However, you've made your situation worse. `$("#calendar").fullCalendar('refetchEvents');` is the syntax for fullCalendar v3, when it was a jQuery plugin. That will never work. You _should_ be able to do `calendar.refetchEvents();`. Why you can't is a mystery. I made a simple demo using your earlier idea, with refetchEvents inside the `select` callback. It works fine - look here: https://codepen.io/ADyson82/pen/bGpwZNL . If you still have a problem, you'll need to give us some code which actually reproduces the issue - something else must be going on to give you an issue. – ADyson Aug 20 '20 at 08:33
  • Thanks for the code sample. As I told already, it is working fine inside the calendar script. The above function is a button on-click function to post data into database. There, after posting the data, I am trying to refresh the calendar events. Is it like, calling refetchevents outside the calendar script is impossible?? – Maya Aug 20 '20 at 23:15
  • "calling refetchevents outside the calendar script is impossible?"....not if the `calendar` object is in scope. You can either make it global or pass it into the function. P.S. This is totally different to the examples you gave previously. _As I told already, it is working fine inside the calendar script_...no, you said exactly the opposite in your original question - see the first version you asked, at the bottom of this page: https://stackoverflow.com/posts/63446566/revisions. You've changed your explanation since then. It's not easy to help someone with a problem when they change the facts. – ADyson Aug 21 '20 at 08:42
  • Am sorry. My first explanation was not that clear. That's why I updated. And still, I am having the same issue. the re fetch inside the select is working the next time when I select the calendar field. Thanks for your time. I apologize for my faults. I am new to programming. So I am not sure how to explain things properly. – Maya Aug 23 '20 at 23:32
  • Ok, so let's try again. "the re fetch inside the select is working the next time when I select the calendar field"...so when it "doesn't work" the first time, is that because of the error you mentioned, or because of something else? Please be specific. It doesn't really make sense that you'd get a scope error one time and not the second time. Can you revise your question to show us a version of the code which actually reproduces this first-time/second-time problem? – ADyson Aug 24 '20 at 06:51
  • error is not related with the refetch inside calendar function.I didn't get any errors inside the calendar function.Newly added event is visible on the calendar when I click the calendar area once again. My question is, How can I refetch after inserting events to database using an ajax function(as shown in the above code). Where/How shall I write calender.refetchevents() in that case? – Maya Aug 24 '20 at 07:31
  • You need to write it inside the "success" area. Otherwise it will try to refetch before your database has finished saving the data (because ajax is asynchronous). If you get the error there, then you need to make sure that `calendar` is in scope in that part of the code. I explained this in a comment 2 days ago already. Do do you understand about variable scope in JavaScript? – ADyson Aug 24 '20 at 08:23
  • Sorry. I didn't understand that. Scope? – Maya Aug 24 '20 at 08:31
  • Ok. This is a relatively basic concept in JavasScript (and most other programming languages). If you declare a particular variable, it is usually only accessible (i.e. "in scope") within a certain area of the code where it was defined. e.g. within a function, or a module, or just within a loop - something like that. This explains in more detail: https://stackoverflow.com/questions/500431/what-is-the-scope-of-variables-in-javascript – ADyson Aug 24 '20 at 08:34
  • So, if you want to access the variable outside that area, you normally have you either increase it scope (e.g. by declaring it in a global context, so it's accessible from everywhere - but this can sometimes lead to poor separation of functionality, making maintenance harder, and/or create some strange bugs), or by passing a reference to the variable into another area you want to use it (e.g. by making it a parameter in a fucntion). – ADyson Aug 24 '20 at 08:35
  • Although I don't have enough code shown in context to be sure, I'd guess that your problem is that `calendar` is not accessible within your `saveData` function because you declared it within a different block of code. – ADyson Aug 24 '20 at 08:36
  • As I see it here you have 3 options: 1 - make calendar global, 2 - pass calendar into the saveData function, or 3 - make saveData return the Promise generated by $.ajax, and then have the calling code handle the "done" event of the Promise, and call refetchEvents from there, so that calendar is already in scope within that area. 3 would arguably be the neatest in terms of separation of concerns in your code. – ADyson Aug 24 '20 at 08:38
  • Thanks for these useful information. I have to learn a little more to understand clearly. I will do it, and try to solve the issue. Once I get a solution, will update here. – Maya Aug 24 '20 at 08:42
  • No problem. If you still need more help after you try to make it work, then please update the question with the relevant code. – ADyson Aug 24 '20 at 08:44
  • I tried passing calender to saveData, but I couldnt make it work well. May be, my knowledge is poor. Sorry ADyson, even though you gave enough instructions. – Maya Sep 28 '20 at 00:44

1 Answers1

1

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.

ADyson
  • 57,178
  • 14
  • 51
  • 63
  • Thank you very much. It worked well, I am so glad than I could explain seeing the calendar re-fetching events. – Maya Sep 28 '20 at 23:33