Fetching API data in Angular for fullcalendar - javascript

I have the function to return the api data for the user bills, and then mapped the data to conform to fullcalendar - when I console log the "this.calendarBills" its json format and the date is also formatted correctly, but when I set "events" for fullcalendar to this.calendarBills, it returns nothing on the calendar...
export class BillPageComponent implements OnInit {
userId = localStorage.getItem('userId') || '';
token = localStorage.getItem('token') || '';
bills: Bill[] = [];
calendarBills: [] = [];
calendarOptions: CalendarOptions | undefined;
constructor(
public fetchApiData: FetchApiDataService,
public snackBar: MatSnackBar,
public dialog: MatDialog,
) { }
ngOnInit(): void {
this.getBills(this.userId, this.token);
}
getBills(userId: string, token: string): void {
this.fetchApiData.getBills(userId, token).subscribe((resp: any) => {
this.bills = resp;
this.calendarBills = resp.map((e: any) => ({ title: e.Description, date: e.Date }))
console.log(this.bills);
console.log(this.calendarBills);
this.calendarOptions = {
headerToolbar: {
center: 'title',
},
initialView: 'dayGridMonth',
eventSources: this.calendarBills,
events: this.calendarBills, // alternatively, use the `events` setting to fetch from a feed
weekends: true,
editable: true,
selectable: true,
selectMirror: true,
dayMaxEvents: true,
dateClick: this.handleDateClick.bind(this),
// select: this.handleDateSelect.bind(this),
// eventClick: this.handleEventClick.bind(this),
// eventsSet: this.handleEvents.bind(this)
/* you can update a remote database when these fire:
eventAdd:
eventChange:
eventRemove:
*/
};
})
}
handleDateClick(arg: { dateStr: string; }) {
alert('date click! ' + arg.dateStr)
}

thanks for the help! Managed to find the problem - had to call the calendarOptions INSIDE the getBills. Also, big thanks to ADyson (those are the types of issues I have without realizing!)
getBills(userId: string, token: string): void {
this.fetchApiData.getBills(userId, token).subscribe((resp: any) => {
this.bills = resp;
this.calendarBills = resp.map((e: any) => ({ title: e.Description, start: e.Date, allDay: true }));
console.log(this.bills);
console.log(this.calendarBills);
// return this.calendarBills;
this.calendarOptions = {
headerToolbar: {
center: 'title',
},
initialView: 'dayGridMonth',
events: this.calendarBills, // alternatively, use the `events` setting to fetch from a feed
weekends: true,
editable: true,
selectable: true,
selectMirror: true,
dayMaxEvents: true,
dateClick: this.handleDateClick.bind(this),
// select: this.handleDateSelect.bind(this),
// eventClick: this.handleEventClick.bind(this),
// eventsSet: this.handleEvents.bind(this)
/* you can update a remote database when these fire:
eventAdd:
eventChange:
eventRemove:
*/
};
})
}

You said
the date is also formatted correctly
...maybe so, but fullCalendar doesn't recognise or understand date as a property name of an event. It will not read it and use it as a date. Therefore, fullCalendar doesn't know where to place your event on the calendar, which is why you can't see it.
The names of the fields you can use in your events are clearly documented already at https://fullcalendar.io/docs/event-parsing. You need to specify start (for the start date/time of the event) and optionally also end (for the end date/time).
Assuming your date really is formatted correctly (as per https://fullcalendar.io/docs/date-parsing) then
{ title: e.Description, start: e.Date }
should work for you.

Related

FullCalendar get events from database

Hi i am using FullCalendar in a laravel project and i need to display the events from the database.
I get all the events from the database and display them using json_encode.
There is the code i use :
My controller :
<?php
namespace App\Http\Controllers;
use App\Http\Gestionnaires\EventGestionnaire;
use Illuminate\Http\Request;
class EventController extends Controller
{
public function afficher(){
$eventGestionnaire = new EventGestionnaire;
$listeEvents = $eventGestionnaire->getListeEvents();
echo json_encode($listeEvents);
return view('pages.calendar');
}
}
And my script :
$calendar.fullCalendar({
viewRender: function(view, element) {
if (view.name != 'month'){
$(element).find('.fc-scroller').perfectScrollbar();
}
},
resourceEditable: true,
eventLimit: true,
editable: true,
selectable: true,
selectHelper: true,
header: {
left: 'month,agendaWeek,agendaDay',
center: 'title',
right: 'prev,next,today'
},
events: 'EventController.php',
The error :
jquery.min.js:3049 GET http://localhost/planner/public/EventController.php?start=2019-09-01&end=2019-10-13&_=1568831263931 404 (Not Found)
I used it in the past, and using the same structure for the javascript side of it as previous answer shows. Once created your route to access it, see php code for responding to your ajax request:
$results = [];
foreach($calendar_events as $calendar_event)
{
$ev = [];
$ev["title"] = $calendar_event->name;
$ev["color"] = $calendar_event->calendar->color ?? "f47d30";
$ev["start"] = Carbon::parse($calendar_event->start)->format("Y-m-d");
$ev["end"] = Carbon::parse($calendar_event->end)->format("Y-m-d");
if (!$calendar_event->is_allday)
{
$ev["start"] = Carbon::parse($calendar_event->start."T".$calendar_event->start_time)->format("Y-m-d\TH:i:s");
$ev["end"] = Carbon::parse($calendar_event->end."T".$calendar_event->end_time)->format("Y-m-d\TH:i:s");
$ev["allDay"] = false;
}
if (!empty($calendar_event->url))
{
$ev["url"] = $calendar_event->url;
}
$results[] = $ev;
}
return response($results);
From FullCallendar V3 DOCS to pass URL with JSON response use
$('#calendar').fullCalendar({
eventSources: [
// your event source
{
url: '/myfeed.php', // use the `url` property
color: 'yellow', // an option!
textColor: 'black' // an option!
}
// any other sources...
]
});

Adding a button to each cell in fullcalendar to allow user to add an event using jQuery

I have been using jQuery along with fullcalendar to create a calendar that displays events from a database using php and MYSQL.
The calendar looks like this.
The events are shown in red. I would like to be able to add a button in each of the cells that do not have an event to allow the user to be able to add one.
Here is the code I have tried
viewRender: function (view) {
$(".fc-content").append('<button>Add</button>')
}
my full code.
$(document).ready(() => {
const calendar = $('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'agendaWeek,agendaDay'
},
defaultView: 'agendaWeek',
defaultTimedEventDuration: '01:00',
allDaySlot: false,
scrollTime: '09:00',
businessHours: {
dow: [ 2, 3, 4, 5, 6 ],
start: '09:00',
end: '17:30'
},
//viewRender: function (view) {
// $(".fc-content").append('<button>Book</button>');
// },
long: /^en-/.test(navigator.language) ? 'en' : 'zh-cn',
eventOverlap: (stillEvent, movingEvent) => {
return true;
},
events:
<?php echo $json;?>
//'2018-12-12T15:00+08:00'
//},
//{
//title: '',
//start: '' //'2018-12-12T12:00+08.00'
,
eventColor: '#FF0000',
edittable: true,
selectable: true,
selectHelper: true,
select: (start, end) => {
const duration = (end - start) / 1000;
if(duration == 1800){
// set default duration to 1 hr.
end = start.add(30, 'mins');
return
calendar.fullCalendar('select', start, end);
}
let eventData;
if (title && title.trim()) {
eventData = {
title: title,
start: start,
end: end
};
calendar.fullCalendar('renderEvent', eventData);
}
calendar.fullCalendar('unselect');
},
eventRender: (event, element) => {
const start = moment(event.start).fromNow();
element.attr('title', start);
},
loading: () => {}
});
});
Ok first off, unless the button is required from UI/UX perspective, you can skip adding the button and just work with fullCalendars built-in method/events.
example (skipping irrelevant options):
fullCalendar({
...
editable: true,
selectable: true, // makes each day selectable
select: function (start, end) {
// in this select callback you are given the start and end dates of the user's selection
// when a user selects any cells this will fire and you can do stuff in here
// fullcalendar will always give 2 dates as callback, even if the user only selected 1
// date, the 'end' will correspond to the next day actually...
events: [{event1},{event2},{event3}], // use this to initialize the events already //existing
eventClick: function (event) {
// this is the handler that will run when the user clicks on an event, not a day! an //event on a day
}
}
})
I hope this helps, you can always read more on the docs
You do not need button ..
you can do it in function eventClick this trigger in click on any day
$('#calendar').fullcalendar({
eventClick : function(xEvent, jsEvent, view){ hus_eventClick(xEvent, jsEvent, view);} ,
});
and in function show dialog box to add event ..
https://fullcalendar.io/docs/dayClick

FullCalendar trying to fetch events from URL instead of array

Using FullCalendar v3.9.0 with jQuery v3.3.1. I have a SailsJS application that's getting the calendar data from MySQL.
this.me.calendar from MySQL currently looks like this.
[{"start":"2018-07-04T13:30:00","end":"2018-07-04T18:00:00","works":["2"]}]
And my FullCalendar code looks like this.
let that = this;
that.me.calendar = this.me.calendar;
$('#calendar').fullCalendar({
header: {
left: 'today prev,next',
center: 'title',
right: 'agendaWeek,agendaDay'
},
views: {
week: {
titleFormat: 'DD.MM.YYYY'
}
},
defaultView: 'agendaWeek',
locale: 'fi',
weekends: false,
scrollTime: '07:00',
businessHours: {
start: '7:00',
end: '21:00',
},
events: function(start, end, timezone, callback) {
let events = that.me.calendar ? that.me.calendar : [];
console.log(events);
callback(events);
},
editable: true,
selectable: true,
selectHelper: true,
select: (start, end) => {
let duration = (end - start) / 1000;
if (duration == 1800) {
// Set default duration to 1 hour
end = start.add(30, 'mins');
return $('#calendar').fullCalendar('select', start, end);
}
let eventData = {
start: start,
end: end,
works: []
}
$('#calendar').fullCalendar('renderEvent', eventData);
$('#calendar').fullCalendar('unselect');
},
eventClick: (event, element) => {
$('#event-works').text(event.works.join(','));
$('#start-date').text(moment(event.start).format('d.MM.YYYY HH:mm'));
$('#end-date').text(moment(event.end).format('d.MM.YYYY HH:mm'));
$('#workModal').modal('show');
$('#add-work-to-event').click(() => {
let work = $('#work').val();
if(_.includes(event.works, work)) return;
event.works.push(work);
$('#event-works').text(event.works.join(','));
});
}
});
While the code above doesn't send the GET, it doesn't display the events in the calendar. However, if I change the events to events: this.me.calendar, the SailsJS console displays GET /account/%22[%7B/%22start/%22:/%222018-07-04T13:30:00/%22,/%22end/%22:/%222018-07-04T18:00:00/%22,/%22works/%22:[/%222/%22]%7D]%22 (1ms 404).
I also tried changing it to events: JSON.stringify(this.me.calendar), which still gave the GET request in console.
If I enter the array in the events on it's own, it is working. Also the console.log inside the events function is returning the same array.
Is there a way for me to simply enter my array for FullCalendar, or do I have to make it get the JSON from an URL?
I managed to solve the issue by changing the let events inside of my events function to let events = that.me.calendar ? JSON.parse(that.me.calendar) : []; and now the events are being displayed.

How to remove allDay from view in fullcalender JS?

I am trying to build an application that creates events within fullcalendar. I don't allow user to create an "allDay" event at all at the client side but they still can see it within the view. Is there any method to remove allDays from views completely?
function initCalendar {
if (!jQuery().fullCalendar) {
return;
}
var date = new Date(),
started,
ended
var header = {};
var calendar = $('#calendar').fullCalendar({
header: header,
selectable: true,
selectHelper: true,
select: function (start, end, allDay) {
$('#fc_create').click();
var dateStart = start;
var dateEnd = end;
$(".antosubmit").on("click", function() {
var title = $("#reservation-title").val();
if (title) {
var event = {
editable: true,
title: title,
start: dateStart,
end: dateEnd,
allDay: false
}
calendar.fullCalendar('renderEvent', event, true);
calendar.fullCalendar('unselect');
#('.antoclose').click();
return false;
}
else {
////alert here
}
})
}
})
}
From the docs:
allDaySlot: false
https://fullcalendar.io/docs/agenda/allDaySlot/
** Update for v5:
https://fullcalendar.io/docs/allDaySlot

Fullcalendar - Can we add custom data to our event Json Data?

I want to send a type in my Event Json Response.
Here is my code:
$('#calendar').fullCalendar({
eventSources: [
{"id":"46_l","title":"CustomEvent-Chargement","start":"2013-12-02","end":"2013-12-03","className":"customEventsClass","type":1},
{"id":"46_d","title":"Custom Event-Livraison","start":"2013-12-11","end":"2013-12-12","className":"customEventsClass","type":2}
]
});
You see I send a type in JSON Response array, is this possible? What parameter can we use for sending our custom data?
As per the documentation:
Non-standard Fields
In addition to the fields above, you may also include your own non-standard fields in each Event Object. FullCalendar will not modify or delete these fields. For example, developers often include a description field for use in callbacks such as eventRender.
Example:
$('#calendar').fullCalendar({
events: [
{
title: 'My Event',
start: '2010-01-01',
type: 1 // Custom field
}
],
eventRender: function(event, element) {
console.log(event.type); // Writes "1"
}
});
Try It with events: instead of eventSources:
$('#calendar').fullCalendar({
events: [
{"id":"46_l","title":"CustomEvent-Chargement","start":"2013-12-02","end":"2013-12-03","className":"customEventsClass","type":1},
{"id":"46_d","title":"Custom Event-Livraison","start":"2013-12-11","end":"2013-12-12","className":"customEventsClass","type":2}
]
});
In the new version you should do this:
eventRender: function (info) {
info.el.firstChild.innerHTML = info.event.extendedProps.type + " " + info.event.extendedProps.customEventsClass;
}
In version 4 custom data is in extendedProps.
In short e.event.extendedProps
You can also pass url endpoint to events as long as the url returns json response
cId.fullCalendar({
header: {
right: '',
center: 'prev, title, next',
left: ''
},
theme: true, //Do not remove this as it ruin the design
selectable: true,
selectHelper: true,
editable: true,
//it will load data from this url
events: "{{ url('api/events') }}",
// events: getData(),
//Add Events
});
and in your controller or function
$events = $request->user()->events()->select('title','color','date')->get();
// dd($even,$events)
$eventsResponse = [];
// created_at->format('Y-m-d')
foreach ($events as $event)
{
$eventsResponse[] = [
'title'=>$event->title,
'color'=>$event->color,
'start'=> Carbon::parse($event->date)->toDateTimeString(),
];
}
return $eventsResponse;

Categories

Resources