I'm using fullcalendar to allow people to select multiple days. If they make a mistake, they can click the event to remove it.
Here's where I am:
var eventArray = new Array();
var cal = $('#new-show-calendar');
cal.fullCalendar({
height: 250
,events: eventArray
,dayClick: function(date, allDay, jsEvent, view) {
var stringDate = date.toString();
e = { title: "Some Title", start: stringDate }
eventArray.push(e);
cal.fullCalendar( 'renderEvent', e );
}
,eventClick: function(event, jsEvent, view) {
eventArray.splice(eventArray.indexOf(event), 1);
cal.fullCalendar( 'removeEvents', event._id );
}
})
This line gives semi-unpredictable results
cal.fullCalendar( 'removeEvents', event._id );
I've tried rerenderEvents (which doesn't do anything) and a few other things. I'm trying to avoid cleaning out all the events then re-rendering each event individually for performance reasons.
I assume this is a bit of wonkiness around having a local, array-based datasource as opposed to a json source somewhere else.
EDIT: This code (above) works as long as the view doesn't change. If I remove some things, then switch months, new events no longer persist on the calendar across views.
How can I remove an event from the calendar?
Related
I'm developing a Calendar application via fullcalendar.
I'm currently working on a mini sized calendar. The mini calendar will not display the events.
I'm trying to use tooltip instead. so when the user will mouseover a specific daycell - all the events of the specific daycell will be displayed via tooltip. (this is my issue)
I been working on this issue for almost two days now.
unfortunately, full calendar only offers "eventMouseover". (no dayMouseover available).
Also, using $(".fc-day").hover is not really the best way to go because it is working only when hovering the bottom of the cell.
there is no documentation for this on the web so far.
Anybody knows which is the best way to Tackle an issue?
here is my code so far:
$("#miniCalendar").fullCalendar({
defaultDate: currentDate,
viewRender: function (view, element)
{
monthStart = view.intervalStart.format("YYYY-MM-DD");
monthEnd = view.intervalEnd.subtract(1, "days");
monthEnd = view.intervalEnd.format("YYYY-MM-DD");
mStart = view.intervalStart.format("M");
yStart = view.intervalStart.format("YYYY");
},
events: function (start, end, timezone, callback) { //custom events function to be called every time the view changes
$.ajax({
url: getMonthDataUrl,
type: "post",
data: {
startDate: monthStart,
endDate: monthEnd,
custom_config: Config
},
error: function () {
//alert("there was an error while fetching events!");
},
success: function (data) {
calendarData = data;
console.log(calendarData);
thingsToDoAfterWeLoadCalendarData(calendarData);
callback(eventsJsonArray); //pass the event data to fullCalendar via the supplied callback function
}
});
},
fixedWeekCount: false,
dayRender:
function (date, cell) {
//the events are loaded vie eventAfterAllRender function
//eventAfterAllRender takes time to load. so we need dayRender function in order to give the calendar default colors until the real colors are loaded
// the default colors spouse to look like the correct colors. this is needed for a better looking calendar while loading new events
if (!cell.hasClass("fc-other-month")) {
//that means this is a cell of this current month (becuase only cells that belong to other month have the "fc-other-month" class
var weekDay = date.format("dddd");
if (weekDay == "Saturday" || weekDay == "Friday") {
cell.css("background-color", "#edf5f9");
} else{
//regular days
cell.css("background-color", "#f7fafc");
}
} else{
//cells that belong to the other months
$(".fc-other-month").css("background-color", "#ffffff");
}
},
eventAfterAllRender:
(function(view, event, element) {
let viewDisplay = $("#miniCalendar").fullCalendar("getView");
if (viewDisplay.name == "month") { //checking if this the month view. this is needed for better display of the week\day view (if we ever want to use it)
$(".fc-day:not(.fc-other-month)").each(function(index, element) {
//loop through each current month day cell
$(this).empty(); //removing old icons in case they are displayed
let cellDate = moment($(this).data("date")).format("YYYY-M-D"); // "YYYY-M-D" date format is the key in the json_backgrundColorBigCalendar array
$(this).css("background-color", json_backgrundColorBigCalendar[cellDate]); //set the background colour of the cell from the json_backgrundColorBigCalendar array.
});
}
$(".fc-other-month").css("background-color", "#ffffff"); //days that belong to other month gets a color background that will show this days are irrelevant
}),
dayClick: function(date, jsEvent, view) {
window.location = fullCalendarUrl;
},
});
I dont really know if there is a "fullcalendar-way" doing this, but why can't you use your hover event listener and just also let it listen on fc-day-top hover?
$(".fc-day, .fc-day-top").hover(function(e) {
console.log($(e.currentTarget).data("date"));
});
This will also work if you hover the top of a day cell.
Update:
To get the events on hover use this:
var $calendar = $("#calendar");
$(".fc-day, .fc-day-top").hover(function(e) {
var date = moment.utc($(e.currentTarget).data("date"));
var events = $calendar.fullCalendar("clientEvents", function(event) { return event.start.startOf("day").isSame(date); });
console.log(events);
});
(Tested on the calendar on the fullcalendar main site).
Of course you have to change the jQuery selector of the calendar (#calendar) as it is in your code.
I've never seen full calendar before, but if I understand correctly you want to bind a hover function to custom days of the calendar. Is that correct?
If so you can simply select days of the calendar with their "data-date" attribute. So something like the code below would let you specify a hover function for a desired day:
$("[data-date='2017-10-10']").hover(function(e) {
console.log("You moused over 10/10/2017!");
});
I am fairly new to angular I am trying to implement a calendar using ui-calendar. So far I have been able to display a very basic calendar and some events on it.
Now I need to be able to click on a day and display the detailed events on a side tab. I seem to be lost on how to achieve this clicking day thing. This may seems very naive, I thought i'd find the html for each day cell on the calendar, and then it would be as easy as attaching a ng-click to it. But I cant seem to find any template where the html for calendar is. All I can see is the directive, which doesnt help much. I dont understand jquery at all, so I am really struggling to find any answers too.
To sum things up, I just want to know how to make a day on calendar clickable.
Thanks in advance.
code:
$scope.uiConfig = {
calendar: {
height: 450,
editable: true,
header: {
left: 'title',
center: '',
right: 'today prev,next'
},
eventClick: $scope.alertOnEventClick,
eventDrop: $scope.alertOnDrop,
eventResize: $scope.alertOnResize,
eventRender: $scope.eventRender,
dayClick: function(date, jsEvent, view) {
console.log("inside dayClick");
alert('Clicked on: ' + date.format());
var events = myCalendar.fullCalendar('clientEvents', function(event) {
return event.start.isSame(date) || event.end.isSame(date) || date.isBetween(event.start, event.end); // Will return all events starting/ending on this date or overlapping this date
});
}
}
};
In your configuration variable you can add a dayClick callback , in this callback you can do something like this:
dayClick: function( date, jsEvent, view ) {
var events = myCalendar.fullCalendar('clientEvents', function(event) {
return event.start.isSame(date) || event.end.isSame(date) || date.isBetween(event.start, event.end); // Will return all events starting/ending on this date or overlapping this date
});
}
This will return all the events that either are on this day or overlap it.
FullCalendar docs can be found here.
i am using javascript fullcalendar in angular js,
i want to update event title on click particular event,so i have used
eventClick:$scope.alertOnEditEvent
$scope.alertOnEditEvent = function( event, jsEvent, view ){
var title = prompt('Event Title:', event.title, { buttons: { Ok: true, Cancel: false} });
if (title){
event.title = title;
$('.calendar').fullCalendar('updateEvent',event);
}
console.log($scope.events);
}
i can see new title in fullcalendar event portion but i can not see new event title in main events object in console
Fixed that.
var events = $('.calendar').fullCalendar('clientEvents');
console.log(events);
My fullcalendar duplicates events visually when i drag them to another timeslot. I have simplified my code down to the eventDrop to isolate the issue and yet I'm unable to understand the issue.
If I store the events to my localStorage I don't get a duplicate in the storage and the duplicate disappears when I reload the page. This means the problem is only visual and with Full Calendar itself.
However, this is obviously a huge issue as I don't want to reload the page: I want to stay in the current view changing what I need.
Here's my code for the eventDrop:
eventDrop: function(event, delta, revertFunc, jsEvent, ui, view) {
if (!confirm("Are you sure you want to change " + event.title + " ?")) {
/*If the user cancels the change, the event returns to its original position. Otherwise it saves the event.*/
revertFunc(); /*Revert changes using the predefined function revertFunc of fullCalendar.*/
$("#calendar").fullCalendar("refetchEvents");
/*FullCalendar Method to refetch events from all sources and rerender them on the screen.*/
} else {
updateConfirm(event); /*Use the logic to confirm the event update properties*/
Evento.prototype.Update(event); /*Modify the targeted event on the localStorage using the Update method of the Evento Class*/
$("#calendar").fullCalendar("updateEvent", event);
/*FullCalendar Method to report changes to an event and render them on the calendar.*/
$("#calendar").fullCalendar("refetchEvents");
/*FullCalendar Method to refetch events from all sources and rerender them on the screen.*/
}
}
And here's a gif of the issue:
https://i.imgur.com/rFPvvjE.gif
UPDATE: With slicedtoad's help I isolated the issue to my updateConfirm logic:
var updateConfirm = function(event) {
if (confirm("New title?")) { /*Check if the user wants to change the event title*/
event.title = prompt("Enter the new title: "); /*Set new title for the event*/
} else {
event.title = event.title;
}
if (confirm("New description?")) { /*Check if the user wants to change the event description*/
event.description = prompt("Enter the new description: "); /*Set new description for the event*/
} else {
event.description = event.description;
}
if (confirm("Is the event important?")) { /*Check if the user wants to change the event priority*/
event.overlap = false;
event.backgroundColor = "red"; /*Set new priority for the event*/
} else {
event.overlap = true;
event.backgroundColor = "blue"; /*Set new priority for the event*/
}
};
UPDATE 2:
console.log(event) before updateConfirm(event):
Object {id: "2015-01-27T15:29:11+00:00", title: "título", start: m, end: m, allDay: false…}_allDay: false_end: m_id: "2015-01-27T15:29:11+00:00"_start: mallDay: falsebackgroundColor: "blue"className: Array[0]description: "gt4"end: mid: "2015-01-27T15:29:11+00:00"overlap: truesource: Objectstart: mstoringId: "2015-01-27T15:29:11+00:00"title: "título"__proto__: Object
console.log(event) after updateConfirm(event):
Object {id: "2015-01-27T15:29:11+00:00", title: "título", start: m, end: m, allDay: false…}_allDay: false_end: m_id: "2015-01-27T15:29:11+00:00"_start: mallDay: falsebackgroundColor: "blue"className: Array[0]description: "gt4"end: mid: "2015-01-27T15:29:11+00:00"overlap: truesource: Objectstart: mstoringId: "2015-01-27T15:29:11+00:00"title: "título"__proto__: Object
Since the event is not locally sourced, calling updateEvent isn't necessary since the event will be refetched from the database when you call $("#calendar").fullCalendar("refetchEvents");
I'm not entirely sure why it would duplicate but the event modified by updateEvent seems to persist past the refetch. You must be changing it's ID or replacing it with another event object, but I wasn't able to reproduce it.
So try removing the update line
} else {
updateConfirm(event);
Evento.prototype.Update(event);
$("#calendar").fullCalendar("refetchEvents");
}
If that doesn't work, try deleting the event manually:
$("#calendar").fullCalendar( 'removeEvents', event._id ) //replace the updateEvent call with this
//or event.id if your events have an explicit id
Addendum
You likely want to actually figure out the cause of the problem since the above just patches it. Something in Evento.prototype.Update updateConfirm is modifying the event to the point that FC thinks it is a different event. Is it being copied and replacing itself? Are you playing with it's id?
Do singleton style solution:
This worked for me to stop the duplication which was caused by "new Draggable(container)"
every time reloaded the view
$scope.Draggable = null if ($scope.Draggable == null) {
$scope.Draggable = new Draggable(containerEl, {
itemSelector: '.item',
eventData: function (eventEl) {
return {
title: eventEl.innerText
};
}
});
}
I want to know if is possible to get a list or array or something with events of one day by clicking that day in fullcalendar.
Now I get the events from google calendar, if I need to make a query each time I want to get events of one day, it will be so hard for connections. I guess it has to be possible since you already have the events for rendering them.
One user ask me for code:
dayClick: function(date, allDay, jsEvent, view) {
console.log(date);
console.log(allDay);
console.log(jsEvent);
console.log(view);
if (allDay) {
// alert('Clicked on the entire day: ' + jsEvent);
}
},
eventClick: function(event) {
if (event.url) {
return false;
}
}
I can't understand why someone voted me negative. I made a question, someone ask for code, I put code but I EXPLAINED why I have no more code, and -1 vote? I can't understand it.
I think you could do something like
dayClick: function(date, allDay, jsEvent, view) {
var dayEvents = $('yourSelector').fullCalendar( 'clientEvents' function(event){
return event.start.setHours(0, 0, 0, 0) === date.setHours(0, 0, 0, 0);
//or some way to compare that is the same day
//I recommend momentjs lib ex moment(event.start).isSame(date,'day')
});
}
What I suggest is to query the client events and filter it checking if its the same day