Laravel Appointment Calendar: Simple FullCalendar Demo

Working with a calendar can be quite common, so in this tutorial, we will use the popular FullCalendar library in a Laravel project and create a simple demo.

The demo is simple - to show a calendar of the appointments for the upcoming week. It can be used for any kind of appointment: doctors, hair salons, etc.

fullcalendar with events


Prepare Laravel Application

For this tutorial, we will use our own Laravel Breeze Skeleton that gives us a simple design.

breeze skeleton

Next, we will quickly create three Models with their Migrations: Appointment, Client, and Employee:

1php artisan make:model Client -m
2php artisan make:model Employee -m
3php artisan make:model Appointment -m

create_clients_table.php:

1return new class extends Migration {
2 public function up()
3 {
4 Schema::create('clients', function (Blueprint $table) {
5 $table->id();
6 $table->string('name');
7 $table->timestamps();
8 });
9 }
10};

app/Models/Client.php:

1class Client extends Model
2{
3 protected $fillable = ['name'];
4}

create_employees_table.php:

1return new class extends Migration {
2 public function up()
3 {
4 Schema::create('employees', function (Blueprint $table) {
5 $table->id();
6 $table->string('name');
7 $table->timestamps();
8 });
9 }
10};

app/Models/Employee.php:

1class Employee extends Model
2{
3 protected $fillable = ['name'];
4}

create_appointments_table.php:

1return new class extends Migration {
2 public function up()
3 {
4 Schema::create('appointments', function (Blueprint $table) {
5 $table->id();
6 $table->datetime('start_time');
7 $table->datetime('finish_time');
8 $table->longText('comments')->nullable();
9 $table->foreignId('client_id')->constrained();
10 $table->foreignId('employee_id')->constrained();
11 $table->timestamps();
12 });
13 }
14};

app/Models/Appointment.php:

1class Appointment extends Model
2{
3 protected $fillable = [
4 'start_time',
5 'finish_time',
6 'comments',
7 'client_id',
8 'employee_id',
9 ];
10 
11 public function client(): BelongsTo
12 {
13 return $this->belongsTo(Client::class);
14 }
15 
16 public function employee(): BelongsTo
17 {
18 return $this->belongsTo(Employee::class);
19 }
20}

Ok, so we have the data structure. Now, let's show it on the calendar.


Prepare FullCalendar

Before showing the calendar, we need to add the Fullcalendar library to our app. For this demo, we will use the link from CDN. In layouts/app.blade.php of Laravel Breeze, add a @stack('scripts') blade directive before the </body> tag.

1 @stack('scripts')
2 </body>
3</html>

Next, we will show the calendar on the home page. For that, we will create an invokable HomeController and modify routes\web.php to use that controller for the home page.

1php artisan make:controller HomeController --invokable

routes/web.php:

1Route::get('/', function () {
2 return view('home');
3})->name('home');
4Route::get('/', \App\Http\Controllers\HomeController::class)->name('home');

Now, the calendar will be shown in resources/views/home.blade.php. In that View, let's add a div with the ID of calendar:

1<div id="calendar"></div>

This ID will be used to tell FullCalendar, where exactly to show the calendar.

Next, in the same home.blade.php View file, before </x-app-layout>, add a Blade tag @push('scripts') and a FullCalendar CDN link inside it.

1 @push('scripts')
2 <script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.11.3/main.min.js"></script>
3 @endpush
4</x-app-layout>

Showing Events in the Calendar

To show all events, the back-end logic will go into HomeController.

app/Http/Controllers/HomeController.php:

1class HomeController extends Controller
2{
3 public function __invoke()
4 {
5 $events = [];
6 
7 $appointments = Appointment::with(['client', 'employee'])->get();
8 
9 foreach ($appointments as $appointment) {
10 $events[] = [
11 'title' => $appointment->client->name . ' ('.$appointment->employee->name.')',
12 'start' => $appointment->start_time,
13 'end' => $appointment->finish_time,
14 ];
15 }
16 
17 return view('home', compact('events'));
18 }
19}

Here we take all Appointments and put them into an array that gets passed to the view. Array keys title, start, and end are taken from the official documentation. You can pass more parameters like text color or background color. For more options, read the official documentation.

Next, in the resources/views/home.blade.php, after FullCalendar CDN we will add JS code to show the calendar.

1 @push('scripts')
2 <script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.11.3/main.min.js"></script>
3 <script>
4 document.addEventListener('DOMContentLoaded', function () {
5 var calendarEl = document.getElementById('calendar');
6 var calendar = new FullCalendar.Calendar(calendarEl, {
7 initialView: 'timeGridWeek',
8 slotMinTime: '8:00:00',
9 slotMaxTime: '19:00:00',
10 events: @json($events),
11 });
12 calendar.render();
13 });
14 </script>
15 @endpush
16</x-app-layout>

Here we added code identical to the one from Fullcalendar official documentation, but with extra configuration.

We change the initialView to timeGridWeek to show events by week, again - check official documentation for other options.

Then we add slotMinTime and slotMaxTime, which will show times in the calendar only for a specified time: in our case, from 8 am to 7 pm.

And, of course, we add the events themselves, with @json.

Now, if you add some appointments to the database and visit your projects home page, you would see events in the calendar. For example, data like below:

appointments in db

It would transform into a calendar like this:

fullcalendar with events


As you can see, it isn't hard to show events or whatever you need in the calendar using FullCalendar. If you need more customizations, read the official documentation.

No comments or questions yet...

Like our articles?

Become a Premium Member for $129/year or $29/month

Written by