0

So I can see the info of a user in a FullCalendar that is opened in a modal but when I try to open another the modal it doesn`t refresh. I tried all the solutions I found here on Stackoverflow but it didn't work. If I refresh the page then it works if I click in a diferent id.

Code where I bring the id of user to my function cale():

<button id="cal" onclick="cale('.$row["idutilizador"].') class="btn" data-toggle="modal" href="#calendario"><i class="fa fa-calendar"></i></button>

My calendar modal Bootstrap:

<div class="modal fade" id="calendario" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-xl" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalLabel">Calendario</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <br />
        <h2 align="center"><a href="#">Calendario</a></h2>
        <br />
        <div class="container">
          <div id="calendar"></div>
        </div>
      </div>
    </div>
  </div>
</div>

My function that loads the information from database with the id I got when I click:

function cale(uti){
    var calendar = $('#calendar').fullCalendar({
        editable:true,
        header:{
            left:'prev,next today',
            center:'title',
            right:'month,agendaWeek,agendaDay'
        },
        events: {    
            url:'../Components/calendar/load.php',
            type: 'POST',
            data: function() { 
                return {
                    id: uti      
                };    
            }
        },
        ...
Don't Panic
  • 13,965
  • 5
  • 32
  • 51
Late Place
  • 13
  • 4

2 Answers2

1

Your code currently reinitialises the calendar every time you click a button. You should only initialise the calendar once, and then change the data it displays. To do that, you need to first remove the previous event source, add the new one, and then get the new events.

A suggestion: convention is that POST is for changing data (eg making a purchase, updating a record), while GET is for reading data. Here your event source is just loading event data to display, that really should be a GET request. Changing that also makes the code a bit simpler. I've changed to GET here, if you want to do this you need to change your PHP to respond to GET instead of POST.

Another suggestion: AFAICT you are using multiple non-unique HTML IDs on the same page. Your code suggests that the button is inside a loop, so you have buttons for multiple users, but your buttons all have the same ID:

<button id="cal" ...

The code you've shown does not use that ID, but if you try to, it won't work. IDs must be unique, if they are not and you try to use them, only the first one will work.

Another suggestion: it is generally considered best to separate your JS and your HTML, so instead of using inline onclick, use a separate event handler. You'll need to add the user ID to the button somehow, maybe with a data attribute:

<button data-id="' . $row["idutilizador"] . '" ...

And then instead of onclick() on that button, add an event handler in your JS:

$('button').on('click', function(e) {
    // Prevent any default action the button click might normally
    // do, eg submit a form or something.
    e.preventDefault();

    // Find the ID of the clicked button
    var userID = $(this).data('id');

    // Now call the calendar function with that ID
    cale(userID);
});

The code below implementes all these suggestions.

UPDATE As per comments you're using FullCalendar v3, so here's a working v3 solution (click Run to see it in action). I've also converted the previous v5 solution into a working snippet, see below.

FullCalendar v3 solution

// The base URL where your events are.  I'm using npoint JSON
// bins from https://www.npoint.io/, yours would be:
// var sourceURL = '../Components/calendar/load.php';
var sourceURL = 'https://api.npoint.io/';

// The current source (none initially)
var currentSource;

// The calendar
var calendar = $('#calendar').fullCalendar({
    defaultDate: '2022-01-15',
    editable:true,
    header:{
        left:'prev,next today',
        center:'title',
        right:'month,agendaWeek,agendaDay'
    },
    // no events initially
});

// Handle button clicks
$('button').on('click', function(e) {
    // Prevent any default action the button click might normally
    // do, eg submit a form or something.
    e.preventDefault();

    // Find the ID of the clicked button
    var userID = $(this).data('id');

    // Now call the calendar function with that ID
    cale(userID);
});

// Update sources
function cale(uti) {

    // First remove the current source.  First time through
    // there is no source, but that does not matter.
    // v3: https://fullcalendar.io/docs/v3/removeEventSource    
    calendar.fullCalendar('removeEventSource', currentSource);

    // Set up the URL to the new source. I'm using npoint JSON
    // bins from https://www.npoint.io/, so this URL format is 
    // different to yours, you would use:
    // currentSource = sourceURL + '?id=' + uti
    currentSource = sourceURL + uti;

    // Now add the new source.  Note this will use a GET request
    // to retrieve events.  The new events will be immediately
    // fetched and displayed.
    // v3: https://fullcalendar.io/docs/v3/addEventSource
    calendar.fullCalendar('addEventSource', currentSource);
}
hr {
    margin: 20px 0;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.4.0/fullcalendar.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.4.0/fullcalendar.min.js"></script>

Click to select a source:
<button data-id="965e830c3e8ab78990c5">Source 1</button>
<button data-id="5c8901e5173d5eab3ad6">Source 2</button>

<hr>

<div id="calendar"></div>

FullCalendar v5 solution

And here's the original v5 solution, as a working snippet, click Run to see it working.

// The base URL where your events are.  I'm using npoint JSON
// bins from https://www.npoint.io/, yours would be:
// var sourceURL = '../Components/calendar/load.php';
var sourceURL = 'https://api.npoint.io/';

// The current source (none initially)
var currentSource;

// The calendar
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
    initialDate: '2022-01-15',
    editable:true,
    // no events initially
});
calendar.render();

// Handle button clicks
$('button').on('click', function(e) {
    // Prevent any default action the button click might normally
    // do, eg submit a form or something.
    e.preventDefault();

    // Find the ID of the clicked button
    var userID = $(this).data('id');

    // Now call the calendar function with that ID
    cale(userID);
});

// Update sources
function cale(uti) {
    // First get all the current event sources
    // v5: https://fullcalendar.io/docs/Calendar-getEventSources
    var sources = calendar.getEventSources();

    // Now remove those event sources.  Note the first time through there
    // are none.
    // v5: https://fullcalendar.io/docs/EventSource-remove
    for (const source of sources) {
        source.remove();
    }

    // Set up the URL to the new source. I'm using npoint JSON
    // bins from https://www.npoint.io/, so this URL format is 
    // different to yours, you would use:
    // currentSource = sourceURL + '?id=' + uti
    currentSource = sourceURL + uti;

    // Now add your new source.  Note this will use a GET request to
    // retrieve events.  The new events will be immediately fetched 
    // and displayed.
    // v5: https://fullcalendar.io/docs/Calendar-addEventSource
    calendar.addEventSource(currentSource);
}
hr {
      margin: 20px 0;
  }
<link href="https://cdn.jsdelivr.net/npm/fullcalendar@5.10.1/main.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.10.1/main.min.js"></script>

Click to select a source:
<button data-id="965e830c3e8ab78990c5">Source 1</button>
<button data-id="5c8901e5173d5eab3ad6">Source 2</button>

<hr>

<div id="calendar"></div>
Don't Panic
  • 13,965
  • 5
  • 32
  • 51
0

Try to empty first the div

$('#calendar').html('');

obviously first of

var calendar = $('#calendar').fullCalendar({...
Joseph
  • 13
  • 3
  • doesnt work, it becames empty – Late Place Jan 25 '22 at 23:05
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 26 '22 at 02:37