简体   繁体   English

Fullcalendar AJAX调用多次触发,没有重新加载页面

[英]Fullcalendar AJAX call fired multiple times without reloading page

When I click a day in month view, a modal will pop-up. 当我单击月份视图中的一天时,将弹出一个模式。

Inside that modal is a button for adding a new event. 在该模式内部是一个用于添加新事件的按钮。 When I click that, another modal will pop-up for the Add Event form. 当我单击该按钮时,将为“添加事件”表单弹出另一个模式。

The problem is when I frequently open/close the first modal and try to add an event after that without reloading the page, the AJAX call fires multiple times even if I click the submit only once. 问题是,当我频繁打开/关闭第一个模式并尝试在此之后添加事件而不重新加载页面时,即使我仅单击一次提交,AJAX调用也会触发多次。 Sometimes it multiplies up to 7 times. 有时它最多可乘以7次。

I don't know what the problem is. 我不知道问题是什么。

My code: 我的代码:

$(document).ready(function() {
      var calendar = $('#calendar').fullCalendar({
        header: {
          left: 'today',
          center: 'prev title next',
          right: 'month,basicWeek,basicDay'
        },
        eventOrder: 'start',
        editable: true,
        droppable: true,
        eventLimit: true,
        selectable: true,
        selectHelper: true,
        events: 'getEvents.php',
        eventRender: function(event, element, view) {
            var today = new Date();
            var startString = moment(event.start).format('YYYY-MM-DD');
            var endString = moment(event.end).format('YYYY-MM-DD');
            $(element).each(function () { 
              $(this).attr('date-num', event.start.format('YYYY-MM-DD')); 
            });
        },
        eventAfterAllRender: function(view){
          for( cDay = view.start.clone(); cDay.isBefore(view.end) ; cDay.add(1, 'day') ){
            var dateNum = cDay.format('YYYY-MM-DD');
            var dayEl = $('.fc-day[data-date="' + dateNum + '"]');
            var eventCount = $('.fc-event[date-num="' + dateNum + '"]').length;
            if(eventCount){
              var html = '<span class="event-count">' + 
                        '<i>' +
                        eventCount + 
                        '</i>' +
                        ' Events' +
                        '</span>';

              dayEl.append(html);
            }
          }
        },
        dayClick: function(start, end, event) {
          var st = start.format('YYYY-MM-DD HH:mm:ss');
          var en = start.format('YYYY-MM-DD HH:mm:ss');

          function fetch_data() {
            $.ajax({
              url: "view-data.php",
              data: 'action=view&start=' + st + '&end=' + en,
              method: "POST",
              success: function(data) {
                $('#view-me').html(data);
                $('#view-data').modal('show');
              }
            });
          }

          fetch_data();

          $(document).on('click', '.add-me', function() {
            $('#start').val(moment($(this).data('start')).format('YYYY-MM-DD[T]HH:mm:ss'));
            $('#end').val(moment($(this).data('end')).format('YYYY-MM-DD[T]HH:mm:ss'));
            $('#ModalAdd').modal('show');

            $('#myFormAdd').on('submit', function(e) { // add event submit
              e.preventDefault();
              doAdd(); // send to form submit function
            });

            function doAdd() { // add event
              var title = $('#title').val();
              var start = $('#start').val();
              var end = $('#end').val();

              $.ajax({
                url: 'addEvent.php',
                data: 'action=add&title=' + title + '&start=' + start + '&end=' + end,
                type: "POST",
                success: function(json) {
                  $('#ModalAdd').modal('hide');
                  fetch_data();
                  calendar.fullCalendar('refetchEvents');
                }
              });
            }
          });
        }
      );

My PHP Code: view-data.php 我的PHP代码:view-data.php

 if($_POST['action'] == "view") // view event dayClick
{ 
 $start = $_POST['start'];
 $end = $_POST['end'];
 ?>

  //Add new button
  <button title="add new here" class="add-me" data-start="<?php echo $start; ?>" 
  data-end="<?php echo $end; ?>" rel="dialog" >ADD</button>

<?php 

 $sql = "SELECT * FROM events WHERE start BETWEEN '$start' AND '$end' OR end BETWEEN '$start' AND '$end'";  
 $result = mysqli_query($connect, $sql);  

 if(mysqli_num_rows($result) > 0)  
 {  
  while($row = mysqli_fetch_array($result))  
  {
  ?>

  <span style="overflow:hidden;text-overflow:ellipsis;white-space: nowrap;"><?php echo $row['title']; ?></span>

  <?php
  }
  } else {
     echo "<span>No event</span>";
  }
  }   
  ?>

Move the $(document).on('click', '.add-me', function(){ out of the dayClick callback 移动$(document).on('click', '.add-me', function(){出的dayClick回调

Every time you click on a day you are adding a new click event listener for the add-me 每次您单击一天时,都会为add-me添加一个新的click事件监听器

So clicking on 3 days would add 3 listeners and then a click on add-me will run the event handler ( and ajax) 3 times 因此,单击3天将添加3个侦听器,然后单击add-me将运行事件处理程序(和ajax)3次

Currently inside your dayClick event handler you've got code to add all your other event handlers, and also defined some functions. 当前,在dayClick事件处理程序中,您已经有了添加所有其他事件处理程序的代码,并且还定义了一些函数。 This is not a good thing to do, because it means that every time a user clicks on a day, this code will run and keep adding more and more event handlers to your page. 这不是一件好事,因为这意味着每次用户单击一天时,此代码将运行并继续向页面中添加越来越多的事件处理程序。 Adding an event handler does not overwrite previously added handlers, it just keeps adding more. 添加事件处理程序不会覆盖以前添加的处理程序,而只是不断添加更多内容。 Then every time the event you add the handler to is triggered, it executes all the event handlers attached to it, simultaneously. 然后,每次触发向您添加处理程序的事件时,它都会同时执行附加到它的所有事件处理程序。

This explains why sometimes you see your ajax calls run again and again - it will be in the cases where you've clicked on a day (or different days) more than once already. 这就解释了为什么有时您会看到ajax调用一次又一次地运行的情况-在这种情况下,您单击一天(或不同日期)一次以上即可。

You need to make sure you event handling code only ever runs once , and your functions are only ever declared once. 您需要确保事件处理代码仅运行一次 ,并且函数仅声明一次。 To do this, move all that code outside your calendar config. 为此,将所有代码移到日历配置之外。 You then also need to allow some parameters to be passed to the fetch_data function, so that it knows what to fetch without relying on closure scope: 然后,您还需要允许将一些参数传递给fetch_data函数,以便它知道在不依赖闭包作用域的情况下要获取的内容:

So, in your fullCalendar code: 因此,在您的完整日历代码中:

dayClick: function(start, end, event) {
  fetch_data(start, end);
}

That's it, that's all you need inside the calendar config. 就是这样,这就是日历配置中所需的全部内容。

Then, outside your calendar config: 然后, 您的日历配置之外

function fetch_data(start, end) {
  var st = start.format('YYYY-MM-DD HH:mm:ss');
  var en = start.format('YYYY-MM-DD HH:mm:ss');
  $.ajax({
    url: "view-data.php",
    data: 'action=view&start=' + st + '&end=' + en,
    method: "POST",
    success: function(data) {
      $('#view-me').html(data);
      $('#view-data').modal('show');
    }
  });
}


$(document).on('click', '.add-me', function() {
  $('#start').val(moment($(this).data('start')).format('YYYY-MM-DD[T]HH:mm:ss'));
  $('#end').val(moment($(this).data('end')).format('YYYY-MM-DD[T]HH:mm:ss'));
  $('#ModalAdd').modal('show');
});

$(document).on("submit", '#myFormAdd', function(e) { // add event submit
  e.preventDefault();
  doAdd(); // send to form submit function
});

function doAdd() { // add event
  var title = $('#title').val();
  var start = $('#start').val();
  var end = $('#end').val();

  $.ajax({
    url: 'addEvent.php',
    data: 'action=add&title=' + title + '&start=' + start + '&end=' + end,
    type: "POST",
    success: function(json) {
      $('#ModalAdd').modal('hide');
      //fetch_data(); //it's not clear why you would need to do this here, since you've just hidden the modal which is populates! Pretty sure you don't need it, so I've commented it out
      calendar.fullCalendar('refetchEvents');
    }
  });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM