Modal Bootstrap 刷新数据 FullCalendar

Modal Bootstrap refreshing data FullCalendar

所以我可以在以模式打开的 FullCalendar 中看到用户的信息,但是当我尝试打开另一个模式时,它不会刷新。我尝试了在 Whosebug 上找到的所有解决方案,但没有用。如果我刷新页面,那么如果我点击不同的 ID,它就会工作。

我将用户 ID 带入我的函数的代码 cale():

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

我的日历模式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>

我的函数使用我单击时获得的 ID 从数据库中加载信息:

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      
                };    
            }
        },
        ...

先尝试清空 div

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

显然是第一个

var calendar = $('#calendar').fullCalendar({...

您的代码当前会在您每次单击 button 时重新初始化日历。您应该只初始化日历一次,然后更改它显示的数据。为此,您需要先删除以前的事件源,添加新事件源,然后获取新事件。

建议:convention is POST 用于更改 数据(例如购买,更新记录),而 GET 用于 正在读取 数据。这里您的事件源只是加载要显示的事件数据,这实际上应该是一个 GET 请求。改变它也使代码更简单一些。我在这里更改为 GET,如果你想这样做,你需要更改你的 PHP 以响应 GET 而不是 POST。

另一个建议:据我所知,您在同一页面上使用了多个 non-unique HTML ID。您的代码表明 button 在一个循环内,因此您有多个用户的按钮,但您的按钮都具有相同的 ID:

<button id="cal" ...

您显示的代码未使用该 ID,但如果您尝试使用,它不会起作用。 ID 必须是唯一的,如果它们不是并且您尝试使用它们,only the first one will work.

另一个建议:通常认为最好将 JS 和 HTML 分开,因此不要使用内联 onclick,而是使用单独的事件处理程序。您需要以某种方式将用户 ID 添加到按钮,可能使用数据属性:

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

然后在您的 JS 中添加一个事件处理程序,而不是该按钮上的 onclick()

$('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 根据评论,您使用的是 FullCalendar v3,因此这是一个有效的 v3 解决方案(单击 运行 查看实际效果)。我还将之前的 v5 解决方案转换为一个工作片段,见下文。

FullCalendar v3 解决方案

// 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 解决方案

这里是原始的 v5 解决方案,作为工作片段,单击 运行 看看它是否有效。

// 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>