I figured out how to add en event quickly in fullcalendar, The idea is add to calendar, display and after save to database, without wait for database, but then events recently added gets duplicate when going back a week and comeback.
The code for add the event to calendar is this:
// First add the event to calendar, displaying almost instantly.
var idTemp = Math.floor(Math.random() * 100000) + 1;
var event = {
id: idTemp,
title: TextoEvento,
start: CalendarInfoSelect.start,
end: CalendarInfoSelect.end,
allDay: false,
tituloOriginal: TextoEvento,
backgroundColor: colorEvento,
textColor: colorEventoTexto
};
calendar.addEvent(event );
// Then, add to database:
$.ajax({
cache: false,
url: '#Url.Action("EventAddedTareaReciente", "CH")',
type: "POST",
dataType: 'json',
data: {
id: Idbd,
idAct: IdAct,
idProy: IdProy,
idProd: IdProd,
newStart: CalendarInfoSelect.startStr,
newEnd: CalendarInfoSelect.endStr,
ini: CalendarInfoSelect.start.toISOString(),
fin: CalendarInfoSelect.end.toISOString()
},
success: function (data) {
if (data.Id > 0) {
event = calendar.getEventById(idTemp);
// Here set id with database's one
event.setProp('id', data.Id);
}
else {
event = calendar.getEventById(idTemp);
event.remove();
}
},
error: function (xhr) {
event = calendar.getEventById(idTemp);
event.remove();
}
});
There is no error here it's works fine.
But when the user click to got one week back and comeback to the original week the event gets duplicate.
If the user add several event this ways this events gets duplicate in calendar.But they are not duplicate in database when refresh browser (F5) the display it's perfectly fine.
It's like the events add this way get sticky in memory.
Any help, ideas? I can't find a solution. Maybe there is another way to do that.
I use FullCalendar Core Package v4.3.1
Thanks
As per https://fullcalendar.io/docs/v4/Calendar-addEvent, if you specify an event source for the event to belong to (logically, it should be the same source you fetch your events from when receiving them from the database), then when the source is re-fetched (e.g. such as when the calendar date changes) it will clear the locally-added event from the calendar.
If you didn't define a specific event source when setting up the calendar, now would be a good time to modify your options slightly to support this - see https://fullcalendar.io/docs/v4/eventSources and https://fullcalendar.io/docs/v4/event-source-object
Example:
Event source is defined in the calendar configuration:
eventSources: [{
id: 1,
url: '/events'
}]
Event manually added to the calendar is associated with the event source:
calendar.addEvent(event, 1);
Related
I want to display data in a sencha comboboxfield, however the dataset has 15,000+ records and it is not feasible to load it all at one time. What I would like to do is have the sencha extreact comboboxfield:
Load remotely (restful api)
return a subset (25 records) that can be scrolled through (infinite scrolling - get next 25 and so on).
filter data based on data typed by the user. This would be a refresh of the data not filter what has already been fetched.
I've read through the documentation and sounds like I may need to use ExtJs store and proxy but for some reason it's not getting through my thick skull :). Any examples I have found appear to have the proxy setup that requires you access the api directly. I cannot do this because I'm working within a framework where that is not possible. All calls need to go through an async function due to authentication, logging and other purposed. If anyone has some pointers or examples to share that would be greatly appreciated.
I've had to make some tweaks to our system but I have this working and thought I would share. I have to give credit to this thread for pointing me in the right direction. Forgive me in advance for formatting issues.
First off, I couldn't figure out how to get the proxy to call a function so just went with the Ext.data.proxy.Ajax approach. A bit of a work around for me but it works. Here is my store and proxy setup (this is placed into component state):
postalCodes = (props) => {
let postalCodeStore = new Ext.data.Store ({
proxy: {
type: 'ajax',
url: postalCodesApiRoutes.DROPDOWNDATA, //stores my api route information
reader: {
type: 'json',
rootProperty: 'postalCode',
totalProperty: 'totalRecordCount'
},
pageParam: 'index',
extraParams: {
pageSize: props.pageSize
},
headers: { ...authHeader(), // returns my authentication header info
<OTHER LOGGING INFO WENT HERE>
},
noCache: false
},
autoLoad: false,
pageSize: props.pageSize,
clearOnPageLoad: false
})
return postalCodeStore;
}
The following is my ComboBoxField config (note: I had to use this.handlePickerCreate.bind(this) because the sencha controls don't appear to honor the arrow function binding):
<ComboBoxField
displayField="value"
valueField="postalCodeId"
queryMode="remote"
store={this.state.postalCodes}
remoteFilter={true}
clearable
allQuery=""
triggerAction="all" // I want when the dropdown clicked on it ignores whats in the combobox text and queries the entire data set. Otherwise if a user types a value a server-side filter will be executed.
queryParam="filter"
onPickerCreate={this.handlePickerCreate.bind(this)}
/>
The following is the handlePickerCreate and onScroll functions:
handlePickerCreate = (obj, picker) => {
picker.getScrollable().on('scroll', this.onScroll);
}
onScroll = (scroller, x, y, deltaX, deltaY, opts) => {
if (y >= scroller.getMaxPosition().y) {
let sStore = this.state.areas;
if (sStore.getTotalCount() != sStore.getCount()){
sStore.nextPage({
callback: function () {
scroller.doScrollTo(0, y);
console.log('store count', sStore.getCount())
}
});
this.setState({areas: sStore})
}
}
}
Anyway, there are still some quirks that I'm trying to figure out like when a value is selected from the list then you click on the trigger/dropdown arrow the picker displays and immediately disappears and the combobox input field clears out. I see a call being made to the server and data being returned but can't figure out what is happening. Well hope this helps someone.
i'm using fullcalendar in a web application i"m building.
i load my events with events function and ajax.
here is my code:
var ajaxData;
var eventsJsonArray;
var json_backgrundColor;
var json_iconstring;
//alert('Hello! 1!');
$(document).ready(function () {
$('#calendar').fullCalendar({
header: {
left: 'prev',
center: 'title',
right: 'next,month,agendaWeek,agendaDay'
},
//custom events function to be called every time the view changes
events: function (start, end, timezone, callback) {
var mStart = start.format('M')
var yStart = start.format('YYYY')
$.ajax({
url: '$getMonthDataUrl',
type: 'GET',
data: {
startDate: start.format(),
endDate: end.format()
},
error: function () {
alert('there was an error while fetching events!');
},
success: function (data) {
alert('nice!!');
ajaxData = data;
json_iconstring = ajaxData['iconString'];
json_backgrundColor = ajaxData['Calendar_cell_background_color'];
eventsJsonArray = ajaxData['all_Events_For_The_Month'];
callback(eventsJsonArray); //pass the event data to fullCalendar via the supplied callback function
}
});
},
fixedWeekCount: false,
showNonCurrentDates: false,
dayRender: function (date, cell, view) {
console.log(json_backgrundColor);//this brings eror because json_backgrundColor is undefined
var cellDate = date.format('D');
if (date.format('M') == view.start.format('M')) //cheacking is this day is part of the currrent month (and not prev/next month)
{
alert(cellDate);
cell.css('background-color', json_backgrundColor[cellDate]);//this brings eror because json_backgrundColor is undefined
}
},
})
});
when i load my events via ajax i'm also getting the information about which background color each cell should get. i can only get this info via the events ajax request.
the problem is that when the dayRender is running, i still don't have the background color data. (json_backgrundColor is undefined).
is there a way that dayRender will run after the events calendar will stop running? or any other code that will fix my problem.
many thanks!!
Your problem is that the "dayRender" callback runs after the view is changed (changing the date using prev/next counts as changing the view, for this purpose), but before the events for the new view have been downloaded and rendered. That's why your json_backgrundColor array is undefined.
Since you mentioned that the colour to be used depends on the exact nature of the events currently scheduled for that specific day, we need to find something that we can run after all the events, and this colour data, have been downloaded.
Inspecting the HTML, we can see that the table cells used to draw each day all have the CSS class "fc-day" applied. They also have a data-date property containing the day that they relate to. Finally, days that are disabled (outside the main month, due to you setting showNonCurrentDates:false) have an extra class of "fc-disabled-day" applied. We can use these pieces of information to identify the cells we want to change, without having to use the dayRender callback.
The eventAfterAllRender callback runs once when all the events have been rendered. Therefore this seems like a good place to alter the background colours of the cells:
eventAfterAllRender(function(view) {
//loop through each non-disabled day cell
$('.fc-day:not(.fc-disabled-day)').each(function(index, element) {
//set the background colour of the cell from the json_backgroundColor arrray, based on the day number taken from the cell's "data-date" attribute.
$(this).css('background-color', json_backgroundColor[moment($(this).data("date")).format("D")]);
});
}
Note that I have renamed json_backgrundColor to json_backgroundColor to correct the spelling error.
N.B. This is brittle in the sense that it relies on the class names that fullCalendar uses internally to represent the day cells. If fullCalendar decides to do this differently in a future release, it will break (whereas if we were able to use the fullCalendar API via the designated callbacks, they would likely maintain consistency despite internal changes, or at least document any change). But it's pretty key to the Month view, so realistically it's not likely to change any time soon - you would just have to remember to test it if you update your fullCalendar version.
if anyone still wondering you can use dateSet option like
datesSet: event => {
var from = moment(event.start).format('YYYY-MM-DD');
var to = moment(event.end).format('YYYY-MM-DD');
dateStatus = getEachDateStatus(from, to);
//{'2022-11-10' : 'fullbooked', '2022-11-09' : 'halfBooked'};
Object.keys(dateStatus).forEach(key => {
$('td[data-date="'+key+'"]').addClass(dateStatus[key]);
});
},
Instead of relying on dayRender, you should create background color events based on your ajax:
events = [
...
{ date: date
color: ...
rendering: 'background'
className: 'my-class'
}]
You can transform events using css any way you like, with or without the rendering: 'background' option.
I am using jQuery Select2 and I am running into an issue setting a value and triggering an event.
I have a simple select2 dropdown hooked up to an Ajax source. This works perfectly fine.
I also have an event waiting for a select2 option to be chosen:
// On project select, we add the projects to the list along with the parties
$('.projSearch').on("select2-selecting", function(e) {
// Set the value of the project
var projectID = e.val,
table = '';
alert(projectID);
console.log(e);
...
When using the select2 dropdown like normal, this event works fine. It detects the data of the option you select.
However, I am also including a button on the page that allows a user to set the data of the field. It sets the data just fine, however it never triggers the event select2-selecting.
I tried passing the data along with the event but not matter what when the select2-selecting event is fired, it returns undefined.
$(document).on("click", "[name=addProject]", function() {
// Set the vars
var projectName = $(this).attr('projectname'),
projectID = $(this).attr('projectid'),
projectNameLong = projectName + ' ('+projectID+')';
// Add the project to the list
$("[name=projects]").select2("data", [{id: projectID, text: projectNameLong}]).trigger("select2-selecting", {val: projectID, data: {id: projectID, text: projectNameLong}});
});
How can I pass data along with the trigger to I can access it within the event?
Thanks for any info!
Select2 normally triggers the select2-selecting event by creating a $.Event object with the custom data containing the val and data attributes that you are looking for. The second parameter of .trigger will allow you to get extra data directly from within the event handler, but it doesn't attach it to the event object.
$(document).on("click", "[name=addProject]", function() {
// Set the vars
var projectName = $(this).attr('projectname'),
projectID = $(this).attr('projectid'),
projectNameLong = projectName + ' ('+projectID+')';
// Create the data object
var data = {
id: projectID,
text: projectNameLong
};
// Create the custom event object
var evt = $.Event("select2-selecting", {
val: data.id,
data: data
});
// Add the project to the list
$("[name=projects]")
.select2("data", [data])
.trigger(evt);
});
This should replicate the original select2-selecting event for you and allow you to reuse your event handler.
I'm using FullCalendar 1.5.3 to display events from a json feed. I have 4 fields per event fed back - id, start, end and title. This works with each event block displaying the title.
In the FullCalendar examples the events with start and end dates show with a start time inserted before the title (formatted as 7p or 10:30a for example). How is this achieved? All my events have start and end times and I'm using the following settings...
$(document).ready(function(){
$('#claimCalendar').fullCalendar({
theme : true,
editable : false,
firstDay : 1,
aspectRatio : 4,
timeFormat: {
'' : 'H(:mm)t'
},
allDayDefault: false,
eventSources: [
{ //list of my eventSources
}
],
loading: function (bool) {
if (bool) $('#loading').show();
else $('loading').hide();
}
});
});
Any ideas on how to get the time to display? Eventually I would like the following information displayed for each event
start title end e.g. 00:00 title 07:30
I've sorted this out... Not sure why this has happened as I have used both allDayDefault:false in the fullCalendar params and allDay:false in my events but no time was displayed. I then modifed line 38 in FullCalendar.js 1.5.3 from allDayDefault:true to allDayDefault:false and hey presto I got my times showing.
I've also solved my second task and my events now display start - title - end.
I am using jquery and fullcalendar to schedule activities. When users select a timeslot, a form is shown on the right of the calendar where they can enter additional details.
With the 'select' callback I render a temporary event on the calendar so my users will have visual feedback while filling out the form.
However, when they have misselected a timeslot, they are able to select a new timeslot. This however renders a second (and possibly a third, fourth...) event on the calendar.
I thought I would be able to use the 'eventAfterRender(event, element)' callback to element.siblings().remove(), but this failed as eventAfterRender is called for every event on the calendar with every renderEvent.
Maybe there is a callback or method that I am missing, but as I see it, there is no easy way to remove an "unsaved" event.
Below is some sample code.
var fullCal = '';
$(function() {
fullCal = $('#fullcalendar').fullCalendar({
// options
select: SelectDate,
eventAfterRender: function(event, element) {
// this does not work as it simply just keeps the last event in the DOM.
element.siblings().remove()
},
viewDisplay: UnselectDate // hides and clears the form, intended behavior
});
});
function SelectDate(startDate, endDate, allDay, jsEvent, view) {
$('#BijlesForm').show();
var BijlesEvent = {start: startDate, end: endDate, title: 'Bijles', allDay: false};
fullCal.fullCalendar('renderEvent', BijlesEvent);
//fill the form
}
Okay, silly silly me. It must've been the fatigue or something, but I found how to do it on my own.
I removed the eventAfterRender callback and changed my SelectDate function to this:
function SelectDate(startDate, endDate, allDay, jsEvent, view) {
$('#BijlesForm').show();
fullCal.fullCalendar( 'removeEvents', 'unsaved' )
var BijlesEvent = {start: startDate, end: endDate, title: 'Bijles', allDay: false, id: 'unsaved'};
fullCal.fullCalendar('renderEvent', BijlesEvent);
}
This works like a charm. Is this also the preferred way of doing things, or should it be done differently?