CakePHP 4 FullCalendar Ajax CRUD Tutorial Example

Reading Time: 11 minutes
4,225 Views

In most applications we need sometime a schedule calendar so that we can add our tasks, events, functions. Those scheduled tasks act like a reminder to the calendar. This feature is very interesting to implement if you are providing adding events to your clients, users, etc.

Inside this article we will see the complete concept of CakePHP 4 fullcalendar ajax CRUD tutorial. This article is super easy to learn and implement in your code as well.

FullCalendar is a jquery plugin by the help of which we can display a calendar to webpage. Even we can create events, appointments etc on a specific date, update existing data, delete data etc. All CRUD operations we can easily manage from it’s interface.

This is not CakePHP 4 specific feature, you can use it in any version of CakePHP.

Learn More –

Let’s get started.

CakePHP 4 Installation

To create a CakePHP project, run this command into your shell or terminal. Make sure composer should be installed in your system.

$ composer create-project --prefer-dist cakephp/app:~4.0 mycakephp

Above command will creates a project with the name called mycakephp.

Create Database

To create a database, either we can create via Manual tool of PhpMyadmin or by means of a mysql command.

CREATE DATABASE mydatabase;

Successfully, we have created a database.

Database Connection

Open app_local.php file from /config folder. Search for Datasources. Go to default array of it.

You can add your connection details here to connect with your database. It will be like this –

//...

'Datasources' => [
        'default' => [
            'host' => 'localhost',
            /*
             * CakePHP will use the default DB port based on the driver selected
             * MySQL on MAMP uses port 8889, MAMP users will want to uncomment
             * the following line and set the port accordingly
             */
            //'port' => 'non_standard_port_number',

            'username' => 'root',
            'password' => 'sample@123',

            'database' => 'mydatabase',
            /*
             * If not using the default 'public' schema with the PostgreSQL driver
             * set it here.
             */
            //'schema' => 'myapp',

            /*
             * You can use a DSN string to set the entire configuration
             */
            'url' => env('DATABASE_URL', null),
        ],
  
     //...

//...

You can pass host, username, password and database.

Successfully, you are now connected with the database.

Create Migration

Open project into terminal and run this command to create migration file.

$ bin/cake bake migration CreateEvents

It will create 20220330143909_CreateEvents.php file inside /config/Migrations folder. Open migration file and write this following code into it.

The code is all about for the schema of events table.

<?php

declare(strict_types=1);

use Migrations\AbstractMigration;

class CreateEvents extends AbstractMigration
{
    public function change()
    {
        $table = $this->table('events');

        $table->addColumn("title", "string", [
            "limit" => 120,
            "null" => false
        ]);

        $table->addColumn("start", "date", [
            "null" => false
        ]);

        $table->addColumn("end", "date", [
            "null" => false
        ]);

        $table->create();
    }
}

Run Migration

Back to terminal and run this command.

$ bin/cake migrations migrate

It will create events table inside database.

Create Model & Entity

Next,

We will create model and entity. Back to terminal and run this command.

$ bin/cake bake model Events --no-validation --no-rules

It will create model file EventsTable.php inside /src/Model/Table folder. Also we should see the entity file Event.php inside /src/Model/Entity folder.

Create Controller

Open project into terminal and run this command into it.

$ bin/cake bake controller Fullcalendar --no-actions

It will create FullcalendarController.php file inside /src/Controller folder. Open controller file and write this code into it.

<?php

declare(strict_types=1);

namespace App\Controller;

class FullcalendarController extends AppController
{
    public function initialize(): void
    {
        parent::initialize();
        $this->loadModel("Events");
    }

    public function myEvents()
    {
        // FullCalendar in frontend
    }

    public function loadData()
    {
        if ($this->request->is("ajax")) {
            // on page load this ajax code block will be run
            $data = $this->Events->find()->where([
                'start >=' => $this->request->getQuery('start'),
                'end <=' => $this->request->getQuery('end')
            ])->toList();

            echo json_encode($data);
        }
        die;
    }

    public function ajax()
    {
        if ($this->request->is("ajax")) {

            switch ($this->request->getData('type')) {

                    // For add event
                case 'add':
                    $event = $this->Events->newEmptyEntity();

                    $event = $this->Events->patchEntity($event, $this->request->getData());

                    if ($this->Events->save($event)) {
                        echo json_encode([
                            "status" => 1,
                            "message" => "Event added successfully"
                        ]);
                    }

                    echo json_encode([
                        "status" => 0,
                        "message" => "Failed to add event"
                    ]);
                    die;
                    break;

                    // For update event        
                case 'update':

                    $event = $this->Events->get($this->request->getData("id"));

                    $event = $this->Events->patchEntity($event, $this->request->getData());

                    if ($this->Events->save($event)) {
                        echo json_encode([
                            "status" => 1,
                            "message" => "Event updated successfully"
                        ]);
                    }

                    echo json_encode([
                        "status" => 0,
                        "message" => "Failed to update event"
                    ]);
                    die;
                    break;

                    // For delete event    
                case 'delete':

                    $event = $this->Events->get($this->request->getData("id"));

                    if ($this->Events->delete($event)) {
                        echo json_encode([
                            "status" => 1,
                            "message" => "Event deleted successfully"
                        ]);
                    }

                    echo json_encode([
                        "status" => 0,
                        "message" => "Failed to delete event"
                    ]);
                    die;
                    break;

                default:
                    break;
            }
        }
    }
}

Inside above code, we have three methods –

  • myEvents() method for frontend layout of fullcalendar.
  • loadData() method responsible to load data into fullcalendar when it loads for first time via ajax request.
  • ajax() method for operating with the events function like insert, update, delete, select.

Create Template

Create Fullcalendar folder inside /templates folder. Next, needs to create my_events.php file inside /templates/Fullcalendar folder.

Open my_events.php file and write this following code into it. This will give the frontend layout for fullcalendar.

<!DOCTYPE html>
<html>

<head>
    <title>CakePHP 4 Fullcalender Tutorial - Online Web Tutor</title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

    <!--fullcalendar plugin files -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.9.0/fullcalendar.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.9.0/fullcalendar.js"></script>

    <!-- for plugin notification -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script>
</head>

<body>

    <div class="container">
        <h3 style="text-align: center">CakePHP 4 Fullcalendar Tutorial - Online Web Tutor</h3>
        <div id="calendar"></div>
    </div>

    <script>
        $(document).ready(function() {

            var calendar = $('#calendar').fullCalendar({
                editable: true,
                events: "/event",
                displayEventTime: false,
                editable: true,
                eventRender: function(event, element, view) {
                    if (event.allDay === 'true') {
                        event.allDay = true;
                    } else {
                        event.allDay = false;
                    }
                },
                selectable: true,
                selectHelper: true,
                select: function(start, end, allDay) {

                    var title = prompt('Event Title:');

                    if (title) {
                        var start = $.fullCalendar.formatDate(start, "Y-MM-DD");
                        var end = $.fullCalendar.formatDate(end, "Y-MM-DD");
                        $.ajax({
                            url: "/eventAjax",
                            data: {
                                title: title,
                                start: start,
                                end: end,
                                type: 'add'
                            },
                            type: "POST",
                            success: function(data) {
                                displayMessage("Event Created Successfully");

                                calendar.fullCalendar('renderEvent', {
                                    id: data.id,
                                    title: title,
                                    start: start,
                                    end: end,
                                    allDay: allDay
                                }, true);

                                calendar.fullCalendar('unselect');
                            }
                        });
                    }
                },

                eventDrop: function(event, delta) {
                    var start = $.fullCalendar.formatDate(event.start, "Y-MM-DD");
                    var end = $.fullCalendar.formatDate(event.end, "Y-MM-DD");

                    $.ajax({
                        url: '/eventAjax',
                        data: {
                            title: event.title,
                            start: start,
                            end: end,
                            id: event.id,
                            type: 'update'
                        },
                        type: "POST",
                        success: function(response) {

                            displayMessage("Event Updated Successfully");
                        }
                    });
                },
                
                eventClick: function(event) {
                    var deleteMsg = confirm("Do you really want to delete?");
                    if (deleteMsg) {
                        $.ajax({
                            type: "POST",
                            url: '/eventAjax',
                            data: {
                                id: event.id,
                                type: 'delete'
                            },
                            success: function(response) {

                                calendar.fullCalendar('removeEvents', event.id);
                                displayMessage("Event Deleted Successfully");
                            }
                        });
                    }
                }

            });

        });

        function displayMessage(message) {
            toastr.success(message, 'Event');
        }
    </script>

</body>

</html>

Above template file contains all code for fullcalendar. It fires an ajax request for each operations like Insert, Update, Delete & Load.

In the above template also we have included the plugin files for fullcalendar and for jquery notifications.

Disable CSRF Token

When we submit a cakephp form, it needs a CSRF token should be submitted with form submission request.

We are not interested to send CSRF token with form data. To disable it, Open Application.php from /src folder.

Remove these lines of code from middleware() method.

->add(new CsrfProtectionMiddleware([
    'httponly' => true,
]))

Add Route

Open routes.php file from /config folder. Add these routes into it.

//...

$routes->connect(
    '/fullcalendar',
    ['controller' => 'Fullcalendar', 'action' => 'myEvents']
);

$routes->connect(
    '/event',
    ['controller' => 'Fullcalendar', 'action' => 'loadData']
);

$routes->connect(
    '/eventAjax',
    ['controller' => 'Fullcalendar', 'action' => 'ajax']
);

//...

Application Testing

Open terminal and run this command to start development server.

$ bin/cake server

URL: http://localhost:8765/fullcalendar

Frontend

Create Event

Click on any date, add and save your event.

In database events table, you will see the events as –

Update Event

To update any event, Simple you can move (drag and drop) that event into any of your date. It will be automatically updated.

Delete Event

To delete, simple click on event and confirm via javascript alert box. It will delete automatically via ajax request.

We hope this article helped you to learn about CakePHP 4 FullCalendar Ajax CRUD Tutorial Example in a very detailed way.

Online Web Tutor invites you to try Skillshike! Learn CakePHP, Laravel, CodeIgniter, Node Js, MySQL, Authentication, RESTful Web Services, etc into a depth level. Master the Coding Skills to Become an Expert in PHP Web Development. So, Search your favourite course and enroll now.

If you liked this article, then please subscribe to our YouTube Channel for PHP & it’s framework, WordPress, Node Js video tutorials. You can also find us on Twitter and Facebook.

Sanjay KumarHello friends, I am Sanjay Kumar a Web Developer by profession. Additionally I'm also a Blogger, Youtuber by Passion. I founded Online Web Tutor and Skillshike platforms. By using these platforms I am sharing the valuable knowledge of Programming, Tips and Tricks, Programming Standards and more what I have with you all. Read more