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:
**
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]
**
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.)