FullCalendar.js is a JavaScript event calendar customizable and open source. You can display a full-size event calendar that also compatible with google calendar.
Download tattali/CalendarBundle
using composer
$ composer require tattali/calendar-bundle
The recipe will import the routes for you
Check the existence of the file config/routes/calendar.yaml
or create it
# config/routes/calendar.yaml
calendar:
resource: "@CalendarBundle/Resources/config/routing.yaml"
NOTE : This guide explains how to use the bundle with doctrine ORM (
composer req symfony/orm-pack
) but you can use any other storage driver.
To load events into the calendar, you must create a listener class and select your events.
Edit the current query to select your own events
// src/EventSubscriber/CalendarSubscriber.php
<?php
namespace App\EventSubscriber;
use App\Repository\BookingRepository;
use CalendarBundle\CalendarEvents;
use CalendarBundle\Entity\Event;
use CalendarBundle\Event\CalendarEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class CalendarSubscriber implements EventSubscriberInterface
{
private $bookingRepository;
private $router;
public function __construct(
BookingRepository $bookingRepository,
UrlGeneratorInterface $router
) {
$this->bookingRepository = $bookingRepository;
$this->router = $router;
}
public static function getSubscribedEvents()
{
return [
CalendarEvents::SET_DATA => 'onCalendarSetData',
];
}
public function onCalendarSetData(CalendarEvent $calendar)
{
$start = $calendar->getStart();
$end = $calendar->getEnd();
$filters = $calendar->getFilters();
// Modify the query to fit to your entity and needs
// Change booking.beginAt by your start date property
$bookings = $this->bookingRepository
->createQueryBuilder('booking')
->where('booking.beginAt BETWEEN :start and :end OR booking.endAt BETWEEN :start and :end')
->setParameter('start', $start->format('Y-m-d H:i:s'))
->setParameter('end', $end->format('Y-m-d H:i:s'))
->getQuery()
->getResult()
;
foreach ($bookings as $booking) {
// this create the events with your data (here booking data) to fill calendar
$bookingEvent = new Event(
$booking->getTitle(),
$booking->getBeginAt(),
$booking->getEndAt() // If the end date is null or not defined, a all day event is created.
);
/*
* Add custom options to events
*
* For more information see: https://fullcalendar.io/docs/event-object
* and: https://github.com/fullcalendar/fullcalendar/blob/master/src/core/options.ts
*/
$bookingEvent->setOptions([
'backgroundColor' => 'red',
'borderColor' => 'red',
]);
$bookingEvent->addOption(
'url',
$this->router->generate('booking_show', [
'id' => $booking->getId(),
])
);
// finally, add the event to the CalendarEvent to fill the calendar
$calendar->addEvent($bookingEvent);
}
}
}
Include the calendar-holder were you want to display the calendar:
<div id="calendar-holder"></div>
Add styles and js. Click here to see other css and js download methods
{% block stylesheets %}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fullcalendar/[email protected]/main.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fullcalendar/[email protected]/main.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fullcalendar/[email protected]/main.min.css">
{% endblock %}
{% block javascripts %}
<script src="https://cdn.jsdelivr.net/npm/@fullcalendar/[email protected]/main.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@fullcalendar/[email protected]/main.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@fullcalendar/[email protected]/main.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@fullcalendar/[email protected]/main.min.js"></script>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', () => {
var calendarEl = document.getElementById('calendar-holder');
var calendar = new FullCalendar.Calendar(calendarEl, {
defaultView: 'dayGridMonth',
editable: true,
eventSources: [
{
url: "{{ path('fc_load_events') }}",
method: "POST",
extraParams: {
filters: JSON.stringify({})
},
failure: () => {
// alert("There was an error while fetching FullCalendar!");
},
},
],
header: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay',
},
plugins: [ 'interaction', 'dayGrid', 'timeGrid' ], // https://fullcalendar.io/docs/plugin-index
timeZone: 'UTC',
});
calendar.render();
});
</script>
{% endblock %}
You may want to customize the FullCalendar javascript to meet your applications needs. To do this, see the official fullcalendar documentation or also the allow create, update and delete events in the bundle.
Hi, I am not sure to understand what you need to do, but to pass extra parameters, you can use filters
in your front template
in the subscriber