Learning FullCalendar Part 2: Building Your First Calendar App
Tags: javascript, php, laravel
Published: 2023-10-14 21:03:53

This is Part 2 of the FullCalendar blog articles. The previous one covered the very basics to get you started. In this blog post, I'll focus on practical aspects and share some of the code I applied in my project.

My task was to concentrate solely on rendering dates with events, without incorporating features such as creating, editing, dragging, or deleting. To keep it simple, I opted for hard-coded data for events instead of setting up a database.

Additionally, the task required the calendar to be displayed in Japanese, and I'll share the relevant code for achieving this. Notably, I won't be using jQuery.

Let's get started.
(The final demo is available at the bottom.)

Laravel 10
Livewire v.3
FullCalendar v.6 

**Initialization**

calendar.blade.php

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vr2av51ww9h4fvfmxhx4.jpeg)

I used the following code for `validRange`:

```
  validRange: function(nowDate) {
    return {
      start: nowDate,
      end: nowDate.clone().add(1, 'months')
    };
  }
```

Unfortunately, this code resulted in an error, specifically, "nowDate.clone is not a function." To work around this issue and achieve my intended functionality of keeping the end date open, I modified the code to include only the start date:

```
validRange: function(nowDate) {
    return {
        start: nowDate,
    };
}
```
With this adjustment, I can select dates starting from `nowDate` while leaving the end date open.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cpq8e2p7fqsr4bs6x5v3.jpeg)

**events**

```
public $events = [
    [
        'id' => 101,
        'start' => '2023-09-20',
        'display' => 'background'
    ],
...
];
```

In my case:
`title` is not needed because event names should not be displayed.
`display` => `background` is necessary to highlight the dates with events.
`allDay` might not be necessarily defined because a date will be highlighted with the setup of `display` => `background` even though the event is shown in the `all-day` section of relevant views.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/puvpzfcrmxct45gg81ie.jpeg)

The `@json` directive is used to convert the PHP array into its JSON representation.
The `events` configuration option specifies the source of events to be displayed on the calendar. 
In this example, a hardcoded dataset is used, but it is common practice to store and retrieve data from a database or any other desired structure. 
Since the `$events` variable is set to public, the events are rendered when the DOM is loaded.

```
public function mount()
{
    $this->getEvent();
}

public function getEvent()
{
    // Query data from the database
}
```

Calendar.php

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0m2routtjp0s09mvuz81.jpeg)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y35xbyjz27akhnq9bdlu.jpeg)

Here are some functions for controlling the calendar.

**dateClick**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aek5k5wot3jq5jkpudrl.jpeg)

 `dateClick` triggers when the user clicks on a date or a time.
`function( dateClickInfo ) { }`
`dateClickInfo` has properties such as `date` and a useful one `dateStr` (e.g., '2023-10-01') that can be sent to the backend.

I wanted to add a red border around the clicked date, and we can achieve this by applying a `classname` defined separately in the style tag. Additionally, I wanted to display only the events that occur on or after the selected day, which is handled by a function defined in the backend using the `selectedDay`.

Let's take a look at what `info` has:
```
dateClick: function (info) {
       console.log('info', info);
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ytt81hanw4sm8fwprlfv.jpeg)

**datesSet**

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3ldhk71i38xkkhqhv7qs.jpeg)

`datesSet` is "[c]alled after the calendar’s date range has been initially set or changed in some way and the DOM has been updated."
`function( dateInfo )`
`dateInfo` has properties such as `start`, `end`, `startStr`, and `view`. The View Object contains information about the calendar view, including `title` that I can use to retrieve the current month.

When clicking a day or the next button to navigate to a different month, the calendar disappears briefly after the view changes. I attempted to use `refetchEvents` and added a new function to retrieve updated data, but these solutions didn't work. The new version of FullCalendar will handle data fetching automatically. The issue was that I had forgotten to use `wire:ignore`.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wen1046f5d9f6okakp54.jpeg)

The `wire:ignore` directive in Livewire is used to instruct Livewire to ignore a specific portion of the DOM during Livewire component updates.  This is necessary because FullCalendar is a JavaScript library that manages its own rendering and event handling. When you integrate FullCalendar into a Livewire component, not using `wire:ignore` can lead to Livewire attempting to re-render the FullCalendar component when the Livewire component state changes, causing issues with FullCalendar's functionality.

This is the final version of the app. I believe it's simplified enough to demonstrate the basic usage. Please pardon the design:)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/66ewc4hxv88but1g8i5z.jpeg)