skip to Main Content

I have a page with a LiveWire componant for showing Fullcalendar events. The page is working well, the events are showing and i can change month,weeks and the activites a loaded well.

I’m lost and confused, and seriously stuck. If someone can help me its will be fantastic.

I can see on the network tool debugger some update fire, but nothing changing on screen.

The composant View :

<?php

namespace AppLivewire;

use AppModelsUser;
use CarbonCarbon;
use LivewireComponent;

class UserCalendrier extends Component
{
    public $events = [];
    public $show = true;
    public $showAnniversary = true;
    public $start;
    public $end;

    protected $listeners = [
        'triggerShowCalendar',
        'refreshCalendar'
    ];

    public function triggerShowCalendar()
    {
        $this->show = true;
        $this->events = $this->fetchEvents($this->start, $this->end);
        return view('livewire.calendar');
    }

    public function render()
    {
        return view('livewire.calendar');
    }

    public function fetchEvents($start, $end)
    {
        $this->start = $start;
        $this->end = $end;

        $start = Carbon::parse($this->start);
        $end = Carbon::parse($this->end);

        if( $this->showAnniversary ) {

            $users = User::whereBetween('anniversary', [$start, $end])->get();

        } else {

            $users = User::whereHas('activities', function ($query) {
                $query->whereBetween('start', [$start, $end]);
            })->get();
        }

        $eventsGrouped = [];

        foreach ($users as $user) {

            
                $eventsGrouped[] = [
                    'id' => $user->id,
                    'start' => $this->showAnniversary ? $user->activities->start->format('Y-m-d H:i:s') : $user->anniversary,
                    'start' => $this->showAnniversary  ? $user->activities->end->format('Y-m-d H:i:s') : $user->anniversary,
                    'title' => $this->showAnniversary ? $user->activities->title : $user->name.'anniversary'
                
                ];
        
       
        }
        return array_values($eventsGrouped);
    }


    public function eventDetail($user_id, $debut)
    {
        $this->dispatch('triggerShowDetailActiviteEleve', [$user_id, $debut, 'calendar-calendrier']);
        $this->show= false;
    }

    public function filterAnniversary()
    {
        $this->showAnniversary = !$this->showAnniversary;
        $this->events = $this->fetchEvents($this->start, $this->end);
        $this->dispatch('refreshCalendar');
        return view('livewire.calendar');
    }

    public function refreshCalendar()
    {
        $this->events = $this->fetchEvents($this->start, $this->end);
        return view('livewire.calendar');
    }
}

The Livewire view component

<div>
  
    <div style="{{ $show ? '' : 'display: none' }};">


        <button wire:click="filterAnniversary" class="btn btn-light-primary">{{ $showAnniversary ? 'Hide anniversary' : 'Show Anniversary' }}</button>

        <div id='calendar-container' wire:ignore >
            <div id='calendar'></div>
        </div>
    </div>


    @push('scripts')


        <script src='https://cdn.jsdelivr.net/npm/[email protected]/main.min.js'></script>
        <script>

            document.addEventListener('livewire:initialized', function() {
                let calendarEl = document.getElementById('calendar');
                let calendar = new FullCalendar.Calendar(calendarEl, {
                    initialView: 'dayGridMonth',
                    theme: false,
                    disableDragging: false,
                    disableResizing: false,
                    firstDay: 1,
                    weekends: true,
                    locale: '{{ config('app.locale') }}',
                    aspectRatio: 2,
                    noEventsMessage: 'no activities',
                    displayEventEnd: true,
                    slotEventOverlap: false,
                    headerToolbar: {
                        left: 'prev,next today',
                        center: 'title',
                        right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
                    },
                    eventLimit: false,
                    views: {
                        agenda: {
                            eventLimit: 15
                        }
                    },
                    eventClick: info => {
                        @this.eventDetail(info.event.id, info.event.extendedProps.debutBrut);

                        //calendar.render();
                        @this.on(`refreshCalendar`, () => {
                            calendar.refetchEvents();
                        });

                    },
                    selectable: true,
                    selectHelper: true,
                    editable: false,

                    eventContent: function(arg) {
                        let customColor = arg.event.extendedProps.eventColor;
                        if (customColor) {
                            arg.backgroundColor = customColor;
                            arg.borderColor = customColor;
                        }
                    },
                    //events: JSON.parse(@this.events),
                    events: function(fetchInfo, successCallback, failureCallback) {
                        @this.call('fetchEvents', fetchInfo.startStr, fetchInfo.endStr)
                            .then(events => successCallback(events))
                            .catch(error => failureCallback(error));
                    },
                    dayClick: function (date, jsEvent, view) {
                        alert(date.format('DD-MM-YYYY'))
                    },
                });

                calendar.render();

                window.addEventListener('refreshCalendar', () => {
                    calendar.refetchEvents();
                });


            });
        </script>
        <link href='https://cdn.jsdelivr.net/npm/[email protected]/main.min.css' rel='stylesheet' />
    @endpush
</div>

But, i’m trying to understand how to refetch the events on the calendar, by two others way, by a simple button "filterAnniversary", and after a event detail was showed.

Thanks for your help

2

Answers


  1. Chosen as BEST ANSWER

    I have changed the "js" part to this

    eventClick: information => {
                            @this.eventDetail(information .event.id, information .event.extendedProps.debutBrut);
                        },
    

    In the network debut console of my browser, i can see a update request when i go back to the calendar after showing the event detail.

    In the debug i can follow the function public function fetchEvents($start, $end) executed and return good value. But, in the update request the value are not the same when the calendar are showing, the return nested in the Json is empty when its a refresh.

    On the first show

    On the refresh

    Thanks again for your help


  2. From what I see there are some small corrections to make:

    On the PHP side

    In the fetchEvents() method

    $users = User::whereHas('activities', function ($query) {
        $query->whereBetween('start', [$start, $end]);
    })->get();
    

    should be:

    $users = User::whereHas('activities', function ($query) use ($start, $end) { 
        $query->whereBetween('start', [$start, $end]);
    })->get();
    

    Also when you fill the $events Grouped[] variable in the foreach loop, you set the ‘start’ key twice: the second should be ‘end’

    I also think that the strings set for ‘start’, ‘end’‘ and ‘title’ should be swapped, for example:

    'start' => $this->showAnniversary ? $user->anniversary : $user->activities->start->format('Y-m-d H:i:s'),
    

    The array_values($eventsGrouped) is not needed you can simply return the $eventsGrouped variable

    At class level:

    return view('livewire.calendar'); must be removed from every method except render() because every time the frontend invokes a backend method render() is automatically executed – among other things if the render() method has the sole function to return the view with a standard name it can also be omitted

    On the javascript side:

    in the eventClick property, the event handler statement @this.on('refreshCalendar'..... must be removed because this sets a new one every time a click is made.

    eventClick can become like this:

    eventClick: information => {
        @this.eventDetail(info.event.id, info.event.extendedProps.debutBrut);
    },
    

    However it is not clear where the info.event.extendedProps.debutBrut property comes from and where the triggerShowDetailActiviteEleve event raised int the eventDetail() method is handled

    Note that you have already set the code to handle the refreshCalendar event:

    window.addEventListener('refreshCalendar', () => {
        calendar.refetchEvents();
    });
    

    Finally, keep in mind that the ‘end’ data provided by the calendar corresponds to the day following the period to be considered ( See here ) when composing the queries

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search