I have events formatted and in a variable named events as follows (3 events listed, each with title, start ,end)
[
{title : 'workout', start : '2018-01-02T15:00:00', end : '2018-01-02T16:00:00'},
{title : 'workout3', start : '2018-01-04T15:30:00', end : '2018-01-04T16:30:00'},
{title : 'workout', start : '2018-01-03T1:30:00', end : '2018-01-03T1:50:00'}
]
When I pass the events variable to the calendar using events: events, the events are not displayed.
In JavaScript, if I simply alert the variable events to the screen and copy/paste it into my code as the events variable, the events all appear in the calendar correctly.
Why would the same exact data in the same exact format not appear in the calendar? How can I get the data in the variable to render?
Code:
$(document).ready(function() {
var events1 = [];
$('#caltable tbody>tr').each(function () {
table_row_data = [];
$('td', this).each(function () {
table_row_data.push($(this).text());
});
if (table_row_data.length > 0) { // Only add a row if it's not empty
events1.push("{"+table_row_data+"}");
}
});
var events = "["+events1+"]"
alert(events);
I'm assuming you have problems adding events after an async call.
Because initializing the fullcalendar works perfectly using the following:
$('#calendar').fullCalendar({'events': [...]});
For async calls, you can attach the event addEventSource to add events programmatically.
Take a look at this code snippet:
let myEvents = [{
title: 'event1',
start: '2018-01-01'
},
{
title: 'event2',
start: '2018-01-05',
end: '2018-01-07'
},
{
title: 'event3',
start: '2018-01-09T12:30:00',
allDay: false // will make the time show
}
];
$('#calendar').fullCalendar();
//Simulate an async call
setTimeout(function() {
$('#calendar').fullCalendar('addEventSource', myEvents);
}, 2000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.8.0/fullcalendar.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.8.0/fullcalendar.js"></script>
<div id='calendar'></div>
I had the same problem because I was using momentJS objects for the event time ('start'/'end') and it has to be convert it to ISO string (exemple: moment(startTime).toISOString()) to make it work.
Hope it helps
Related
I was successfully able to specify multiple sources: My SQL server source, and an empty array to hold any user-generated events userAddedEvents = []. The idea was that I could use this array later to "save" new events to my server.
var userAddedEvents = []; //container for event objects that will hold user-generated content
var calendar = new FullCalendar.Calendar(calendarEl, {
eventSources: [
{
events: function (fetchInfo, successCallback, failureCallback) {
$.ajax({
url: url,
type: 'post',
contentType: "application/json; charset=utf-8", //include fetchInfo in request body instead of form-data
dataType: "json",
data: JSON.stringify(fetchInfo), //the fetchInfo object must be stringified
success: function (data) {
events = $.merge([], data.events);
successCallback(events);
}
});
}
}, //end server source
{
id: 'userAddedEvents',
events: userAddedEvents
} //end local array source
]
});
So, here's me trying to add an event to my userAddedEvents source...
select: function (info) {
// https://fullcalendar.io/docs/select-callback
console.log(info)
console.log('selected ' + info.startStr + ' to ' + info.endStr)
calendar.addEvent({
start: info.startStr,
end: info.endStr,
rendering: 'background', //v4 and v5 use different terminology
color: '#ff9f89',
selected: true, //custom, extended property
}, userAddedEvents);
calendar.unselect(); //clear the current selection
},
Anyway, long story short... when I try to dump out the results of userAddedEvents, it's empty, although, I do see new content on my calendar.
==UPDATED== with example included... I added a custom button where I attempt to get content from the userAddedEvents array.
Alternatively (also shown in the example), I've had success getting ALL events with calendar.getEvents(), then using $.grep to filter some specific property or extended property. Ultimately though, I suppose I'm trying to use a "temporary event source" for the sake of convenience -- I can act upon the userAddedEvents array, stringify it, empty it, etc. I do not know how to getEvents for a specific source object.
customButtons: {
getUserCreatedEvents: {
text: 'Get User Events',
click: function () {
console.log(calendar.getEventSources()); //both event sources are listed
console.log(calendar.getEventSourceById(userAddedEvents)); //missing the id in output {calendar, id, internalEventSource, url}
console.log(calendar.getEventSourceById('userAddedEvents')); //has the the id in output {calendar, id, internalEventSource, url}
console.log(userAddedEvents) //the array is empty
/*
events = calendar.getEvents();
// console.log(events)
var filteredResultsGREP = $.grep(events, function (event) {
return event.rendering === 'background';
});
*/
/*
https://fullcalendar.io/docs/Event-toPlainObject (version 5 only)
*/
// this WILL show any events added based on the property specified
// console.log(filteredResultsGREP);
}
}
}
How do I get the events that are new? I want to hold all user-created events before I send them to SQL for processing.
Firstly, apologies for totally forgetting about this question, having started to help with it.
After some digging it looks like you can't get the raw events for an individual event source, which is a bit annoying.
So I think actually your simplest approach is just to add the events to your separate array, without worrying about the structure in fullCalendar. Then you can just send that list to the server when you want to save them.
select: function (info) {
var evt = {
start: info.startStr,
end: info.endStr,
rendering: "background", //v4 and v5 use different terminology
color: "#ff9f89",
selected: true //custom, extended property
};
calendar.addEvent(evt);
userAddedEvents.push(evt);
calendar.unselect(); //clear the current selection
},
Demo: https://codepen.io/ADyson82/pen/abdVVNM
The only extra complication you might have is if you allow events to be dragged or resized (or otherwise edited) after they've been added, you'll have to sync that with the separate array, which is a bit of extra work.
I'm filtering my calendar, I change the start and end date, status of my events, and other stuffs. I do that with:
$("body").on("click", "#btnFiltrar", function() {
fechaIni = $("#fechaIni").val();
fechaFin = $("#fechaFin").val();
cp = $("#txtCP").val();
var events = {
url: "./php/xxxxxxxx.php",
type: "POST",
data: {
fechaIni: fechaIni,
fechaFin: fechaFin,
cp: cp,
provincia: provincia,
...
}
}
$("#calendar").fullCalendar("removeEventSource", events);
$("#calendar").fullCalendar("addEventSource", events);
$("#calendar").fullCalendar("refetchEvents");
});
It works fine. But when I want to change the variable hiddenDays dynamically, I can't make it work!
I add to my code this:
(By default this variables are global)
var dias = ["0","1","2","3","4","5","6"];
var ocultarDias = []; // is empty because it shows all days
// inside click button
diasSeleccionados = $("#selDias").val(); // returns array eg: ["1","2","3","4","5"]
ocultarDias = $(dias).not(diasSeleccionados).get(); // compare 2 arrays and get the difference
So, with that and the call fullcalendar with the attribute:
function llenarCalendario() {
$("#calendar").fullCalendar({
lang: 'es',
firstDay: 1,
hiddenDays: ocultarDias,
...
});
}
I miss something? I want to do this without reload the page, just call again the function or, as the function on click button, refetchEvents or something like that. Is possible?
You can recreate the calendar and add the events, which you have already have, again with the following method.
function reloadCalendar(){
//Get all events in a array
var events = $("#calendar").fullCalendar( 'getEventSources' );
$("#calendar").fullCalendar( 'destroy' ); // Destroy the calendar
$("#calendar").fullCalendar({ //Recreate the calendar with the hidden days
hiddenDays: [ 2, 4 ]
});
//With JavaScript
events.forEach(function(event) { //Restore all events
$("#calendar").fullCalendar( 'addEventSource', event);
});
//With jQuery
var jEvents = $.makeArray(events);
$(jEvents).each(function( i ) {
$("#calendar").fullCalendar( 'addEventSource', events[i]);
});
}
Now you simply can call the method. I hope it was helpful.
var newhiddendays = [0, 6]; // show Mon-Fr (hide Sat/Sun)
$('#calendar').fullCalendar('option', 'hiddenDays', newhiddendays);
You have to use it with optionmethod in order to set new options for your calendar
https://fullcalendar.io/docs/utilities/dynamic_options/
function llenarCalendario() {
$("#calendar").fullCalendar('option',{
lang: 'es',
firstDay: 1,
hiddenDays: ocultarDias,
...
});
}
I finally found a way to do that without reload the page. With the help of #todes using 'options' and adding the three lines below that.
Very important: the array of hiddenDays must be an array of ints.
var dias = ["0","1","2","3","4","5","6"];
var ocultarDias = []; // is empty because it shows all days
$(document).ready(function () {
llenarCalendario();
$("body").on("click", "#btnFiltrar", function() {
fechaIni = $("#fechaIni").val();
fechaFin = $("#fechaFin").val();
cp = $("#txtCP").val();
var diasSeleccionados = $("#selDias").val(); // select multiple, returns array eg: ["1","2","3","4","5"]
ocultarDias = $(dias).not(diasSeleccionados).get(); // compare 2 arrays and get the difference
ocultarDias = ocultarDias.map(Number); // array of strings to int for fullcalendar to work
var events = {
url: "./php/xxxxxxxxxx.php",
type: "POST",
data: {
fechaIni: fechaIni,
fechaFin: fechaFin,
cp: cp
}
}
$("#calendar").fullCalendar('option', {
hiddenDays: ocultarDias
});
$("#calendar").fullCalendar("removeEventSource", events);
$("#calendar").fullCalendar("addEventSource", events);
$("#calendar").fullCalendar("refetchEvents");
});
});
function llenarCalendario() {
$("#calendar").fullCalendar({
lang: 'es',
firstDay: 1,
hiddenDays: ocultarDias,
...
});
}
I'm try to update fullcalendar event after user change date from bootstrap-datepicker: http://bootstrap-datepicker.readthedocs.org/en/latest/events.html
I'm following the (only) solution found here: How to combine jquery date-picker and jquery full calendar
which for bootstrap-datepicker would be:
$('#fullcalEventEnd').datepicker().on('changeDate', function(evt){
var endDate = evt.date;
list.eventUpdated.end = moment(endDate).format("DD-MM-YYYY");
$(cal).fullCalendar('renderEvent', list.eventUpdated, true);
});
What it should do is, update an event created once the user selects the calendar, so on my select function i have:
select: function(start, end) {
$('#fullcalEventFrom').datepicker('setValue', start);
$('#fullcalEventTo').datepicker('setValue', end);
list.eventUpdated = {
title: eventTitle,
start: start,
end: end
};
$(cal).fullCalendar('renderEvent', list.eventUpdated, true); // stick? = true
$(cal).fullCalendar('updateEvent', event);
},
....
list is my global object: var list = {}
But so far nothing, I'm not able to update the event and this line
$(cal).fullCalendar('renderEvent', list.eventUpdated, true); is giving me an error and I don't understand why
Anyone already face this problem?
I am working with Kendo UI, js and the scheduler component.
My question is, if there is a way to disable a specific event from scheduler.
I find this, but this disables all events in scheduler. I want to disable just a specific event. The code should be something like this>
function disableEvents()
{
var data = $("#scheduler").data("kendoScheduler").dataSource.data();
data.forEach(function(event){
if(event.ID='2')
{
event.disable = true; //I have tried with event.editable = true;
}
});
}
I can't find the property editable nor disable, or something like that. Maybe there is a way to disable it using jquery. Can anybody help me?
Thank you!
You will need to implement all the events specified in the restriction example of Kendo and preventDefault behaviour where ever your condition is not successfully.
For reference: Kendo Restriction Events Description.
You will need to take care of all the events (i.e. edit, save, resize, move) if you want to disable any event from any changes. The events are as below:
resize: function(e) {
if (e.event.meetingID = 1) {
this.wrapper.find(".k-marquee-color").addClass("invalid-slot");
e.preventDefault();
}
},
move: function(e) {
if (e.event.meetingId = 1) {
this.wrapper.find(".k-event-drag-hint").addClass("invalid-slot");
}
},
save: function(e) {
if (e.event.meetinID = 1) {
e.preventDefault();
}
},
edit: function (e) {
if (e.event.meetinID = 1) {
e.preventDefault();
}
}
I have updated the Kendo Restriction example with your condition: Demo
Use the event event's preventDefault method:
$("#scheduler").kendoScheduler({
date: new Date("2013/6/6"),
views: ["day", "month"],
dataSource: [{
id: 1,
start: new Date("2013/6/6 08:00 AM"),
end: new Date("2013/6/6 09:00 AM"),
title: "Interview editable"
}, {
id: 2,
start: new Date("2013/6/6 06:00 AM"),
end: new Date("2013/6/6 07:00 AM"),
title: "Interview not editable"
}],
edit: function (e) {
if (e.event.id === 2) {
e.preventDefault();
}
}
});
(demo)
I've written a program that includes a form that the user interacts with. Because there are lots of events bound to different buttons I have written a loop that parses some JS that contains the form input information. Here is some example data:
var value = 0,
forms = {
place_controls : {
attrs : {
'class' : 'place-form'
},
input : {
place_x : {
attrs : {
type : 'text',
},
events : {
change : function () {
value = 10;
}
}
},
place_y : {
attrs : {
type : 'text',
},
events : {
change : function () {
value = 50
}
}
}
}
}
}
The data is then parsed by this:
$.each(forms, function (form_index, form) {
var $form_markup = $('<form>').attr(form.attrs);
// Next: loop through each input element of the form we've reached
$.each(form.input, function (element_index, element) {
var $elem = $('<input>').attr(element.attrs);
$elem.appendTo($form_markup);
if (element.events !== undefined) {
$.each(element.events, function (event_index, event) {
$elem.bind(event_index, event);
//$form_markup.on(event_index, $elem, event);
});
}
});
$form_markup.appendTo($form_goes_here);
});
As you can see, I'm using .bind() at the moment, however I want to use .on(). Unfortunately, when I do this all of the items within a form are bound to the last event parsed by the function. When I use .bind() everything works as planned - i.e. Clicking on 'place_x' sets value to 10, clicking 'place_y' sets value to 50.
When using .on(), whichever I change sets value to 50, which I am assuming is because the last function is becoming bound to each event.
Can anybody see what I have done wrong?
Update: There are many different ways to do this, and I have subsequently changed how my code works, however this question is related to why .bind() is working and why .on() is not.
//$elem.bind(event_index, event);
//It looks like you should just be using .on() like this
$elem.on(event_index, event);
The way it looks like you are trying to use .on() is in the live -bubbling- event sort of way, it looks like only the last event you are created is sticking, why each value just gets set to 50.
//$form_markup.on(event_index, $elem, event);
You can create elements with property maps that include handler functions in one simple call:
var $elem = $('<input/>', properties);
The "properties" object can contain event handlers:
var $elem = $('<input/>', {
type: 'text',
name: 'somethingUseful',
click: function(ev) { /* click handler */ },
change: function(ev) { /* change handler */ },
css: { color: "red" }
});