Skip to main content

Event CRUD in FullCalendar using PHP and jQuery Tutorial

In this tutorial, I will show how to Create CRUD Operation in FullCalendar with PHP and MySQL Database. here, you will learn to add, edit, view, and delete events on the calendar. The events will be stored in MySQL Database. This feature can be useful for your future PHP Projects such as Appointment Management Systems or Scheduling Systems.

We will create a simple PHP application with dummy MySQL data that stores the events/schedules. The main goal of the application is to have features or functionalities that adds, updates, view, and delete events in FullCalendar.

Getting Started

Download XAMPP as your local web server to run our PHP Script. After Installing the virtual server, open the XAMPP's Control Panel and start the Apache Server and MySQL.

Since, that events will be shown in a calendar view using the FullCalendar library/plugin, download the library's resources here.

Download Bootstrap v5 and jQuery for the interface design of the application that we'll be creating. After that move the library directory to the folder where you will store the source code on your end.

Creating The Database

Open a new tab in your browser and browse the XAMPP's PHPMyAdmin. Next, create a new database naming dummy_db. Then, navigate the page into the SQL Tab/Page and paste SQL Script below to the provided text field. Lastly, click the Go Button to execute the script.

  1. CREATE TABLE `schedule_list` (
  2. `id` int(30) NOT NULL PRIMARY KEY AUTO_INCREMENT,
  3. `title` text NOT NULL,
  4. `description` text NOT NULL,
  5. `start_datetime` datetime NOT NULL,
  6. `end_datetime` datetime DEFAULT NULL
  7. ) ENGINE= InnoDB DEFAULT CHARSET=utf8mb4;

Creating The Database Connection

Open a text editor such as sublime text, notepad++, or VSCode. Create a new PHP File naming db-connect.php. Then, Copy/Paste the code below. Make sure to configure the database credentials according to your setup.

  1. <?php
  2. $host = 'localhost';
  3. $username = 'root';
  4. $password = '';
  5. $dbname ='dummy_db';
  6.  
  7. $conn = new mysqli($host, $username, $password, $dbname);
  8. if(!$conn){
  9. die("Cannot connect to the database.". $conn->error);
  10. }

Or, you can also import the SQL File I provided along with working source code file. The file is known as dummy_db.sql and located inside the db folder.

Creating The Interface

Next, we will be creating the interface of our page. The page contains the HTML elements and PHP script that shows the data and query data in the database. Copy/Paste the script below and save it as index.php.

  1. <?php require_once('db-connect.php') ?>
  2. <!DOCTYPE html>
  3. < html lang="en">
  4.  
  5. < head>
  6. < meta charset="UTF-8">
  7. < meta http-equiv="X-UA-Compatible" content="IE=edge">
  8. < meta name="viewport" content="width=device-width, initial-scale=1.0">
  9. < title>Scheduling</ title>
  10. < link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/>
  11. < link rel="stylesheet" href="./css/bootstrap.min.css">
  12. < link rel="stylesheet" href="./fullcalendar/lib/main.min.css">
  13. < script src="./js/jquery-3.6.0.min.js"></ script>
  14. < script src="./js/bootstrap.min.js"></ script>
  15. < script src="./fullcalendar/lib/main.min.js"></ script>
  16. < style>
  17. :root {
  18. --bs-success-rgb: 71, 222, 152 !important;
  19. }
  20.  
  21. html,
  22. body {
  23. height: 100%;
  24. width: 100%;
  25. font-family: Apple Chancery, cursive;
  26. }
  27.  
  28. .btn-info.text-light:hover,
  29. .btn-info.text-light:focus {
  30. background: #000;
  31. }
  32. table, tbody, td, tfoot, th, thead, tr {
  33. border-color: #ededed !important;
  34. border-style: solid;
  35. border-width: 1px !important;
  36. }
  37. </ style>
  38. </ head>
  39.  
  40. < body class="bg-light">
  41. <nav class="navbar navbar-expand-lg navbar-dark bg-dark bg-gradient" id="topNavBar">
  42. < div class="container">
  43. < a class="navbar-brand" href="https://sourcecodester.com">
  44. Sourcecodester
  45. </ a>
  46.  
  47. < div>
  48. < b class="text-light">Sample Scheduling</ b>
  49. </ div>
  50. </ div>
  51. </nav>
  52. < div class="container py-5" id="page-container">
  53. < div class="row">
  54. < div class="col-md-9">
  55. < div id="calendar"></ div>
  56. </ div>
  57. < div class="col-md-3">
  58. < div class="cardt rounded-0 shadow">
  59. < div class="card-header bg-gradient bg-primary text-light">
  60. < h5 class="card-title">Schedule Form</ h5>
  61. </ div>
  62. < div class="card-body">
  63. < div class="container-fluid">
  64. < form action="save_schedule.php" method="post" id="schedule-form">
  65. < input type="hidden" name="id" value="">
  66. < div class="form-group mb-2">
  67. < label for="title" class="control-label">Title</ label>
  68. < input type="text" class="form-control form-control-sm rounded-0" name="title" id="title" required>
  69. </ div>
  70. < div class="form-group mb-2">
  71. < label for="description" class="control-label">Description</ label>
  72. < textarea rows="3" class="form-control form-control-sm rounded-0" name="description" id="description" required></ textarea>
  73. </ div>
  74. < div class="form-group mb-2">
  75. < label for="start_datetime" class="control-label">Start</ label>
  76. < input type="datetime-local" class="form-control form-control-sm rounded-0" name="start_datetime" id="start_datetime" required>
  77. </ div>
  78. < div class="form-group mb-2">
  79. < label for="end_datetime" class="control-label">End</ label>
  80. < input type="datetime-local" class="form-control form-control-sm rounded-0" name="end_datetime" id="end_datetime" required>
  81. </ div>
  82. </ form>
  83. </ div>
  84. </ div>
  85. < div class="card-footer">
  86. < div class="text-center">
  87. < button class="btn btn-primary btn-sm rounded-0" type="submit" form="schedule-form">< i class="fa fa-save"></ i> Save</ button>
  88. < button class="btn btn-default border btn-sm rounded-0" type="reset" form="schedule-form">< i class="fa fa-reset"></ i> Cancel</ button>
  89. </ div>
  90. </ div>
  91. </ div>
  92. </ div>
  93. </ div>
  94. </ div>
  95. <!-- Event Details Modal -->
  96. < div class="modal fade" tabindex="-1" data-bs-backdrop="static" id="event-details-modal">
  97. < div class="modal-dialog modal-dialog-centered">
  98. < div class="modal-content rounded-0">
  99. < div class="modal-header rounded-0">
  100. < h5 class="modal-title">Schedule Details</ h5>
  101. < button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></ button>
  102. </ div>
  103. < div class="modal-body rounded-0">
  104. < div class="container-fluid">
  105. < dl>
  106. < dt class="text-muted">Title</ dt>
  107. < dd id="title" class="fw-bold fs-4"></ dd>
  108. < dt class="text-muted">Description</ dt>
  109. < dd id="description" class=""></ dd>
  110. < dt class="text-muted">Start</ dt>
  111. < dd id="start" class=""></ dd>
  112. < dt class="text-muted">End</ dt>
  113. < dd id="end" class=""></ dd>
  114. </ dl>
  115. </ div>
  116. </ div>
  117. < div class="modal-footer rounded-0">
  118. < div class="text-end">
  119. < button type="button" class="btn btn-primary btn-sm rounded-0" id="edit" data-id="">Edit</ button>
  120. < button type="button" class="btn btn-danger btn-sm rounded-0" id="delete" data-id="">Delete</ button>
  121. < button type="button" class="btn btn-secondary btn-sm rounded-0" data-bs-dismiss="modal">Close</ button>
  122. </ div>
  123. </ div>
  124. </ div>
  125. </ div>
  126. </ div>
  127. <!-- Event Details Modal -->
  128.  
  129. <?php
  130. $schedules = $conn->query("SELECT * FROM `schedule_list`");
  131. $sched_res = [];
  132. foreach($schedules->fetch_all(MYSQLI_ASSOC) as $row){
  133. $row['sdate'] = date("F d, Y h:i A",strtotime($row['start_datetime']));
  134. $row['edate'] = date("F d, Y h:i A",strtotime($row['end_datetime']));
  135. $sched_res[$row['id']] = $row;
  136. }
  137. ?>
  138. <?php
  139. if(isset($conn)) $conn->close();
  140. ?>
  141. </ body>
  142. < script>
  143. var scheds = $.parseJSON('<?= json_encode($sched_res) ?>')
  144. </ script>
  145. < script src="./js/script.js"></ script>
  146.  
  147. </ html>

Creating The PHP Queries

Next, we will be creating the PHP queries. The codes below is the scripts that inserts, updates, and delete event data in our database. Save the files according to the filename above each scripts.

save_schedule.php

This scripts contains the insert and update query scripts.

  1. <?php
  2. require_once('db-connect.php');
  3. if($_SERVER['REQUEST_METHOD'] !='POST'){
  4. echo "<script> alert('Error: No data to save.'); location.replace('./') </script>";
  5. $conn->close();
  6. exit;
  7. }
  8. extract($_POST);
  9. $allday = isset($allday);
  10.  
  11. if( empty($id)){
  12. $sql = "INSERT INTO `schedule_list` (`title`,`description`,`start_datetime`,`end_datetime`) VALUES ('$title','$description','$start_datetime','$end_datetime')";
  13. }else{
  14. $sql = "UPDATE `schedule_list` set `title` = '{$title}', `description` = '{$description}', `start_datetime` = '{$start_datetime}', `end_datetime` = '{$end_datetime}' where `id` = '{$id}'";
  15. }
  16. $save = $conn->query($sql);
  17. if($save){
  18. echo "<script> alert('Schedule Successfully Saved.'); location.replace('./') </script>";
  19. }else{
  20. echo "<pre>";
  21. echo "An Error occurred.<br>";
  22. echo "Error: ".$conn->error."<br>";
  23. echo "SQL: ".$sql."<br>";
  24. echo "</pre>";
  25. }
  26. $conn->close();
  27. ?>
delete_schedule.php

This scripts contains the delete query scripts.

  1. <?php
  2. require_once('db-connect.php');
  3. if(! isset($_GET['id'])){
  4. echo "<script> alert('Undefined Schedule ID.'); location.replace('./') </script>";
  5. $conn->close();
  6. exit;
  7. }
  8.  
  9. $delete = $conn->query("DELETE FROM `schedule_list` where id = '{$_GET['id']}'");
  10. if($delete){
  11. echo "<script> alert('Event has deleted successfully.'); location.replace('./') </script>";
  12. }else{
  13. echo "<pre>";
  14. echo "An Error occured.<br>";
  15. echo "Error: ".$conn->error."<br>";
  16. echo "SQL: ".$sql."<br>";
  17. echo "</pre>";
  18. }
  19. $conn->close();
  20.  
  21. ?>

Creating The Main Function

Lastly, the script below is a javascript codes that initialize the calendar, render the events in the calendar, and some other functionalities. Save this file as script.js.

  1. var calendar;
  2. var Calendar = FullCalendar.Calendar;
  3. var events = [];
  4. $(function() {
  5. if (!!scheds) {
  6. Object.keys(scheds).map(k => {
  7. var row = scheds[k]
  8. events.push({ id: row.id, title: row.title, start: row.start_datetime, end: row.end_datetime });
  9. })
  10. }
  11. var date = new Date()
  12. var d = date.getDate(),
  13. m = date.getMonth(),
  14. y = date.getFullYear()
  15.  
  16. calendar = new Calendar(document.getElementById('calendar'), {
  17. headerToolbar: {
  18. left: 'prev,next today',
  19. right: 'dayGridMonth,dayGridWeek,list',
  20. center: 'title',
  21. },
  22. selectable: true,
  23. themeSystem: 'bootstrap',
  24. //Random default events
  25. events: events,
  26. eventClick: function(info) {
  27. var _details = $('#event-details-modal')
  28. var id = info.event.id
  29. if (!!scheds[id]) {
  30. _details.find('#title').text(scheds[id].title)
  31. _details.find('#description').text(scheds[id].description)
  32. _details.find('#start').text(scheds[id].sdate)
  33. _details.find('#end').text(scheds[id].edate)
  34. _details.find('#edit,#delete').attr('data-id', id)
  35. _details.modal('show')
  36. } else {
  37. alert("Event is undefined");
  38. }
  39. },
  40. eventDidMount: function(info) {
  41. // Do Something after events mounted
  42. },
  43. editable: true
  44. });
  45.  
  46. calendar.render();
  47.  
  48. // Form reset listener
  49. $('#schedule-form').on('reset', function() {
  50. $(this).find('input:hidden').val('')
  51. $(this).find('input:visible').first().focus()
  52. })
  53.  
  54. // Edit Button
  55. $('#edit').click(function() {
  56. var id = $(this).attr('data-id')
  57. if (!!scheds[id]) {
  58. var _form = $('#schedule-form')
  59. console.log(String(scheds[id].start_datetime), String(scheds[id].start_datetime).replace(" ", "\\t"))
  60. _form.find('[name="id"]').val(id)
  61. _form.find('[name="title"]').val(scheds[id].title)
  62. _form.find('[name="description"]').val(scheds[id].description)
  63. _form.find('[name="start_datetime"]').val(String(scheds[id].start_datetime).replace(" ", "T"))
  64. _form.find('[name="end_datetime"]').val(String(scheds[id].end_datetime).replace(" ", "T"))
  65. $('#event-details-modal').modal('hide')
  66. _form.find('[name="title"]').focus()
  67. } else {
  68. alert("Event is undefined");
  69. }
  70. })
  71.  
  72. // Delete Button / Deleting an Event
  73. $('#delete').click(function() {
  74. var id = $(this).attr('data-id')
  75. if (!!scheds[id]) {
  76. var _conf = confirm("Are you sure to delete this scheduled event?");
  77. if (_conf === true) {
  78. location.href = "./delete_schedule.php?id=" + id;
  79. }
  80. } else {
  81. alert("Event is undefined");
  82. }
  83. })
  84. })

DEMO VIDEO

That's it! You can now test the application in your browser and see if we have met our goal on this tutorial. If ever you have encountered any errors, please review your source code by differentiating it from the source code I provided above. You can also test the working source code I created for this tutorial. You can download the source code zip file below this article.

That is the end of this tutorial. I hope you'll find this Tutorial useful for your current and future PHP projects.

Happy Coding :)

Tags

Comments

Submitted byUwe (not verified)on Fri, 02/04/2022 - 01:31

资讯网旅游业营销推广方案起四个字名字的大气中介公司起名两页作文设计网站的基本流程起一个名seo快排怎么周公解梦分析禹字可以用来起名吗比较有趣的小名叫起来好听的酷博士seo搜索技巧企业公司网站制作建设八卦易经在线起名诗经楚辞周易取名男孩马可街头流行馆餐饮进货表网站建设布吉周公解梦全书原文2019年猪女宝宝起名大全宁陵撤县设区2018年生孩子起名男孩制作网站建成的公司贴对联的左右顺序seo每一天起名字女孩免费最新1518八字起名袁 起名字微信个性签名空白拉长qq个性签名大全伤感的少年生前被连续抽血16次?多部门介入两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”淀粉肠小王子日销售额涨超10倍高中生被打伤下体休学 邯郸通报单亲妈妈陷入热恋 14岁儿子报警何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言张家界的山上“长”满了韩国人?男孩8年未见母亲被告知被遗忘中国拥有亿元资产的家庭达13.3万户19岁小伙救下5人后溺亡 多方发声315晚会后胖东来又人满为患了张立群任西安交通大学校长“重生之我在北大当嫡校长”男子被猫抓伤后确诊“猫抓病”测试车高速逃费 小米:已补缴周杰伦一审败诉网易网友洛杉矶偶遇贾玲今日春分倪萍分享减重40斤方法七年后宇文玥被薅头发捞上岸许家印被限制高消费萧美琴窜访捷克 外交部回应联合利华开始重组专访95后高颜值猪保姆胖东来员工每周单休无小长假男子被流浪猫绊倒 投喂者赔24万小米汽车超级工厂正式揭幕黑马情侣提车了西双版纳热带植物园回应蜉蝣大爆发当地回应沈阳致3死车祸车主疑毒驾恒大被罚41.75亿到底怎么缴妈妈回应孩子在校撞护栏坠楼外国人感慨凌晨的中国很安全杨倩无缘巴黎奥运校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变王树国卸任西安交大校长 师生送别手机成瘾是影响睡眠质量重要因素国产伟哥去年销售近13亿阿根廷将发行1万与2万面值的纸币兔狲“狲大娘”因病死亡遭遇山火的松茸之乡“开封王婆”爆火:促成四五十对奥巴马现身唐宁街 黑色着装引猜测考生莫言也上北大硕士复试名单了德国打算提及普京时仅用姓名天水麻辣烫把捣辣椒大爷累坏了

资讯网 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化