【问题标题】:How to update an event in the database by dragging/dropping an external event in JavaScript and PHP?如何通过在 JavaScript 和 PHP 中拖放外部事件来更新数据库中的事件?
【发布时间】:2020-03-05 15:23:47
【问题描述】:

我正在使用全日历 JavaScript 库开发日历。我已经准备好前端,但我不确定如何更新数据库中的事件数据,在它被删除到日历之后。我对 JavaScript 很陌生,我提到了一些类似的问题,但没有得到我想要的东西。

这是我的代码:

**index.php**

<link href='https://unpkg.com/@fullcalendar/core@4.4.0/main.min.css' rel='stylesheet' />
<link href='https://unpkg.com/@fullcalendar/daygrid@4.4.0/main.min.css' rel='stylesheet' />
<link href='https://unpkg.com/@fullcalendar/timegrid@4.4.0/main.min.css' rel='stylesheet' />
<script src='https://unpkg.com/@fullcalendar/core@4.4.0/main.min.js'></script>
<script src='https://unpkg.com/@fullcalendar/interaction@4.4.0/main.min.js'></script>
<script src='https://unpkg.com/@fullcalendar/daygrid@4.4.0/main.min.js'></script>
<script src='https://unpkg.com/@fullcalendar/timegrid@4.4.0/main.min.js'></script>


<div id='external-events'>
 <p>
<strong>Draggable Events</strong>
</p>
<div class='fc-event'>My Event 1</div>
<div class='fc-event'>My Event 2</div>
<div class='fc-event'>My Event 3</div>
<div class='fc-event'>My Event 4</div>
<div class='fc-event'>My Event 5</div>
<p>
<input type='checkbox' id='drop-remove' />
<label for='drop-remove'>remove after drop</label>
</p>
   </div>
    <div id='calendar-container'>
     <div id='calendar'></div>
    </div>
 ** main.js**
 document.addEventListener('DOMContentLoaded', function() {
 var Calendar = FullCalendar.Calendar;
 var Draggable = FullCalendarInteraction.Draggable;

var containerEl = document.getElementById('external-events');
var calendarEl = document.getElementById('calendar');
var checkbox = document.getElementById('drop-remove');


new Draggable(containerEl, {
itemSelector: '.fc-event',
eventData: function(eventEl) {
  return {
    title: eventEl.innerText
  };
}
});

var calendar = new Calendar(calendarEl, {
plugins: [ 'interaction', 'dayGrid', 'timeGrid' ],
header: {
  left: 'prev,next today',
  center: 'title',
  right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
editable: true,
droppable: true, 
drop: function(info) {
  if (checkbox.checked) {
    info.draggedEl.parentNode.removeChild(info.draggedEl);
  }
},

});

calendar.render();
}); 

**add_event.php**

require 'database.php';
echo $_POST['title'];
$title = $_POST['title'];
$start = $_POST['start'];
$end = $_POST['end'];
$conn = DB::databaseConnection();
$conn->beginTransaction();
$sqlInsert = "INSERT INTO Events (title, start, [end]) VALUES    (:title, :start, :end)";
$stmt = $conn->prepare($sqlInsert);
$stmt->bindParam(':title', $title);
$stmt->bindParam(':start', $start);
$stmt->bindParam(':end', $end);


   if ($stmt->execute()) {
        $conn->commit();
        return true;
    } else {
        $conn->rollback();
        return false;
    }

这是我提到的密码的链接:https://fullcalendar.io/docs/external-dragging-demo 我只是不确定如何让 javascript 链接到插入函数。因此,当事件被删除时,它应该保存在数据库中。

【问题讨论】:

  • 您需要在 fullCalendar 中处理 eventReceive 回调。这将为您提供来自已删除项目的关联事件数据。然后,您可以使用 AJAX 将该数据发送到 add_event.php。见fullcalendar.io/docs/eventReceive
  • P.S. 警告:您的代码容易受到 SQL 注入攻击。您应该使用参数化查询来帮助防止攻击者通过使用恶意输入值来破坏您的数据库。 bobby-tables.com 给出了风险解释,以及一些如何使用 PHP 安全地编写查询的示例。 切勿将未经处理的数据直接插入您的 SQL 中。以您现在编写代码的方式,有人可以轻松窃取、错误更改甚至删除您的数据。 (您使用了准备好的语句,但也没有使用参数,它没有提供任何保护!)
  • 嘿,你能解释一下我如何处理事件接收吗?我得到了 ajax 部分,但在此之前需要处理 eventreceive 吗?
  • 感谢 sql 部分。那我应该做bindparam吗?
  • 是的,你绝对必须做 bindparam

标签: javascript php fullcalendar fullcalendar-4


【解决方案1】:

您需要在 fullCalendar 中处理 eventReceive 回调。这将为您提供来自已删除项目的关联事件数据。然后,您可以使用 AJAX 将该数据发送到 add_event.php。有关回调的更多详细信息,请参阅https://fullcalendar.io/docs/eventReceive

这样的事情应该可以工作:

eventReceive: function( info ) {

  //get the bits of data we want to send into a simple object
  var eventData = {
    title: info.event.title,
    start: info.event.start,
    end: info.event.end
  };
  //send the data via an AJAX POST request, and log any response which comes from the server
  fetch('add_event.php', {
    method: 'POST',
    headers: {'Accept': 'application/json'},
    body: encodeFormData(eventData)
  })
  .then(response => console.log(response))
  .catch(error => console.log(error));
}

注意:我使用现代的 fetch() 函数来执行 AJAX 调用,而不是旧的 XmlHttpRequest 或任何依赖 jQuery 或其他外部库的东西。

这是上面代码使用的 encodeForm 函数的代码(感谢 this site 的想法):

const encodeFormData = (data) => {
  var form_data = new FormData();

  for ( var key in data ) {
    form_data.append(key, data[key]);
  }
  return form_data;   
}

演示:

document.addEventListener('DOMContentLoaded', function() {
  var Calendar = FullCalendar.Calendar;
  var Draggable = FullCalendarInteraction.Draggable;

  var containerEl = document.getElementById('external-events');
  var calendarEl = document.getElementById('calendar');
  var checkbox = document.getElementById('drop-remove');


  new Draggable(containerEl, {
    itemSelector: '.fc-event',
    eventData: function(eventEl) {
      return {
        title: eventEl.innerText
      };
    }
  });

  var calendar = new Calendar(calendarEl, {
    plugins: ['interaction', 'dayGrid', 'timeGrid'],
    header: {
      left: 'prev,next today',
      center: 'title',
      right: 'dayGridMonth,timeGridWeek,timeGridDay'
    },
    editable: true,
    droppable: true,
    eventReceive: function(info) {

      //get the bits of data we want to send into a simple object
      var eventData = {
        title: info.event.title,
        start: info.event.start,
        end: info.event.end
      };
      console.log(eventData);
      //send the data via an AJAX POST request, and log any response which comes from the server
      fetch('add_event.php', {
          method: 'POST',
          headers: {
            'Accept': 'application/json'
          },
          body: encodeFormData(eventData)
        })
        .then(response => console.log(response))
        .catch(error => console.log(error));
    }
  });
  calendar.render();
});

const encodeFormData = (data) => {
  var form_data = new FormData();

  for (var key in data) {
    form_data.append(key, data[key]);
  }
  return form_data;
}
<link href='https://unpkg.com/@fullcalendar/core@4.4.0/main.min.css' rel='stylesheet' />
<link href='https://unpkg.com/@fullcalendar/daygrid@4.4.0/main.min.css' rel='stylesheet' />
<link href='https://unpkg.com/@fullcalendar/timegrid@4.4.0/main.min.css' rel='stylesheet' />
<script src='https://unpkg.com/@fullcalendar/core@4.4.0/main.min.js'></script>
<script src='https://unpkg.com/@fullcalendar/interaction@4.4.0/main.min.js'></script>
<script src='https://unpkg.com/@fullcalendar/daygrid@4.4.0/main.min.js'></script>
<script src='https://unpkg.com/@fullcalendar/timegrid@4.4.0/main.min.js'></script>


<div id='external-events'>
  <p>
    <strong>Draggable Events</strong>
  </p>
  <div class='fc-event'>My Event 1</div>
  <div class='fc-event'>My Event 2</div>
  <div class='fc-event'>My Event 3</div>
  <div class='fc-event'>My Event 4</div>
  <div class='fc-event'>My Event 5</div>
  <p>
    <input type='checkbox' id='drop-remove' />
    <label for='drop-remove'>remove after drop</label>
  </p>
</div>
<div id='calendar-container'>
  <div id='calendar'></div>
</div>

附:您还应该紧急修复PHP代码中的SQL注入漏洞,正如我在上面的cmets中提到的。

【讨论】:

  • 嘿!我修复了 SQL 并测试了上面的代码。错误显示标题、开始和结束的未定义索引。
  • 好的。这有点令人惊讶。您是否使用浏览器的网络工具来调试 fetch 请求中实际发送的内容?您是否尝试过记录 $_POST 的内容以查看它在传递到服务器时实际包含的内容?我们需要更具体的信息来调试它。
  • 是的。做过某事。在参数本身中,它显示标题未定义。下面是它的样子:title=undefined&start=Wed%20Mar%2011%202020%2000%3A00%3A00%20GMT-0400%20(Eastern%20Daylight%20Time)&end=null
  • 这很奇怪。我在上面做了一个可运行的sn-p,将我的代码和你的代码结合起来,没有出现这样的问题——标题已定义。并且数据传输正确。尽管您可能想考虑以不同的方式格式化日期。
  • 我刚刚编辑了上面的sql,有什么错误吗?似乎该文件没有获得标题、开始和结束。
猜你喜欢
  • 1970-01-01
  • 2021-03-24
  • 1970-01-01
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-20
  • 1970-01-01
相关资源
最近更新 更多