I've just started out using this plugin and I am having some trouble removing events that I have just created. I can delete all the events when using eventClick, but not particular ones on eventClick.
Any help would be appreciated. Here is my code.
<script type='text/javascript'>
$(document).ready(function() {
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
var calendar = $('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
selectable: true,
selectHelper: true,
select: function(start, end, allDay) {
var title = prompt('Trade Show Name:');
if (title) {
calendar.fullCalendar('renderEvent',
{
title: title,
start: start,
end: end,
allDay: allDay,
id: 12
},
true // make the event "stick"
);
$('input[name="startDate"]').val(start);
}
calendar.fullCalendar('unselect');
},
eventClick: function(calEvent, jsEvent, view) {
$('#calendar').fullCalendar('removeEvents', function (calEvent) {
return true;
});,
editable: true
});
});
You can do this in 2 ways:
1) Set a unique ID to each of your events and pass those IDs to the removeEvents call.
eventClick: function (calEvent, jsEvent, view) {
$('#calendar').fullCalendar('removeEvents', calEvent._id);
}
Here _id is the unique ID fullCalendar generates.
2) Pass a filter function to delete the event you want.
Considering that you are trying to do this in eventClick, I would suggest you use the 2nd. An example to your case is as follows:
eventClick: function (calEvent, jsEvent, view) {
$('#calendar').fullCalendar('removeEvents', function (calEvent) {
return true;
});
}
Here the filter function passed to removeEvents accepts the event you want to delete and returns true. Since you are doing this in eventClick, all you have to do is pass calEvent.
Hope this helps!
Related
Does anybody know why is the end date null on those "allday=false" events?
Fiddle Sample: https://jsfiddle.net/L1g0z3jd/
I instantiate it differently from the start date, it shows just fine in the calendar view, but for some reason I can't understand whenever i get clientEvents, even thought i have not changed it, I got a null in the event end date!
PS: Just for the sake of "conscience" I must add ... I'm using and old version of google chrome (v 57.0.2987.133 64-bit) and an old ubuntu version (Linux Mint 18.1 Serena)
Its getting me crazy! Thanks!
HTML Code:
<button onclick="javascript:getEvents()">Get Events</button>
<div id='calendar'></div>
Javascript Code:
$(function() {
$('#calendar').fullCalendar({
header: false,
allDaySlot: false,
visibleRange: {start: moment('2000-01-02'), end: moment('2000-01-09')},
editable: true,
selectable: true,
views: {
settimana: {
type: 'agenda',
columnFormat: 'ddd',
hiddenDays: []
}
},
defaultView: 'settimana',
defaultDate: $.fullCalendar.moment().startOf('week'),
slotMinutes: 30,
events: [
$.fn.getAgendaWorktime(1, "08:00:00", 60),
$.fn.getAgendaWorktime(2, "08:30:00", 120),
],
select: function(startDate, endDate) {
$('#calendar').fullCalendar('renderEvent', {
title: 'free time',
start: startDate.format(),
end: endDate.format(),
allDay: false
});
},
eventClick: function(calEvent, jsEvent, view) {
console.log(calEvent, jsEvent, view);
if(doubleClick==calEvent._id){
if (confirm('Delete it?')) {
$('#calendar').fullCalendar('removeEvents',calEvent._id);
}
doubleClick = null;
}else{
doubleClick=calEvent._id;
}
},
});
});
function getEvents() {
var e=0,err=false,$data = []
$('#calendar').fullCalendar('clientEvents').forEach(periodo => {
if (periodo.end==null || periodo.start.format().substr(0,10)!=periodo.end.format().substr(0,10)) {
if (e==0) {
err = true;
e++;
alert('Event startint at '+periodo.start.format()+' cant spread to multiple days');
}
} else {
$data.push({'ini': periodo.start.format(), 'fim': periodo.end.format()});
}
});
alert($data);
}
jQuery.fn.getAgendaWorktime = function ($dow, $start, $elapsed) {
var r = {
allDay: false,
title: 'free time',
start: new Date('2000-01-02 '+$start),
end: new Date('2000-01-02 '+$start)
};
r.start.setDate(r.start.getDate()+$dow);
r.end.setDate(r.end.getDate()+$dow);
r.end.setHours(r.end.setHours()+($elapsed*60));
return(r);
}
I figured out how to solve the question, I will reply to it here for I have not found any workaround or further analysis of the problem in the internet ....
I didn't review my problem to determine if it was specific related to the fact that I was setting the event's end time incorrectly and the calendar wasn't giving me any errors on the issue or anything else, but if you're gowing by the same road i went i can tell you:
Check to see if the end time is been created corretly (that seams to be my real mistaken, I was using setHours instead getHours in the getAgendaWorktime function, which turned the final value to be null. I corrected it in the sample below, but let it incorrectly in the fiddle to show the use of the forceEventDuration attribute);
Set "forceEventDuration" parameter to "true" (that forces the "end" attribute to always be filled easying me up in my code for I can always awaits for an string from ".format()" method of the attibute);
for meny reasons fullcalendar.io some times does not sets the event end date and this was getting me problems whenever avaluating the event end time (Ok, I could work around it but I was intrigged for why does it was getting me those results when it sould not, and the answare was a buged code). With "forceEventDuration: true" fullcalendar gave me the end time every time therefor i could find out that the input method i was using was seting the end date incorrectly and gave me the chance to correct it as well.
Links related:
Calendar parameter documentation https://fullcalendar.io/docs/forceEventDuration
Corrected Fiddle https://jsfiddle.net/gjrfox05/
I hope this answer could be of some help for newcomers at fullcalendar.io as me.
Fiddle Javascript part corrected sample:
$(function() {
$('#calendar').fullCalendar({
header: false,
allDaySlot: false,
forceEventDuration: true,
visibleRange: {start: moment('2000-01-02'), end: moment('2000-01-09')},
editable: true,
selectable: true,
views: {
settimana: {
type: 'agenda',
columnFormat: 'ddd',
hiddenDays: []
}
},
defaultView: 'settimana',
defaultDate: $.fullCalendar.moment().startOf('week'),
slotMinutes: 30,
events: [
$.fn.getAgendaWorktime(1, "08:00:00", 60),
$.fn.getAgendaWorktime(2, "08:30:00", 120),
],
select: function(startDate, endDate) {
$('#calendar').fullCalendar('renderEvent', {
title: 'free time',
start: startDate.format(),
end: endDate.format(),
allDay: false
});
},
eventClick: function(calEvent, jsEvent, view) {
console.log(calEvent, jsEvent, view);
if(doubleClick==calEvent._id){
if (confirm('Delete it?')) {
$('#calendar').fullCalendar('removeEvents',calEvent._id);
}
doubleClick = null;
}else{
doubleClick=calEvent._id;
}
},
});
});
function getEvents() {
var e=0,err=false,$data = []
$('#calendar').fullCalendar('clientEvents').forEach(periodo => {
if (periodo.end==null || periodo.start.format().substr(0,10)!=periodo.end.format().substr(0,10)) {
if (e==0) {
err = true;
e++;
alert('Event startint at '+periodo.start.format()+' cant spread to multiple days');
}
} else {
$data.push({'ini': periodo.start.format(), 'fim': periodo.end.format()});
}
});
alert($data[0].fim);
}
jQuery.fn.getAgendaWorktime = function ($dow, $start, $elapsed) {
var r = {
allDay: false,
title: 'free time',
start: new Date('2000-01-02 '+$start),
end: new Date('2000-01-02 '+$start)
};
r.start.setDate(r.start.getDate()+$dow);
r.end.setDate(r.end.getDate()+$dow);
r.end.setHours(r.end.getHours()+($elapsed*60));
return(r);
}
By default FullCalendar end date null when event end_date = start_date.
I Just pass another fiend with same date from database (Django View).
event_sub_arr['end'] = end_date
event_sub_arr['end_same_date'] = end_date
And check in javaScript
eventClick: function(info) {
var modal = document.getElementById('DeleteEventModal')
getEventDeleteUrl(info.event.id)
getEventUpdateUrl(info.event.id)
modal.style.display = 'block'
calendar.unselect()
var start = info.event.start
var end_same_date = info.event.end_same_date
var end = info.event.end || end_same_date
$("#event_id_name").text(info.event.title)
$("#event_id_start").text(moment(start).format('h:mm:ss a, MMMM Do YYYY'))
$("#event_id_end").text(moment(end).format('h:mm:ss a, MMMM Do YYYY'))
console.log(info.event.start)
console.log(info.event.end)
console.log({{ event_data|safe }})
},
ITS WORK FOR ME
i'm trying to upgrade my fullCalendar version to the latest ( 3.9.0 ) but i can't seams to make the renderEvent function work. The event simply does not render. I'm also using the latest version of the scheduler plugin ( 1.9.3 )
I tried adding events using the $('#calendar').fullCalendar('renderEvent', event, true) like I used to, but now it does not seams to work.
I also tried $('#calendar').fullCalendar('addEventSource', event) followed by $('#calendar').fullCalendar('refetchEventSources') nothing seams to be working.
Here is my code.
$(document).ready(function() {
//Calendar option
const LOCALE_DEFAULT = 'fr';
const TIMEZONE_DEFAULT = 'local';
const IGNORE_TIMEZONE_DEFAULT = false;
const HEIGHT_DEFAULT = 'auto';
const DROPPABLE_DEFAULT = true;
const ALL_DAY_DEFAULT_DEFAULT = false;
const ALL_DAY_DEFAULT = false;
const ALL_DAY_SLOT_DEFAULT = false;
const TIME_EVENT_DURATION_DEFAULT = '03:00:00';
const SELECTABLE_DEFAULT = true;
const SLOT_EVENT_OVERLAPP_DEFAULT = false;
const SELECT_HELPER_DEFAULT = false;
const EVENT_RESOURCE_EDITABLE_DEFAULT = false;
const PUBLISHED = true;
const SCHEDULER_LICENCE = 'CC-Attribution-NonCommercial-NoDerivatives';
let events = [{"id":2,"title":"test","start":"2018-03-18T15:30:00.000Z","end":"2018-03-18T19:30:00-04:00","creationDate":"2018-03-18 14:55:25","resourceFullName":"testRessource","resourceId":3,"type":"shift"}];
let resources = [{
fullname: "resource 1",
id: 1
},
{
fullname: "resource 3",
id:3
}]
$("#calendar").fullCalendar({
locale: LOCALE_DEFAULT,
timezone: TIMEZONE_DEFAULT,
ignoreTimezone: IGNORE_TIMEZONE_DEFAULT,
slotDuration: '00:30:00',
height: HEIGHT_DEFAULT,
header: {
left: 'prev,next today',
center: 'title',
right: 'timelineDay, weekCustom' + /*, timelineWeek */', month, agendaDay'
},
buttonText: {
today: "today",
timelineDay: "timelineDay",
timelineWeek: "timelineWeek",
month: "month",
agendaDay: "agenda"
},
views: {
weekCustom: {
type: 'timeline',
timeFormat: 'H(:mm)',
buttonText: 'Semaine',
displayEventEnd: true,
duration: {week: 1},
slotDuration: {days: 1}
}
},
defaultView: "weekCustom",
lang: 'fr'/*$filter('translate')('language')*/,
scrollTime: "08:00:00",
resourceAreaWidth: "220px",
events: events,
editable: true,
droppable: DROPPABLE_DEFAULT,
allDayDefault: ALL_DAY_DEFAULT_DEFAULT,
allDay: ALL_DAY_DEFAULT,
allDaySlot: ALL_DAY_SLOT_DEFAULT,
defaultTimedEventDuration: TIME_EVENT_DURATION_DEFAULT,
resourceLabelText: "resources",
schedulerLicenseKey: SCHEDULER_LICENCE,
selectable: SELECTABLE_DEFAULT,
slotEventOverlap: SLOT_EVENT_OVERLAPP_DEFAULT,
selectHelper: SELECT_HELPER_DEFAULT,
eventResourceEditable: EVENT_RESOURCE_EDITABLE_DEFAULT,
resources: resources,
select: function (start, end, jsEvent, view, resourceObj) {
let event = {
start: start,
end: end,
title: "test"
};
//$("#calendar").fullCalendar('addEventSource', [event]);
//$("#calendar").fullCalendar('refetchEventSources', [event]);
//true for stick events
$("#calendar").fullCalendar('renderEvent', event, true);
},
eventClick: function (event, jsEvent, view) {
},
eventDrop: function (event, delta, revertFunc) {
},
eventResize: function (event, dayDelta, minuteDelta, revertFunc, jsEvent, ui, view) {
},
viewRender: function (view) {
},
loading: function (bool, view) {
}
});
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.9.0/fullcalendar.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar-scheduler/1.9.3/scheduler.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.21.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.9.0/fullcalendar.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar-scheduler/1.9.3/scheduler.min.js"></script>
<div id="calendar">
</div>
P.S. use the timeline day for a more efficient test.
Your code works fine, and creates the event quite happily - try it: select a time period (in any view), remember the date/time you chose, and then go to your "month" view. You will see the created event in the timeslot you selected.
The problem comes when you try to view the event in a view which uses resources. Your code does not specify a resourceId for the new event. Therefore, fullCalendar has no idea which resource to show the event on, and so cannot display it at all in any resource-aware view.
To fix this, simply take the resourceId supplied in the resourceObj parameter of the select callback, and include it in your new event object:
let event = {
start: start,
end: end,
title: "test",
resourceId: resourceObj.id
};
P.S. you should also run "unselect" after the call to "renderEvent", otherwise the timeslot chosen will remain highlighted on the calendar behind the created event (until or unless the user clicks elsewhere). In some views this is more obvious than others, but it doesn't look right. The command is simply:
$("#calendar").fullCalendar('unselect');
I need to filter the events that are displayed on the screen using a select. I am using .change to send the value of the selected option and the screen is refreshed, but I have not been successful.The events are displayed correctly if I remove the WHERE. I think the model is not getting the value of rut_usu. Any help is welcome.
Controller ( cCalendar )
public function geteventos(){
$rut_usu = $this->input->post('rut_jc');
$r = $this->mCalendar->geteventos();
echo json_encode($r, $rut_usu);
}
Model (mCalendar)
public function geteventos($rut_usu){
$this->db->select('CONCAT(estudiantes.pnombre," ", estudiantes.apellido_pa," ", estudiantes.apellido_ma,", ",motivos_citas.descripcion_mot) As title ,citas.id_ci id, citas.fecha_ini start, citas.fecha_ter end, citas.id_mot mot, CONCAT(estudiantes.pnombre," ", estudiantes.apellido_pa," ", estudiantes.apellido_ma) as estudiante');
$this->db->select('CONCAT(usuarios.pnombre," ", usuarios.apellido_pa," ", usuarios.apellido_ma) as jefe_c, estudiantes.rut_estu rut_estudiante');
$this->db->from('citas');
$this->db->join('estudiantes', 'citas.rut_estu = estudiantes.rut_estu');
$this->db->join('motivos_citas','citas.id_mot = motivos_citas.id_mot');
$this->db->join('usuarios','citas.rut_usu = usuarios.rut_usu');
$this->db->where('rut_usu',$rut_usu);
return $this->db->get()->result();
}
Javascript (send select value to filter events)
$("#rut_jc").change(function(){;
//rut_jc is the name of the select
var rut_usu = $("#rut_jc").val();
$.ajax({
url: "<?php echo base_url(); ?>" + "cCalendar/geteventos/",
type: 'post',
data: { "rut_jc": rut_usu },
success: function(response){
$("#calendar").fullCalendar('refetchEvents');
}
});
Javascript (show the events)
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay,listMonth'
},
defaultDate: new Date(),
navLinks: true, // can click day/week names to navigate views
businessHours: true, // display business hours
events: function(start, end, timezone, callback) {
$.post('<?php echo base_url(); ?>cCalendar/geteventos',
{ "start": start.format("YYYY-MM-DD"), "end": end.format("YYYY-MM-DD") },
function (data) {
callback($.parseJSON(data));
});
},
dayClick: function (date, jsEvent, view) {
date_last_clicked = $(this);
$('#modal_registrar').modal();
},
eventClick: function(event, jsEvent, view) {
$('#event_id').val(event.id);
$('#id_mot2').val(event.mot);
$('#nombre_estudiante').val(event.estudiante);
$('#jc2').val(event.jefe_c);
$('#rut_estudiante').val(event.rut_estudiante)
$('#start_f').val(moment(event.start).format('DD/MM/YYYY HH:mm:ss'));
$('#end_f').val(moment(event.end).format('DD/MM/YYYY HH:mm'));
$('#modal_editar').modal();
},
minTime: "08:30:00",
maxTime: "23:00:00"
});
when you run $("#calendar").fullCalendar('refetchEvents'); it runs another ajax call (the one defined in the calendar's events option), separate to the one you made explicitly from the "change" handler. You're throwing away the response from that call where you included rut_jc / rut_usu. You don't do anything with it. So it's no surprise it doesn't affect the calendar.
Instead of making a separate, meaningless ajax call, simply integrate this new functionality into your existing code:
Calendar Code
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay,listMonth'
},
defaultDate: new Date(),
navLinks: true, // can click day/week names to navigate views
businessHours: true, // display business hours
events: function(start, end, timezone, callback) {
$.post('<?php echo base_url(); ?>cCalendar/geteventos', {
"start": start.format("YYYY-MM-DD"),
"end": end.format("YYYY-MM-DD"),
"rut_jc": $("#rut_jc").val() //add the extra value to the existing filter parameters. fullCalendar can then use it directly.
},
function(data) {
callback($.parseJSON(data));
}
);
},
dayClick: function(date, jsEvent, view) {
date_last_clicked = $(this);
$('#modal_registrar').modal();
},
eventClick: function(event, jsEvent, view) {
$('#event_id').val(event.id);
$('#id_mot2').val(event.mot);
$('#nombre_estudiante').val(event.estudiante);
$('#jc2').val(event.jefe_c);
$('#rut_estudiante').val(event.rut_estudiante)
$('#start_f').val(moment(event.start).format('DD/MM/YYYY HH:mm:ss'));
$('#end_f').val(moment(event.end).format('DD/MM/YYYY HH:mm'));
$('#modal_editar').modal();
},
minTime: "08:30:00",
maxTime: "23:00:00"
});
Change handler for the <select>
$("#rut_jc").change(function(){;
$("#calendar").fullCalendar('refetchEvents');
});
Additionally, you weren't passing the $rut_usu value to your model (instead, you just sent it back in the response, which made no sense).
N.B. I have also taken the liberty of adding the start/end dates sent by fullCalendar into your controller and model. As I mentioned in my answer to your earlier question a few days ago, you now need to alter your database query with another WHERE clause to ensure it only returns events which start or end between these two dates (inclusive).
Controller
public function geteventos(){
$start = $this->input->post('start');
$end = $this->input->post('end');
$rut_usu = $this->input->post('rut_jc');
$r = $this->mCalendar->geteventos($start, $end, $rut_usu);
echo json_encode($r);
}
Model
public function geteventos($start, $end, $rut_usu){
//...etc
I don't want user to be able to create allDay events in my calendar. I want calendar to change view from month view to agendaDay view by clicking the date, but everytime when I click the date calendar changes the view to agendaDay but it tries to create an allDay event.
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
dayClick: function(date,allDay, jsEvent, view) {
if (allDay) {
// Clicked on the entire day
$('#calendar').fullCalendar('gotoDate',date)
$('#calendar').fullCalendar('changeView', 'agendaDay')
}
view = $('#calendar').fullCalendar('getView');
},
selectable: function(){
if(view.name=='agendaDay' ){
return true;
}else{
return false;
}
},
selectHelper: true,
select: function(start, end) {
var title = prompt('Event Title:');
var eventData;
if (title) {
eventData = {
title: title,
start: start,
end: end,
};
$('#calendar').fullCalendar('renderEvent', eventData, true);
}
$('#calendar').fullCalendar('unselect');
}
});
You're handling dayClick, selectable and select; whereas this could be achieved by only handling select:
select: function(start, end, jsEvent, view) {
if (view.name=='month') {
$('#calendar').fullCalendar('changeView', 'agendaDay');
$('#calendar').fullCalendar('gotoDate', start)
} else {
var title = prompt('Event Title:');
var eventData;
if (title) {
eventData = {
title: title,
start: start,
end: end
};
$('#calendar').fullCalendar('renderEvent', eventData, true);
}
}
$('#calendar').fullCalendar('unselect');
}
See http://jsfiddle.net/wijgerden/t81qtupz/ for a JSFiddle demo using FullCalendar v2.1.1; note that this still allows users to create all-day events on the agendaWeek and agendaDay views. On month view selecting date(s) will switch the view to agendaDay (first day in case of multi-select), while still allowing clicking on events.
On the first load of the page, it shows a single event per day, but on the second load (or refresh of the page) it adds a duplicate event on the same day in the full calendar.
Here is my code:
var CalendarView = Backbone.View.extend({
el : '#calendar-box',
initialize : function() {
// TODO for instance: more instances, Event Bus bindings... only once.
this.calendarModel = new CalendarModel();
$('#calendar-box').hide();
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
this.calendarModel.fetch({
success : function(model, response, options) {
$.unblockUI();
var count=0;
var eventsList=[];
model.attributes.result.forEach(function(){
eventsList.push({
id: model.attributes.result[count].eventId,
title:model.attributes.result[count].title,
start: new Date(model.attributes.result[count].startDate),
end: new Date(model.attributes.result[count].endDate),
attorneyName: model.attributes.result[count].attorneyName,
codeLitOrg: model.attributes.result[count].codeLitOrg,
balance: model.attributes.result[count].balance,
litCode: model.attributes.result[count].litCode
});
count++;
});
if (!_.isEmpty(eventsList)){
$('#calendar').fullCalendar({
editable: true,
events: eventsList,
eventMouseover: function(event, jsEvent, view) {
var info = event.title+'\nBK/LIT: '+event.codeLitOrg+'\nBalance: '+event.balance
+'\nAttorney: '+event.attorneyName+'\nLitCode: '+event.litCode;
$(jsEvent.target).attr('title', info);
},
theme: false,
height:575,
weekMode:'liquid',
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
});
}
},
error : function(model, xhr, options) {
$.unblockUI();
}
});
$.eventBus.on('calendarModalLoaded',function(){
if (!($('.fc-border-separate').html())){
$('#calendar').fullCalendar('today');
}
});
},
render : function() {
// TODO for instance, bindings elements after ready in DOM.
$('#calendar').fullCalendar('today');
return this;
},
events : {
'click a.op-attorney-info' : 'onAttorneyInfo',
'click .go-back-link' : 'goBack'
},
goBack: function(){
$('#calendar-box, .content-box').toggle();
//$('.content-box').toggle();
//$('.go-back-link').hide();
},
onAttorneyInfo : function(ev) {
// TODO for instance, fetch attorney's model
}
});
return CalendarView;
});
I have tried $('#calendar').fullCalendar('removeEvents'), but it is also not working.
Please help me out.