phplaravelfullcalendarlaravel-8fullcalendar-3

Laravel: full-calendar displayEventTime doesn't display the time correctly (12a)


I'm trying to create a full calendar with laravel for an application I'm working on. I have created some cards that have the names of some providers and I want to display the time when the event starts on the card at the beginning.

I understand that fullCalendar has a calendar parameter called displayEventTime. However, when I set it to true I only get 12a in all of my cards, no matter when the actual event takes place. I Googled and I found that this is because the time is default at 00:00. So, I'm guessing that either some time format is wrong or that the time start/end doesn't pass to the event from the controller.

How can I pull for each event it's start/end time and display it on the cards?

View:

var calendar = $('#calendar').fullCalendar({
            events: SITEURL + "/availabilityHours?providerTypeID={{$providerTypeID}}",
            editable: false,
            //timeFormat: 'H(:mm)',
            displayEventTime: true,
            selectable: true,
            selectHelper: true,
            eventRender: function (event, element, view) {
                event.allDay = false;
            },
            select: function (start, end, allDay) {
                window.location.href = SITEURL + "/availabilityHours/create?eventDate=" + start.unix();
            },
             
            eventDrop: function (event, delta) {
                        console.log('dragged and dropped')
                    },
            eventClick: function (event) {
                window.location.href = SITEURL + "/availabilityHours/" + event.id + "/edit";
            }
        });
    });

Controller:

public function index(AvailabilityHourDataTable $availabilityHourDataTable, Request $request)
    {
        //return $availabilityHourDataTable->render('availability_hours.index');
        
        if(request()->ajax()) 
        {
 
            $start = (!empty($_GET["start"])) ? ($_GET["start"]) : ('');
            $end = (!empty($_GET["end"])) ? ($_GET["end"]) : ('');
            $providerTypeID = (!empty($_GET["providerTypeID"])) ? ($_GET["providerTypeID"]) : ('0');
        
            $providers = $providerTypeID == 0 ?
                $this->eProviderRepository->all()->pluck('id') : 
                $this->eProviderRepository->where('e_provider_type_id', $providerTypeID)->pluck('id');
            
            $data = $this->availabilityHourRepository
                    ->getModel()
                    ->whereDate('day', '>=', $start)
                    ->whereDate('day', '<=', $end)
                    ->whereIn('e_provider_id', $providers)
                    ->get();
            $responceData = [];

            
            foreach($data as $entry){
                $date = Carbon::createFromFormat('Y-m-d H:i:s', $entry->day, 'UTC')->setTimezone('Europe/Athens');
                $eProvider = $this->eProviderRepository->findWithoutFail($entry->e_provider_id);
                
                $newEntry = [
                    'id' => $entry->id,
                    'title' => $eProvider->name,
                    'date' => $date,
                    'color' => $eProvider->color,
                ];
                $responceData[] = $newEntry;
            }
            
            return Response::json($responceData);
        }
        
        $providerTypes = $this->eProviderTypeRepository->all()->pluck('name', 'id');
        $providerTypes['0'] = 'All';
        $providerTypeID = isset($request->providerTypeID) ? $request->providerTypeID : 0;
        
        return view('availability_hours.index2', compact('providerTypeID', 'providerTypes'));
    }

Model:

public static $rules = [
        'day' => 'required',
        'start_at' => 'required|date_format:H\:i',
        'end_at' => 'required|date_format:H\:i|after:start_at',
        'data' => 'max:255',
        'e_provider_id' => 'required|exists:e_providers,id'
    ];
    public $translatable = [
        'data',
    ];
    public $timestamps = false;
    public $table = 'availability_hours';
    public $fillable = [
        'day',
        'start_at',
        'end_at',
        'data',
        'e_provider_id'
    ];

The calendar in question:

enter image description here

**

EDIT: I followed @ADyson's solution and i parsed the time correctly. However now, I don't get the end time. Here are the changes I did to Controller/View.

Controller

foreach($data as $entry){
                $date = Carbon::createFromFormat('Y-m-d H:i', $entry->day->toDateString().' '.$entry->start_at, 'UTC');
                $endDate = Carbon::createFromFormat('Y-m-d H:i', $entry->day->toDateString().' '.$entry->end_at, 'UTC');
                $eProvider = $this->eProviderRepository->findWithoutFail($entry->e_provider_id);
                
                $newEntry = [
                    'id' => $entry->id,
                    'title' => $eProvider->name,
                    'date' => $date,
                    'endDate' => $endDate,
                    'color' => $eProvider->color,
                ];
                $responceData[] = $newEntry;                
            }
            
            return Response::json($responceData);

View

<script>
    $(document).ready(function () {
        var SITEURL = "{{url('/')}}";
        $.ajaxSetup({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            }
        });
 
        var calendar = $('#calendar').fullCalendar({
            events: SITEURL + "/availabilityHours?providerTypeID={{$providerTypeID}}",
            editable: false,
            displayEventTime: true,
            timeFormat: 'H:mm',
            displayEventEnd: true,
            selectable: true,
            selectHelper: true,
            select: function (start, end, allDay) {
                window.location.href = SITEURL + "/availabilityHours/create?eventDate=" + start.unix();
            },
            eventDrop: function (event, delta) {
                        console.log('dragged and dropped')
                    },
            eventClick: function (event) {
                window.location.href = SITEURL + "/availabilityHours/" + event.id + "/edit";
            }
        });
    });
    $('#providerType').change(function(ev) {
        console.log(ev.target.value)
        let optionValue = ev.target.value
        document.location.href="{!!route('availabilityHours.index')!!}" + "?providerTypeID=" + optionValue;
    });
    </script>
[enter image description here][2]

**


Solution

  • If there's no time specified in the data you pass to fullCalendar, then you won't get a time in the calendar. In your case it seems to be $entry which is at fault and contains only a date (without a time).

    Since your date and time are stored separately, you can just concatenate them together and ensure they make a valid date in the format required by fullCalendar 3 (which is actually anything that momentJS can parse. The most obvious and reliable format would be an ISO8601 compatible string, such as YYYY-MM-DD HH:mm). Carbon can potentially help you with formatting, if you prefer, rather than bare concatenation. might depend a bit how the data is stored in your database / model.

    Secondly, to make your end times show up, change 'endDate' => $endDate to 'end' => $endDate. Your event object's property names must match the ones which fullCalendar expects - see the documentation to know which property names it recognises. (Strictly, your date ought to be start as well but I think in that particular case in fullCalendar 3 it would actually accept date even though it's undocumented.)