diff --git a/README.md b/README.md
index 6959137..83dab11 100644
--- a/README.md
+++ b/README.md
@@ -66,7 +66,9 @@ use Saade\FilamentFullCalendar\Widgets\FullCalendarWidget;
class CalendarWidget extends FullCalendarWidget
{
-
+ /**
+ * Return events that should be rendered statically on calendar first render.
+ */
public function getViewData(): array
{
return [
@@ -84,10 +86,22 @@ class CalendarWidget extends FullCalendarWidget
]
];
}
+
+ /**
+ * FullCalendar will call this function whenever it needs new event data.
+ * This is triggered when the user clicks prev/next or switches views on the calendar.
+ */
+ public function fetchEvents(array $fetchInfo, array $ignorableIds): array
+ {
+ // You can use $fetchInfo to filter events by date, and $ignorableIds to ignore already displayed events.
+ return [];
+ }
}
```
-> You should return an array of FullCalendar [EventObject](https://fullcalendar.io/docs/event-object).
+You can use one or both methods to fetch events.
+
+> Both methods should retun an array of [EventObject](https://fullcalendar.io/docs/event-object).
@@ -132,7 +146,7 @@ return [
# Listening for events
-The only events supported right now are: [EventClick](https://fullcalendar.io/docs/eventClick) and [EventDrop](https://fullcalendar.io/docs/eventDrop)
+The only event-related events supported right now are: [EventClick](https://fullcalendar.io/docs/eventClick) and [EventDrop](https://fullcalendar.io/docs/eventDrop)
They're commented out by default so livewire does not spam requests without they being used. You are free to paste them in your `CalendarWidget` class. See: [FiresEvents](https://github.com/saade/filament-fullcalendar/blob/main/src/Widgets/Concerns/FiresEvents.php)
@@ -171,7 +185,14 @@ The process of saving and editing the event is up to you, since this plugin does
## Creating Events:
-Override the `createEvent` function in your widget class, and you are ready to go!
+Events can be created in two ways.
+
+- Clicking on a day (default)
+- Selecting a date range (click and drag across calendar days) (you need to opt-in for this, set `selectable => true` in the config file.)
+
+This will open the Create Event modal.
+
+When the create form gets submitted, it will call the `createEvent` function on your widget. Be sure to add the snippet below to your calendar class.
```php
public function createEvent(array $data): void
@@ -200,7 +221,11 @@ protected static function getCreateEventFormSchema(): array
## Editing Events:
-Override the `editEvent` function in your widget class, and you are ready to go!
+Events can be edited by clicking on an event on the calendar.
+
+This will open the Edit Event modal.
+
+When the edit form gets submitted, it will call the `editEvent` function on your widget. Be sure to add the snippet below to your calendar class.
```php
public function editEvent(array $data): void
@@ -271,6 +296,50 @@ public function yourMethod(): void
+# Filtering events based on the calendar view
+
+If you want to filter your events based on the days that are currently shown in the calendar, you can implement the `fetchInfo()` method from the [CanFetchEvents](https://github.com/saade/filament-fullcalendar/blob/main/src/Widgets/Concerns/CanFetchEvents.php) trait. Add the following code to your calendar widget:
+
+```php
+/**
+ * FullCalendar will call this function whenever it needs new event data.
+ * This is triggered when the user clicks prev/next or switches views.
+ *
+ * @see https://fullcalendar.io/docs/events-function
+ * @param array $fetchInfo start and end date of the current view
+ * @param array $ignorableIds ids of the events that are already loaded and should be ignored
+ */
+public function fetchEvents(array $fetchInfo, array $ignorableIds): array
+{
+ return [];
+}
+```
+
+you can filter events based on the timespan `$fetchInfo['start']` and `$fetchInfo['end']`.
+> **Warning**
+>
+> Keep in mind that returning events that are already in the calendar, can cause duplicates. You should filter them out using the `$ignorableIds` ids.
+
+example:
+```php
+public function fetchEvents(array $fetchInfo, array $ignorableIds): array
+{
+ $schedules = Appointment::query()
+ ->where([
+ ['start_at', '>=', $fetchInfo['start']],
+ ['end_at', '<', $fetchInfo['end']],
+ ])
+ ->whereNotIn('id', $ignorableIds)
+ ->get();
+
+ $data = $schedules->map( ... );
+
+ return $data;
+}
+```
+
+
+
## Testing
```bash
diff --git a/resources/views/fullcalendar.blade.php b/resources/views/fullcalendar.blade.php
index 7103ce9..032f68e 100644
--- a/resources/views/fullcalendar.blade.php
+++ b/resources/views/fullcalendar.blade.php
@@ -1,4 +1,4 @@
-@php($locale = strtolower(str_replace('_', '-', $this->getConfig()['locale'])))
+@php($locale = strtolower(str_replace('_', '-', $this->config('locale', config('app.locale')))))
@@ -8,8 +8,11 @@
x-init='
document.addEventListener("DOMContentLoaded", function() {
const config = @json($this->getConfig());
- const events = @json($events);
const locale = "{{ $locale }}";
+ const events = @json($events);
+ const cachedEventIds = [
+ ...events.map(event => event.id),
+ ];
const eventClick = function ({ event, jsEvent }) {
if( event.url ) {
@@ -41,21 +44,40 @@
@endif
}
+ const fetchEvents = function ({ start, end }, successCallback, failureCallback) {
+ @if( $this::canFetchEvents() )
+ return $wire.fetchEvents({ start, end }, cachedEventIds)
+ .then(events => {
+ // Cache fetched events
+ cachedEventIds.push(...events.map(event => event.id));
+
+ return successCallback(events);
+ })
+ .catch( failureCallback );
+ @else
+ return successCallback([]);
+ @endif
+ }
+
const calendar = new FullCalendar.Calendar($el, {
...config,
locale,
- events,
eventClick,
eventDrop,
dateClick,
select,
+ eventSources:[
+ { events },
+ fetchEvents
+ ]
});
calendar.render();
- window.addEventListener("filament-fullcalendar:refresh", (event) => {
+ window.addEventListener("filament-fullcalendar:refresh", () => {
calendar.removeAllEvents();
- event.detail.data.map(event => calendar.addEvent(event));
+ cachedEventIds.length = 0;
+ calendar.refetchEvents();
});
})
'>
diff --git a/src/Widgets/Concerns/CanFetchEvents.php b/src/Widgets/Concerns/CanFetchEvents.php
new file mode 100644
index 0000000..9a6b724
--- /dev/null
+++ b/src/Widgets/Concerns/CanFetchEvents.php
@@ -0,0 +1,25 @@
+dispatchBrowserEvent('filament-fullcalendar:refresh', ['data' => $this->getViewData()]);
+ $this->dispatchBrowserEvent('filament-fullcalendar:refresh');
}
}
diff --git a/src/Widgets/Contracts/LazyLoading.php b/src/Widgets/Contracts/LazyLoading.php
new file mode 100644
index 0000000..c81994b
--- /dev/null
+++ b/src/Widgets/Contracts/LazyLoading.php
@@ -0,0 +1,8 @@
+