diff --git a/README.md b/README.md index 9866dd4..fa27701 100644 --- a/README.md +++ b/README.md @@ -211,6 +211,30 @@ Event::make() ->extendedProps(['baz' => 'qux', 'quux' => 'corge']); ``` +## Available Methods + +### Refresh events +If you need to trigger a refresh of the events in the calendar, you can call `refreshRecords()` on the widget. + +```php +$this->refreshRecords(); +``` + +### Refresh resources +If you need to trigger a refresh of the resources in the calendar, you can call `refreshResources()` on the widget. + +```php +$this->refreshResources(); +``` + +### Set Option +To change any calendar option during runtime, you can use the `setOption()` method on the widget. + +For example to programmatically change the date, you can use: +```php +$this->setOption('date', today()->addDay()->toIso8601String()); +``` + ## Custom Event Content By default, we use the default view from the calendar package. However, you are able to use your own by overriding the `getEventContent` method on your calendar widget class. @@ -252,6 +276,20 @@ public function getEventContent(): null|string|array } ``` +## Custom resource label content +By default, we use the default view from the calendar package. However, you are able to use your own by overriding the `getResourceLabelContent` method on your calendar widget class. + +```php +public function getResourceLabelContent(): null|string|array +{ + // return a blade view + return view('calendar.resource'); + + // return a HtmlString + return new HtmlString('
My resource
'); +} +``` + ## Customize the form schema When an event triggers an action (such as view or edit actions), a modal with a form is mounted. diff --git a/dist/js/calendar-widget.js b/dist/js/calendar-widget.js index 73b716a..3e36d78 100644 --- a/dist/js/calendar-widget.js +++ b/dist/js/calendar-widget.js @@ -1 +1 @@ -function g({view:o="dayGridMonth",locale:w="en",firstDay:E=1,events:b=[],eventContent:l=null,resourceLabelContent:s=null,selectable:j=!1,eventClickEnabled:h=!1,eventDragEnabled:i=!1,eventResizeEnabled:c=!1,noEventsClickEnabled:p=!1,dateSelectEnabled:u=!1,dateClickEnabled:y=!1,viewDidMountEnabled:m=!1,dayMaxEvents:f=!1,moreLinkContent:v=null,resources:C=[],hasDateClickContextMenu:D=!1,hasDateSelectContextMenu:S=!1,hasEventClickContextMenu:x=!1,hasNoEventsClickContextMenu:k=!1,options:$={}}){return{calendarEl:null,init:async function(){this.calendarEl=this.$el;let t=this,n={view:o,resources:C,eventSources:[{events:(e,r,a)=>this.$wire.getEventsJs(e)}],locale:w,firstDay:E,dayMaxEvents:f,selectable:u,eventStartEditable:i,eventDurationEditable:c};y&&(n.dateClick=e=>{D?t.$el.querySelector("[calendar-context-menu]").dispatchEvent(new CustomEvent("calendar--open-menu",{detail:{mountData:{date:e.date,dateStr:e.dateStr,allDay:e.allDay,view:e.view,resource:e.resource},jsEvent:e.jsEvent,dayEl:e.dayEl,context:"dateClick"}})):this.$wire.onDateClick({date:e.date,dateStr:e.dateStr,allDay:e.allDay,view:e.view,resource:e.resource})}),u&&(n.select=e=>{S?t.$el.querySelector("[calendar-context-menu]").dispatchEvent(new CustomEvent("calendar--open-menu",{detail:{mountData:{start:e.start,startStr:e.startStr,end:e.end,endStr:e.endStr,allDay:e.allDay,view:e.view,resource:e.resource},jsEvent:e.jsEvent,context:"dateSelect"}})):this.$wire.onDateSelect({start:e.start,startStr:e.startStr,end:e.end,endStr:e.endStr,allDay:e.allDay,view:e.view,resource:e.resource})}),l!==null&&(n.eventContent=e=>{let r=t.getEventContent(e);if(r!==void 0)return{html:r}}),v!==null&&(n.moreLinkContent=e=>({html:t.getMoreLinkContent(e)})),s!==null&&(n.resourceLabelContent=e=>{let r=t.getResourceLabelContent(e);if(r!==void 0)return{html:r}}),h&&(n.eventClick=e=>{if(e.event.extendedProps.url){let r=e.event.extendedProps.url_target??"_blank";window.open(e.event.extendedProps.url,r)}else x?t.$el.querySelector("[calendar-context-menu]").dispatchEvent(new CustomEvent("calendar--open-menu",{detail:{mountData:{event:e.event,view:e.view},jsEvent:e.jsEvent,context:"eventClick"}})):this.$wire.onEventClick({event:e.event,view:e.view})}),p&&(n.noEventsClick=e=>{k?t.$el.querySelector("[calendar-context-menu]").dispatchEvent(new CustomEvent("calendar--open-menu",{detail:{mountData:{view:e.view},jsEvent:e.jsEvent,context:"noEventsClick"}})):this.$wire.onNoEventsClick({view:e.view})}),n.eventResize=async e=>{let r=e.event.durationEditable,a=c;r!==void 0&&(a=r),a&&await this.$wire.onEventResize({event:e.event,oldEvent:e.oldEvent,endDelta:e.endDelta,view:e.view}).then(d=>{d===!1&&e.revert()})},n.eventDrop=async e=>{let r=e.event.startEditable,a=i;r!==void 0&&(a=r),a&&await this.$wire.onEventDrop({event:e.event,oldEvent:e.oldEvent,oldResource:e.oldResource,newResource:e.newResource,delta:e.delta,view:e.view}).then(d=>{d===!1&&e.revert()})},m&&(n.viewDidMount=e=>{this.$wire.onViewDidMount({view:e})}),this.ec=new EventCalendar(this.$el.querySelector("div"),{...n,...$}),window.addEventListener("calendar--refresh",()=>this.ec.refetchEvents())},getEventContent:function(t){if(typeof l=="string")return this.wrapContent(l,t);if(typeof l=="object"){let n=t.event.extendedProps.model,e=l[n];return e===void 0?void 0:this.wrapContent(e,t)}},getResourceLabelContent:function(t){if(typeof s=="string")return this.wrapContent(s,t);if(typeof s=="object"){let n=t.event.extendedProps.model,e=s[n];return e===void 0?void 0:this.wrapContent(e,t)}},getMoreLinkContent:function(t){return this.wrapContent(v,t)},wrapContent:function(t,n){let e=document.createElement("div");return e.innerHTML=t,e.setAttribute("x-data",JSON.stringify(n)),e.classList.add("w-full"),e.outerHTML}}}export{g as default}; +function g({view:o="dayGridMonth",locale:w="en",firstDay:E=1,events:b=[],eventContent:l=null,resourceLabelContent:s=null,selectable:j=!1,eventClickEnabled:h=!1,eventDragEnabled:i=!1,eventResizeEnabled:c=!1,noEventsClickEnabled:p=!1,dateSelectEnabled:u=!1,dateClickEnabled:y=!1,viewDidMountEnabled:m=!1,dayMaxEvents:f=!1,moreLinkContent:v=null,resources:C=[],hasDateClickContextMenu:D=!1,hasDateSelectContextMenu:S=!1,hasEventClickContextMenu:x=!1,hasNoEventsClickContextMenu:k=!1,options:$={}}){return{calendarEl:null,init:async function(){this.calendarEl=this.$el;let t=this,n={view:o,resources:C,eventSources:[{events:(e,r,a)=>this.$wire.getEventsJs(e)}],locale:w,firstDay:E,dayMaxEvents:f,selectable:u,eventStartEditable:i,eventDurationEditable:c};y&&(n.dateClick=e=>{D?t.$el.querySelector("[calendar-context-menu]").dispatchEvent(new CustomEvent("calendar--open-menu",{detail:{mountData:{date:e.date,dateStr:e.dateStr,allDay:e.allDay,view:e.view,resource:e.resource},jsEvent:e.jsEvent,dayEl:e.dayEl,context:"dateClick"}})):this.$wire.onDateClick({date:e.date,dateStr:e.dateStr,allDay:e.allDay,view:e.view,resource:e.resource})}),u&&(n.select=e=>{S?t.$el.querySelector("[calendar-context-menu]").dispatchEvent(new CustomEvent("calendar--open-menu",{detail:{mountData:{start:e.start,startStr:e.startStr,end:e.end,endStr:e.endStr,allDay:e.allDay,view:e.view,resource:e.resource},jsEvent:e.jsEvent,context:"dateSelect"}})):this.$wire.onDateSelect({start:e.start,startStr:e.startStr,end:e.end,endStr:e.endStr,allDay:e.allDay,view:e.view,resource:e.resource})}),l!==null&&(n.eventContent=e=>{let r=t.getEventContent(e);if(r!==void 0)return{html:r}}),v!==null&&(n.moreLinkContent=e=>({html:t.getMoreLinkContent(e)})),s!==null&&(n.resourceLabelContent=e=>{let r=t.getResourceLabelContent(e);if(r!==void 0)return{html:r}}),h&&(n.eventClick=e=>{if(e.event.extendedProps.url){let r=e.event.extendedProps.url_target??"_blank";window.open(e.event.extendedProps.url,r)}else x?t.$el.querySelector("[calendar-context-menu]").dispatchEvent(new CustomEvent("calendar--open-menu",{detail:{mountData:{event:e.event,view:e.view},jsEvent:e.jsEvent,context:"eventClick"}})):this.$wire.onEventClick({event:e.event,view:e.view})}),p&&(n.noEventsClick=e=>{k?t.$el.querySelector("[calendar-context-menu]").dispatchEvent(new CustomEvent("calendar--open-menu",{detail:{mountData:{view:e.view},jsEvent:e.jsEvent,context:"noEventsClick"}})):this.$wire.onNoEventsClick({view:e.view})}),n.eventResize=async e=>{let r=e.event.durationEditable,a=c;r!==void 0&&(a=r),a&&await this.$wire.onEventResize({event:e.event,oldEvent:e.oldEvent,endDelta:e.endDelta,view:e.view}).then(d=>{d===!1&&e.revert()})},n.eventDrop=async e=>{let r=e.event.startEditable,a=i;r!==void 0&&(a=r),a&&await this.$wire.onEventDrop({event:e.event,oldEvent:e.oldEvent,oldResource:e.oldResource,newResource:e.newResource,delta:e.delta,view:e.view}).then(d=>{d===!1&&e.revert()})},m&&(n.viewDidMount=e=>{this.$wire.onViewDidMount({view:e})}),this.ec=new EventCalendar(this.$el.querySelector("div"),{...n,...$}),window.addEventListener("calendar--refresh",()=>{this.ec.refetchEvents()}),this.$wire.on("calendar--set",e=>{this.ec.setOption(e.key,e.value)})},getEventContent:function(t){if(typeof l=="string")return this.wrapContent(l,t);if(typeof l=="object"){let n=t.event.extendedProps.model,e=l[n];return e===void 0?void 0:this.wrapContent(e,t)}},getResourceLabelContent:function(t){if(typeof s=="string")return this.wrapContent(s,t);if(typeof s=="object"){let n=t.event.extendedProps.model,e=s[n];return e===void 0?void 0:this.wrapContent(e,t)}},getMoreLinkContent:function(t){return this.wrapContent(v,t)},wrapContent:function(t,n){let e=document.createElement("div");return e.innerHTML=t,e.setAttribute("x-data",JSON.stringify(n)),e.classList.add("w-full"),e.outerHTML}}}export{g as default}; diff --git a/resources/js/calendar-widget.js b/resources/js/calendar-widget.js index bf43d5d..51cc11f 100644 --- a/resources/js/calendar-widget.js +++ b/resources/js/calendar-widget.js @@ -250,7 +250,13 @@ export default function calendarWidget({ ...options }); - window.addEventListener('calendar--refresh', () => this.ec.refetchEvents()) + window.addEventListener('calendar--refresh', () => { + this.ec.refetchEvents(); + }); + + this.$wire.on('calendar--set', (data) => { + this.ec.setOption(data.key, data.value); + }); }, getEventContent: function (info) { diff --git a/src/Widgets/CalendarWidget.php b/src/Widgets/CalendarWidget.php index 06c9e57..c027123 100644 --- a/src/Widgets/CalendarWidget.php +++ b/src/Widgets/CalendarWidget.php @@ -67,8 +67,24 @@ class CalendarWidget extends Widget implements HasActions, HasForms protected int | string | array $columnSpan = 'full'; - public function refreshRecords(): void + public function refreshRecords(): static { $this->dispatch('calendar--refresh'); + + return $this; + } + + public function refreshResources(): static + { + $this->setOption('resources', $this->getResourcesJs()); + + return $this; + } + + public function setOption(string $key, mixed $value): static + { + $this->dispatch('calendar--set', key: $key, value: $value); + + return $this; } }