Полный вызов AJAX сработал несколько раз без перезагрузки страницы - PullRequest
0 голосов
/ 29 мая 2018

Когда я нажимаю на просмотр дня в месяце, появляется модальное окно.

Внутри этого модала есть кнопка для добавления нового события.Когда я нажимаю на это, появляется другой модал для формы добавления события.

Проблема в том, что я часто открываю / закрываю первый модал и пытаюсь добавить событие после этого без перезагрузки страницы, AJAXвызов срабатывает несколько раз, даже если я нажму на отправить только один раз.Иногда это умножается до 7 раз.

Я не знаю, в чем проблема.

Мой код:

$(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');
                }
              });
            }
          });
        }
      );

Мой код 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>";
  }
  }   
  ?>

Ответы [ 2 ]

0 голосов
/ 29 мая 2018

В настоящее время внутри вашего обработчика событий dayClick у вас есть код для добавления всех других обработчиков событий, а также определены некоторые функции.Это не очень хорошая вещь, потому что это означает, что каждый раз, когда пользователь нажимает на день, этот код будет запускаться и будет добавлять все больше и больше обработчиков событий на вашу страницу.Добавление обработчика событий не перезаписывает ранее добавленные обработчики, оно просто добавляет больше.Затем каждый раз, когда событие, к которому вы добавляете обработчик, запускается, он одновременно выполняет все обработчики событий, прикрепленные к нему.

Это объясняет, почему иногда вы видите, что ваши вызовы ajax запускаются снова и снова - это будет в тех случаях, когда вы нажимали на день (или разные дни) уже более одного раза.

Вам необходимо убедиться, что код обработки событий запускается только один раз , а ваши функции объявляются только один раз.Для этого переместите весь этот код за пределы конфигурации календаря.Затем вам также необходимо разрешить передачу некоторых параметров в функцию fetch_data, чтобы она знала, что нужно извлечь, не полагаясь на область закрытия:

Итак, в вашем коде fullCalendar:

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

Вот и все, это все, что вам нужно внутри конфигурации календаря.

Затем за пределами вашей конфигурации календаря:

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');
    }
  });
}
0 голосов
/ 29 мая 2018

Перемещение $(document).on('click', '.add-me', function(){ из dayClick обратного вызова

Каждый раз, когда вы щелкаете в день, вы добавляете новый прослушиватель событий щелчка для add-me

Так что нажимая на3 дня добавят 3 слушателя, а затем клик по add-me запустит обработчик событий (и ajax) 3 раза

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...