I have a modal which has two event dates how to create two events in fullcalendar when clicked on add button.I tried this.
$('#btnAdd').on('click', function (e) {
$('#interviewModal').modal('hide');
var arr = new Array();
var event = {
title : $('#txtTitle').val(),
start : $('#txtStartDate').val(),
end : $('#txtEndDate').val(),
allDay: false,
stick : true
}
var event2 = {
title : $('#txtTitle').val(),
start : $('#txtStartDate2').val(),
end : $('#txtEndDate2').val(),
allDay : false,
stick : true
}
arr.push(event);
arr.push(event2)
e.preventDefault();
$('#calendar').fullCalendar('renderEvent',arr);
});
Also my modal looks like this
Modal Picture
Use "renderEvents" instead of "renderEvent". https://fullcalendar.io/docs/event_rendering/renderEvents/
$('#calendar').fullCalendar('renderEvents', arr, true);
This accepts an array of events, instead of a single one.
Related
I'm using fullcalendar v2 and the sources of the events are selectable from an ul-li menu. The initial call uses the link from the first li and I may navigate through all the months in the calendar. When I use the second link, fullcalendar retrieves the events from the previous link as well as the new link. On each new select, fullcalendar remember the event sources. How can I disable this? Here my code:
$("#chgBranch li").on("click", function (event) {
event.preventDefault(); // To prevent following the link (optional)
var urlEvents = $(this).children('a').attr('href');
var branchName = $(this).children('a').text();
$('#calendarSchedules').fullCalendar('removeEvents');
$('#calendarSchedules').fullCalendar('removeEventSource');
// refill calendar
fillEvents(urlEvents, branchName);
});
function fillEvents(urlEvents, branchName) {
// change title of potlet box
var newTitle = '<i class="fa fa-calendar"></i> Available schedules for: ' + branchName;
$('#calendarCaption').html(newTitle);
$('#calendarSchedules').fullCalendar({
year: <?= $yy ?>,
month: <?= --$mm ?>, // javascript month is 0 based
date: 1,
header: {
left: '',
center: 'title',
right: 'prev,next,today'
},
defaultView: 'month',
firstDay: 1, // monday
editable: false,
slotEventOverlap: false,
selectable: true,
selectHelper: true,
dayRender: function (view, element) {
$('.fc td.fc-sun').css('background', '#E7EFEF');
$('.fc td.fc-sat').css('background', '#E7EFEF');
},
eventClick: function (event) {
$('#dueTime').show();
$('#duedate').val(moment(event.start).format('YYYY-MM-DD'));
$('#duetime').val(moment(event.start).format('HH:mm:ss'));
$('#isPartitionable').val(event.partitionable); // user clicked on partitionable dispo or not
}
});
$('#calendarSchedules').fullCalendar('addEventSource', urlEvents);
}
// load first branch item
$('#chgBranch li a:first').trigger('click');
I think you should destroy your calendar also. Because you are initializing fullcalendar every tine on sources change from ul-li.
Try below one.
$("#chgBranch li").on("click", function (event) {
event.preventDefault(); // To prevent following the link (optional)
var urlEvents = $(this).children('a').attr('href');
var branchName = $(this).children('a').text();
$('#calendarCaption').fullCalendar( 'destroy' );
// refill calendar
fillEvents(urlEvents, branchName);
});
This will work for sure. I tried locally and works fine.
I tried it with following method which also works fine, but #Chintan method is also fine:
$('#calendarSchedules').fullCalendar('removeEvents');
$('#calendarSchedules').fullCalendar('removeEventSource', storedEventSource);
And I store the event source in a hidden field once the calendar rendered.
I am trying to separate a list of JSON data into segments ("sliders") and have succeeded in creating a data object in the format I want, however the foreach binding is not working as expected.
HTML Template:
<div class="slide" data-bind="foreach: actionSliders">
Stuff
</div>
Here is my relevant Knockout code:
function Slider() {
this.actions = ko.observableArray([]);
}
var viewModel = {
actionSliders: ko.observableArray([])
};
viewModel.loadData = function() {
//LOAD Actions from API
jQuery.ajax({
type: 'GET',
url: 'http://'+window.location.hostname+'/api/actions/get_author_posts/',
dataType: 'json',
success: function (ActionData) {
console.log('getJSON data - Actions',ActionData.posts);
var actionSlidersCount = 0;
viewModel.actionSliders([]);
//create the first slider array
viewModel.actionSliders().push(new Slider());
viewModel.actionSliders()[0].actions([]);
jQuery.each(ActionData.posts, function(index) {
// add each action to the current slider
viewModel.actionSliders()[actionSlidersCount].actions().push(new Action(this));
//add a new slider every 5 records
var calc = (parseInt(index)+1)%5;
if(calc ==0 ){
//new slider
actionSlidersCount++;
viewModel.actionSliders().push(new Slider());
viewModel.actionSliders()[actionSlidersCount].actions([]);
}
});
console.log('ActionSliders',viewModel.actionSliders());
},
data: { },
async: true
});
};
This is what my data looks like in the console:
ActionSliders
[Slider, Slider, Slider, Slider, Slider, Slider, Slider, sortNum: function, random: function, sum: function, max: function, min: function…]
0: Slider
actions: Object[0]
__proto__: Slider
1: Slider
2: Slider
3: Slider
4: Slider
5: Slider
6: Slider
length: 7
__proto__: Array[0]
* I can access all the data with console commands:
> viewModel.actionSliders()[0].actions()[0]
Action {id: 197, title: "Turned off the tap while brushing my teeth"…}
> viewModel.actionSliders()
[ Slider, Slider, Slider, Slider, Slider, Slider, Slider]
So, as you can see, in the working model (no errors in console, no data-bind errors), the object is fully populated with data, and in the template, "stuff" should repeat 6 times - once for each Slider, but the loop isn't even working. Is there a problem with having observable arrays inside of others? Am I missing something in the way I am creating the Slider objects? Any advice is most welcome, please.
Since you pushed new Slider object into your actionSliders observableArray I guessing the structure might be like this:
actionSliders = [
{
actions = {}
},
{
actions = {}
}
];
I'm sorry if this doesn't work for your, but how if you try to bind it like this ? :
<div class="slide" data-bind="foreach: actionSliders().actions">
Stuff
</div>
I found the answer, it was a two part issue.
The reason why foreach wasn't working was because I was pushing to the function, instead of the array. I needed to use:
viewModel.actionSliders.push(new Slider());
instead of:
viewModel.actionSliders().push(new Slider());
Once I did that, the foreach worked for the main object
Then, I realized I needed to inject the data inside the class, instead of from outside. To remedy that, I modified the code like this:
var tempActionArray = [];
jQuery.each(ActionData.posts, function(index) {
//add an action to the current slider
var tempAction = new Action(this);
tempActionArray.push(tempAction);
var calc = (parseInt(index)+1)%5;
if(calc ==0 ){
//add a new slider
actionSlidersCount++;
viewModel.actionSliders.push(new Slider(tempActionArray));
//reset temp array
tempActionArray = [];
//viewModel.actionSliders[actionSlidersCount].actions([]);
}
});
function Slider(data) {
var data = data || [];
this.actions = ko.observableArray([]);
var Actions = [];
//console.log("slider data",data)
jQuery.each(data, function(index) {
//console.log("action index",data[index])
Actions.push(data[index]);
});
this.actions = Actions;
}
and now all is good in the world! :) Moving on...
I have FullCalendar installed and working great, pulling in courses from my database.
You can view different courses based on clicking a button that submits the page again but passes different criteria.
The Issue is that on reloading of the page and the new content it skips back to the current date which is rather annoying when when you are looking at courses 3 months into the future!!
Does anybody know how to make the calendar go back to the page you where on after you have refreshed the page???
I have a feeling it might be something to do with getdate as I got the following code to work but can't seem to pass the result back through the URL and into the calendar setup.
$('#my-button').click(function() {
var d = $('#calendar').fullCalendar('getDate');
alert("The current date of the calendar is " + d);
});
If you use jquery.cookie you can store the currently viewed date in a cookie for the page being viewed and use that value to set the defaultDate when the page reloads. Pass these in as options when you initialise your calendar:
defaultView: Cookies.get('fullCalendarCurrentView') || 'month',
defaultDate: Cookies.get('fullCalendarCurrentDate') || null,
viewRender: function(view) {
Cookies.set('fullCalendarCurrentView', view.name, {path: ''});
Cookies.set('fullCalendarCurrentDate', view.intervalStart.format(), {path: ''});
}
This code also saves the current view (e.g. month, day etc...)
I used a combination of the two above. I set the localStorage value for the start date when creating, moving, or resizing an event as well as viewRender and then assigned that value to the defaultDate.
defaultDate: localStorage.getItem('Default_FullCalendar_Date'),
viewRender: function(view) {
localStorage.setItem('Default_FullCalendar_View', view.name);
...
},
select: function(start, due){
localStorage.setItem('Default_FullCalendar_View', start);
...
},
eventDrop: function(event, delta, revertFunc, jsEvent, ui, view){
localStorage.setItem('Default_FullCalendar_View', event._start._d);
...
},
eventResize: function(event, delta, revertFunc, jsEvent, ui, view){
localStorage.setItem('Default_FullCalendar_View', event._start._d);
...
}
Works like a charm.
You can use gotoDate method:
var d = $('#calendar').fullCalendar('getDate');
$('#calencar').fullCalendar( 'gotoDate', d.getFullYear(), d.getMonth(), d.getDate() )
Here is an updated answer for version 4 and 5 of fullcalendar.
since viewRender is no longer an option in these versions. I came up with a different approach using the loading option.
The loading option will give you a boolean argument stating whether the calendar is done loading or not. Inside that function I check if the calendar is done loading and if so, I set the calendar date to localStorage. Next I created an if else statement before the fullcalendar object to check if the localstorage item exists, and if so I set the defaultDate option in the calendar object to to localStorage date; if not, I just set it to today's date.
Example:
let viewDate;
const savedDate = localStorage.getItem("calDate");
if (savedDate !== null) {
viewDate = new Date(savedDate);
} else {
viewDate = today();
}
const calendarElement = document.getElementById('your_calendar');
const calendar = new FullCalendar.Calendar(calendarElement, {
defaultDate: viewDate,
loading: function(stillLoading) {
if (stillLoading === false) {
// When Calendar is done loading....
localStorage.setItem("calDate", calendar.getDate());
}
},
});
I am trying to select events on fullcalendar, based on user selection.
Example: if user selects class A, then all classes with the same ID should turn green (using applied className).
I am having trouble applying classes to the other events that I can successfully select by ID. I guess my issue is combining the event objects with jQuery objects.
sample code:
eventClick: function(event) {
$(this).addClass("reg_selected"); //this works fine on selected event
var selectedID = event.id
alert(selectedID); //get event.ID, and use it to find similar ones.
var similarEvents = $("#calendar").fullCalendar('clientEvents',selectedID).addClass("reg_selected");
the error I get is:
addClass is not a function
I also tried this method of looping, and got the same error:
for (var i = 0; similarEvents.length > i ; i++){
alert(similarEvents[i].title);
similarEvents[i].className("reg_selected");
}
the alert() worked, but the className() generated the same error as above
This answer for a very similar situation, but when event classes are selected with round-trip to the event source for possible persistence in the db or checks.
Class name can be specified in the event object in the source as follows (start and end given for the context only):
[{
...
"className": "selected-event",
"start": '2017-05-01T08:30:00.0',
"ends": '2017-05-01T09:00:00.0',
...
}, ...]
The idea is that user clicks the event; ajax call to select events goes to backend; onsuccess, frontend javascript does$calendar.fullCalendar('rerenderEvents'); and receives the event source with events' classes. The immediate child of .fc-event-container gets the specified class, in the example above - selected-event.
As a result, the selection can be persisted on the backend.
clientEvents returns an array of matching objects. You need to iterate through the array (in your case similarEvents) and call addClass for each item
Update:
There is also issues using an id to update multiple events, using a filter function instead is a better way to go.
eventClick: function(event) {
var similarEvents = $("#calendar").fullCalendar('clientEvents', function(e) { return e.test === event.test });
for (var i = 0; similarEvents.length > i ; i++){
similarEvents[i].className = 'reg_selected';
$('#calendar').fullCalendar('updateEvent', similarEvents[i]);
}
},
See jsfiddle
For fullcalendar add event class, id and title see this.
if($('#eventTitle').val() == "Avilable") {
eventClass = "avilable";
}else {
eventClass = "unavilable";
}
$myCalendar.fullCalendar('renderEvent', {
id:response,
title: title.val(),
start: start.val(),
end: end.val(),
allDay: true,
className: eventClass,
color: color
}, true
);
I was able to get it working with the following code:
eventRender: function (eventObj, $el) {
$el.addClass(eventObj.ClassName);
},
eventObj.ClassName = "calendar-priority-warning"
I use jQuery fullCalendar (http://arshaw.com/fullcalendar/docs/selection/unselectAuto/)
I use Selectable version of this calendar (http://arshaw.com/js/fullcalendar/demos/selectable.html)
It's working fine however I want to cancel/delete my old selections if I continue selecting new dates.
Lets say I chose 1 Jan and gave a title to it.
When I try to select 2 Jan, I want to see only 2 Jan selection.
I thought unselectAuto is for this but I couldnt manage to make it work :(
Any ideas?
I used unselectAuto right under
selectable: true,
unselectAuto: true,
First it's still necessary to use the $('#yourCalendar').fullCalendar('unselect'); function.
The second thing that I needed to do, was to specify how the unselect callback was going to behave (when setting up the fullcalendar options). For me I had to unbind the submit button from my form
unselect: function(){
$('#submitButton').unbind();
},
It worked great!
I was able to reach this conclusion after reading this post "multiple events created"
u can try this way, this works for me :)
var liveDate = new Date(); // current Date
var calendar = $('#calendar').fullCalendar({
select: function (startDate, endDate) {
if (liveDate > startDate) {
alert('Selected date has been passed');
return false;
} else {
//do your wish
}
calendar.fullCalendar('unselect');
}
});
Had the same problem but my user was interfacing directly with the calendar and multiple events were being generated. ie. not through a form with a button and therefore nothing to "unbind" as many of the previous solutions.
To only allow one selection and to clear previous submissions I changed the select function as follows:
select: function(start, end) {
var title = "Desired Booking";
var eventData;
eventData = {
title: title,
start: start,
end: end
};
$('#calendar').fullCalendar('renderEvent', eventData, true); },
select: function(start, end) {
$('#calendar').fullCalendar('removeEvents');
$('#calendar').fullCalendar('rerenderEvents')
var title = "Desired Booking";
var eventData;
eventData = {
title: title,
start: start,
end: end
};
$('#calendar').fullCalendar('renderEvent', eventData, true); },
This did the trick for me.
I had problems with unselectAuto also. Sometimes it would unselect when I didn't want it to, and sometimes it would NOT unselect when I DID want it to. My solution was to manually trigger the unselect method.
Here's how to unselect all currently selected:
$('#yourCalendar').fullCalendar('unselect');
You can put this line of code inside custom jQuery events that you bind outside of the plugin. You can also include it in fullCalendar callbacks, etc...
Hope this helps.
Scott
Here is an exemple of Version 5 doing the unselect
You could do it by :
const calendarApi = selectInfo.view.calendar;
calendarApi.unselect(); // clear date selection
Use this code
$('#trainings_modal').on('hidden', function () {
$('#trainings_modal *').unbind(); // Unbind all events
});
Unbind on hide form with any method (i.e esc press, or out key)