FullCalendar events are missing 'Editable' field? - javascript

Let's say I have a basic setup of events like the following :
initialEvents: EventInput[] = [
{
title: 'Event 0',
start: '2021-02-22T10:00:00',
end: '2021-02-22T12:00:00',
editable: false
},
{
title: 'Event 1',
start: TODAY_STR + 'T12:00:00',
end: TODAY_STR + 'T16:00:00',
},
{
title: 'Event 2',
start: '2021-02-24T09:00:00',
end: '2021-02-26T12:00:00',
}
]
Using this in my calendar options :
...
initialView: 'timeGridWeek',
initialEvents: this.initialEvents,
eventClick: this.handleEventClick.bind(this),
...
And having this method :
handleEventClick(clickInfo: EventClickArg): void {
console.log(clickInfo.event);
if (confirm(`Are you sure you want to delete the event '${clickInfo.event.title}'`)) {
clickInfo.event.remove();
}
}
It seems the EventApi event fom my clickInfo works almost fine, it contains almost all the properties stated in the documentation there : https://fullcalendar.io/docs/event-object
Except it's missing the properties editable and resourceEditable.
They are also missing in the EventApi class found in the ...\node_modules\#fullcalendar\common\main.d.ts file.
So how can I access the editable property of my event when I click it ?
(I'm using the v5.5.0 with angular)

OK, so it turns out, events don't have an editable property.
This is just a convenience setter that sets both startEditable and durationEditable.
These are the 2 properties to use in order to get the editable status of the event.

Related

GetEvents from FullCalendar

I'm working with Full Calendar I want to create a button that take all the events from the calendar and send them to my database. But when trying to call the getEvents method referenced here from the calendar object, I cannot get it to work. The method doesn't seem to exist. I get undefined method.
Below is a snippet of the initialization of the calendar.
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
initialDate: '2020-09-12',
navLinks: true, // can click day/week names to navigate views
selectable: true,
selectMirror: true,
select: function(arg) {
var title = prompt('Event Title:');
if (title) {
calendar.addEvent({
title: title,
start: arg.start,
end: arg.end,
allDay: arg.allDay
})
}
calendar.unselect()
},
eventClick: function(arg) {
if (confirm('Are you sure you want to delete this event?')) {
arg.event.remove()
}
},
editable: true,
dayMaxEvents: true, // allow "more" link when too many events
events: [
{
title: 'All Day Event',
start: '2020-09-01'
},
{
title: 'Long Event',
start: '2020-09-07',
end: '2020-09-10'
},
{
groupId: 999,
title: 'Repeating Event',
start: '2020-09-09T16:00:00'
},
{
groupId: 999,
title: 'Repeating Event',
start: '2020-09-16T16:00:00'
},
{
title: 'Conference',
start: '2020-09-11',
end: '2020-09-13'
},
{
title: 'Click for Google',
url: 'http://google.com/',
start: '2020-09-28'
}
]
});
calendar.render();
I use the last version of Full Calendar (v5)
When I try to create a button that will get the calendar then retrieve all the events and send it to my database I get error saying that the function doesn't exist.
Here is how I do that :
var calendar = document.getElementById("calendar");
/* I can do that since I have my calendar with the id "calendar"
And then I try use the getEvents function
*/
var events = calendar.getEvents();
/* Show undefined */
<div id="calendar"></div>
Super Important Note: I realized that the function doesn't exist since I try to apply it to the HTML element and not the FullCalendar JS object. So my question is how can I get a FullCalendar JS Object from the HTML element in order to retrieve the events that the user has saved ??
Your problem is because var calendar = document.getElementById("calendar"); fetches the HTML element into which the rest of the calendar's HTML was added by fullCalendar. It does not fetch the fullCalendar instance which was generated by new FullCalendar.Calendar when you intialised the calendar. It's the latter which exposes the functions to manipulate the calendar or get data from it.
Notice how you already use that object in your code to call fullCalendar's render function, e.g. calendar.render();.
(The HTML element object just contains standard functions found on any HTML element, not anything specific to fullCalendar.)
So in summary you need to use the calendar variable you created from the new FullCalendar... instantiation. If you need access to that outside the scope it was originally declared in (which is the callback of the DOMContentLoaded event handler), then one way round that is to make it a global variable, e.g.
var calendar; //global variable
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
calendar = new FullCalendar.Calendar(calendarEl, {
....
});
calendar.render();
});
Then somewhere else in your code, wherever you need it, you can write
var events = calendar.getEvents();

fullcalendar.io 5: addEventSource not work from external function

For a small project I want to add events at runtime.
The actual calendar is created with data from a database. The separate script creates additional events, which are created dynamically at runtime of the calendar. These events should be added to the existing calendar afterwards.
For testing I have a calendar and an external button. If you click on the button, an event should be added to the calendar. Calendar is created and the click is recognized. But no event is added.
Where is the thought error?
The HTML
<button class="holiday">Add Feiertage</button>
<div id='calendar'></div>
The Code:
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek'
},
initialDate: '2020-11-12',
businessHours: true, // display business hours
editable: true,
events: [
{
title: 'Business Lunch',
start: '2020-11-03T13:00:00',
constraint: 'businessHours'
},
{
title: 'Meeting',
start: '2020-11-13T11:00:00',
constraint: 'availableForMeeting', // defined below
color: '#257e4a'
},
{
title: 'Conference',
start: '2020-11-18',
end: '2020-11-20'
},
{
title: 'Party',
start: '2020-11-29T20:00:00'
},
// areas where "Meeting" must be dropped
{
groupId: 'availableForMeeting',
start: '2020-11-11T10:00:00',
end: '2020-11-11T16:00:00',
display: 'background'
},
{
groupId: 'availableForMeeting',
start: '2020-11-13T10:00:00',
end: '2020-11-13T16:00:00',
display: 'background'
},
// red areas where no events can be dropped
{
start: '2020-11-18',
title: 'Test-Holiday',
overlap: false,
display: 'background',
color: '#ff9f89'
}
]
});
calendar.render();
});
// external events by Click
jQuery(document).ready(function($) {
$('.holiday').on('click', function() {
console.log('klick');
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl);
//var src = calendar.getEventSources(); // give me a empty array
calendar.addEventSource(
{
events: [ // put the array in the `events` property
{
title : 'Test-Event',
start : '2020-11-11',
overlap: false,
display: 'background',
color: '#ff9f89'
}
]
});
calendar.refetchEvents();
});
});
});
Here is my Test:
https://jsfiddle.net/LukasHH/tu14xfwr/
The calendar variable you're using for calendar.addEventSource refers to a different FullCalendar instance than the one which is shown on your page. You have created a completely new calendar - but then didn't render it to the page. That's why you don't get errors, but also nothing useful happens.
The original calendar is defined and populated inside your document.addEventListener('DOMContentLoaded', function() { block, but you tried to create a new one inside your jQuery(document).ready(function($) { block. You need to use the existing reference to calendar - but of course it's out of scope when you need it, because you're in a different code block.
Now, document.addEventListener('DOMContentLoaded', function() { and jQuery(document).ready(function($) { are essentially equivalent, it's just that one is written in native JS and one is jQuery syntax. They basically do the same task - i.e. delay execution of the code until the DOM is completely loaded. Therefore it doesn't make much sense or add any value to have both of them in the page at the same time. Just use one block to include all of your code, and then you won't have any scope problems regardless.
As well as that, for similar reasons it also makes no sense to have another document.addEventListener('DOMContentLoaded', function() { within the jQuery "ready" block! You simply don't need it. I can only assume you didn't understand what that code did and thought it was part of fullCalendar - it's not.
And
var i = calendar.initialEvents();
console.log(i);
makes no sense. There's no method called initialEvents in fullCalendar and you don't seem to be trying to use i for anything anyway, so you can just remove these lines.
e.g.
jQuery(document).ready(function($) {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
//...etc
});
calendar.render();
$('.holiday').on('click', function() {
calendar.addEventSource({
events: [ // put the array in the `events` property
{
title: 'Test-Event',
start: '2020-11-11',
overlap: false,
display: 'background',
color: '#ff9f89'
}
]
});
});
Demo: https://jsfiddle.net/32w4kLvg/

angularjs ui calendar not displaying added event

I am trying to add a new events to the ui calendar using ui bootstrap modal box. However, its not showing on the calendar. Below I have created the function for the day click event which contains the code for the modal box:
$scope.dayClickEvent = function(date,jsEvent,view){
//open model view for adding a event title
var creatEventModalInstance = $modal.open({
templateUrl: '/js/schedule/event_modal.html',
controller: function($scope, $modalInstance){
$scope.add = function(event){
$modalInstance.close(event);
};
$scope.close = function(){
$modalInstance.dismiss('cancel');
};
}
});
Here is the code for the ui configuration for the calendar:
$scope.uiConfig = {
calendar:{
height: 450,
editable: true,
header:{
left: 'month basicWeek basicDay agendaWeek agendaDay',
center: 'title',
right: 'today prev,next'
},
dayClick: $scope.dayClickEvent
}
};
Also the code for the event source to provide ui calendar with data about the events:
$scope.eventSources = {
events: [
{
title: 'Event1',
start: '2015-01-18'
},
{
title: 'dsadas',
start: '2015-01-18'
}
// etc...
],
color: 'yellow', // an option!
textColor: 'black' // an option!
};
So, what I am doing wrong and thanks in advance.
$scope.eventSources is an array that includes one or more event source objects.
It's an extended form meant to allow you to add multiple event sources.
an Event Source Object includes the events array as well as any Event Source Options related to the events - such as text or background colours.
Therefore you must to add an object for each event source
- then you include your events array within the object - along with any options.
...in your example you put the events array directly within an $scope.eventSources object...
To correct:
- make $scope.eventSources an array ie use [square brackets]
- put the events:[] array inside an object ie within {curly brackets}
try something like this:
$scope.eventSources = [
//this is event source object #1
{
events: [ // put the array in the `events` property
{
title: 'Event1',
start: '2015-01-24'
},
{
title: 'Event2',
start: '2015-01-28'
}
],
color: 'black', // an Event Source Option!
textColor: 'yellow' // an Event Source Option!
}
];
as outlined in this answer, you can add multiple sources by referencing objects, like:
$scope.eventSources = [$scope.eventSourceObject1, $scope.eventSourceObject2, etc...],
(you can call your Event Source Objects whatever you want, as long as they're correctly constructed)
Again each event source will have to be an object that includes the events array inside.

Is it possible to move an Event to the bottom of a day cell?

I am using fullcalendar with month view, I want to move an event to the bottom of a day cell. Is it possible and how?
I have made a picture of my goal, I made ​​it with the help of Google Chrome's Inspect element
i was able to do it at v.3.9.0 only using CSS
.fc-row .fc-content-skeleton{
padding-bottom: 2em;
}
and add a class to yout event and use:
.fc-event.your-class{
position: absolute;
bottom: 0;
}
I can't comment so please understand. I have tried everything that would come to mind to be able to do something like this. With their demo they have for FullCalendar http://arshaw.com/fullcalendar/ I immediately see that it is using tables for the structure. There is a major problem with this. Tables have their own predefined structures and allow you to order things in a specific table driven format.. obviously right...
Problem with this is by definition each has a defined height built from the content inside. If you position absolute (which is what you would need for your task) they do one of two things. Disappear (if done on content) or lose defined table column width. They then are unable to move around unless you know a calculated amount.
So what you would need to do (without having actual code in front to see how you are populating the fields) is to count each element that has status within the given day and give each position absolute. For every given item that you want to be at the bottom you calculate that in and then you have to move each individual item up.
Basically this would not work very well and would be very complicated. I don't recommend using this calendar for what you're trying unless you can somehow change the structure to something a bit more flexible.
If someone does find a way great! But sadly there was no solution that made sense from their provided demo for me.
I'm not sure about FullCalendar but normally vertical-align: bottom will put the data on bottom. Problem is it will place ALL data on bottom, not as you shown on the image.
to solve this particular problem you can place a new table inside the cell so you end up with :
<table> //Main Table
<tr>
<td>
<table> // new table
<tr>
<td> data</td>
</tr>
<tr> // vertical align : bottom
<td>custom event</td>
</tr>
</table>
</td>
</tr>
</table>
but then you end with lot of ugly code. (also you may want to use rowspan=2 when there is no custom event)
Another apporach would be to have always a space for this 'custom event'
Doing this you only need to use a position:relative; padding-bottom:30px; on the <td> and then the custom event item using position: absolute; bottom:0.
this have a new problem where you always have a padding bottom of 30px even when u don't have a custom event. (this can be mitigated by adding the padding on the fly with JavaScript)
not sure if this actually helps you, but those are the things that came to my mind right now.
I was able to achieve this on fullcalendar-2.1.1 using the demo default.html. Here is the code:
$(document).ready(function() {
$('#calendar').fullCalendar({
defaultDate: '2014-09-12',
editable: true,
eventLimit: true, // allow "more" link when too many events
events: [
{
title: 'All Day Event',
start: '2014-09-01',
isStickied: true
},
{
title: 'Long Event',
start: '2014-09-07',
end: '2014-09-10'
},
{
id: 999,
title: 'Repeating Event',
start: '2014-09-09T16:00:00'
},
{
id: 999,
title: 'Repeating Event',
start: '2014-09-16T16:00:00'
},
{
title: 'Conference',
start: '2014-09-11',
end: '2014-09-13'
},
{
title: 'Meeting',
start: '2014-09-12T10:30:00',
end: '2014-09-12T12:30:00',
isStickied: true
},
{
title: 'Lunch',
start: '2014-09-12T12:00:00'
},
{
title: 'Meeting',
start: '2014-09-12T14:30:00'
},
{
title: 'Happy Hour',
start: '2014-09-12T17:30:00'
},
{
title: 'Dinner',
start: '2014-09-12T20:00:00'
},
{
title: 'Birthday Party',
start: '2014-09-13T07:00:00'
},
{
title: 'Click for Google',
url: 'http://google.com/',
start: '2014-09-28'
}
],
eventAfterRender: function(event, element, view) {
if (event.isStickied) {
$(element).css('position', 'absolute');
$(element).css('bottom', '0');
}
}
});
});
You will also need to modify fullcalendar.css line 648 for .fc-content-skeleton to have:
height: 108px;
This will assume that your monthly calendar view will always have a fixed row height of 108px like in the demo.

TreeNode click event on ExtJs 4

I'm using ExtJS 4 (beta 3) and I have a TreePanel that is my kind of navigation menu.
It is something like this:
Jobs
Add Job
List All Jobs
...
...
...
(this will be made on a permission system base, but that's another story)
On ExtJS 3, do something when i clicked "Add Job" was as simple as adding
...
leaf:true,
listeners:{
click:function(n){
//my code...
}
}
...
to the root children elements.
Now It's not that simple. The closer i got was with (on the treepanel)
listeners:{
click : {
element : 'el',
fn : function(eve, elem, obj){
console.log(node);
console.log(elem);
console.log(obj);
}
}
}
So, maybe i'm just a noob, maybe i have already a strong hatred for ExtJS, maybe is just a problem in this beta version, but...
How do I add a listener to the click event on the tree nodes? (the Select event won't do what i need)
Thank you guys.
EDIT: Currently testing with this, and it's not working.
... = Ext.create('Ext.tree.TreePanel', {
region : 'west',
collapsible : false,
title : 'ITMI',
width : 220,
margins : '5 5 5 5',
cmargins : '5 5 5 5',
hideHeaders : true,
useArrows : true,
rootVisible : false,
headers: [{
xtype : 'treeheader',
text : 'Nome',
flex : 1,
dataIndex: 'nome'
}],
store: store,
listeners:{
itemclick: function(n){
console.info(n);
}
}
...
EDIT 2: The itemclick event now works (on EXJS 4 final), It still doesn't solve my problem. I'd Like to call a specific function when i call each treenode. Before it was really easy. Now i can't figure it out.
in ext4 beta3 (maybe in final release too)... there is no longer click event....
this has changed to itemclick more info
var tree = Ext.create('Ext.tree.Panel', {
store: store,
renderTo: Ext.getBody(),
height: 300,
width: 250,
title: 'Files',
listeners:{
itemclick: function(n){
console.info(n);
}
}
});
So, It may help some people who may be struggling with the same issue I did then.
The "itemclick" event is the way to handle leafs clicks, and it didn't work then for reasons I don't remember.
I accomplished what I needed by splitting the config I had in the database, something like
controllerName|functionName
and then call this code on the handler of the "itemclick:
this.getController(ctr)[fn]();
where ctr is the controllerName and fn is the functionName. This could easily be done with eval, but I prefer not to.
I could not get itemclick to fire with IE (fine in Chrome). I modified my code to use 'checkchange' and it works fine.

Categories