How to save events in database with fullcalendar v4 - fullcalendar

Before, I'm used Ajax to save events and it was ok. But now, with the v4, my code doesn't work anymore like if Ajax doesn't recognise anymore. Does someone have the solution ?
My code in v3.09
eventDrop: function(event, delta, revertFunc) { // Déplacement d'une événement
var date = new Date();
if (($.fullCalendar.formatDate(event.start, "M")>=date.getMonth()+1 && $.fullCalendar.formatDate(event.start, "D")>=date.getDate()) || ($.fullCalendar.formatDate(event.start, "M")>date.getMonth()+1)) {
$.ajax({
url: 'php/update_events.php',
data: 'title='+ event.title+'&start='+ $.fullCalendar.formatDate(event.start, "YYYY-MM-DD HH:mm:ss") +'&end='+ $.fullCalendar.formatDate(event.end, "YYYY-MM-DD HH:mm:ss") +'&id='+ event.id ,
type: "POST",
success: function(json) {
$('#script-info').show();
setTimeout('divOff()',1000);
}
});
} else {
alert ("Vous ne pouvez pas déplacer une absence à une date antérieure à la date du jour.");
revertFunc();
}
},
My code in v4
eventDrop: function(info) {
var date = new Date();
if (calendar.formatDate(info.event.start, {month: 'numeric'})>=date.getMonth()+1 && calendar.formatDate(info.event.start, {day: 'numeric'})>=date.getDate()) {
$.ajax({
url: 'php/update_events.php',
data: 'title="Test"',
type: "POST",
success: function(json) {
$('#script-info').show();
setTimeout('divOff()',1000);
}
});
alert('Ok');
} else {
alert('Vous ne pouvez pas déplacer un créneau de sport à une date antérieure à la date du jour.');
info.revert();
}
}

You give me the solution !
I've removed script src='lib/jquery.min.js' script.
How stupid i am ! So, it's works again. Sorry for the inconvenient

Not sure if this helps others, but if you want to save events via ajax in V4 this is what I did assuming calEvent is coming from sort of event (click, drag etc) in V4:
eventClick: function (calEvent) { var cloned= jQuery.extend(true, {},calendar.getEventById( calEvent.event.id ));
cloned.start=clientEvents[i].start;
cloned.end=clientEvents[i].end;
cloned.title=clientEvents[i].title
delete cloned.jsEvent;
delete cloned.view;
Above shows how you can clone the event (needs jquery) and then add custom properties, remove some unneeded properties and ultimately turn this into JSON to send back to server.
HTH

Related

Fullcalendar V4: How to parse json received from ajax into event list

I'm trying to retrieve a list of events from an ajax call. I use the following code.
document.addEventListener("DOMContentLoaded", function()
{ var calendarEl = document.getElementById("id_d_agenda_1");
var calendar = new FullCalendar.Calendar(calendarEl, {
plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list' ],
header: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
},
defaultDate: '2019-08-12',
editable: true,
navLinks: true, // can click day/week names to navigate views
eventLimit: true, // allow "more" link when too many events
selectMirror: true,
select: function(arg) {
var title = prompt('Event Title:');
if (title) {
calendar.addEvent({
title: title,
start: arg.start,
end: arg.end,
allDay: arg.allDay
})
}
calendar.unselect()
},
events: function(arg) {
$.ajax({
url: 'd.php',
dataType: 'json',
data: {
cmd:'getdata',
start:arg.startStr,
end:arg.endStr,
tz:arg.timeZone,
component:'d_agenda_1',
},
success: function(doc) {
$(doc).each(function() {
calendar.addEvent( this );
})
}
})
}
})
calendar.render();
});
While debugging my javascript I can see the rows of events appear in 'doc'. First I tried to bulk add them to the agenda, but that didn't seem to work. Now I'm adding them one-by-one, buth they still don't appear. I have checked the this variable in the debugger and it shows a single event:
title:"value", start:"2019-08-01". In fact I'm using the sample list that comes with the package. Can someone point me to the right direction in what I'm doing wrong?
other options I tried (with no luck ;-):
I tried to leave the jquery out, but with similar effect:
success: function(doc) {
doc.forEach(function(value) {
calendar.addEvent( value );
})
}
success: function(doc) {
$(doc).each(function() {
calendar.addEvent({
title:this.title,
start:this.start
});
})
Not sure if it's helpful, but I added the selectable option and tested the select option. The calendar.addevent on the select: doesn't add the event either. Since this is copied from the sample i'm quite confused now. Fun part is that if you replace the ajax part with a regular [] expression that all works well. Even the selectable options, so there's definitely something wrong with my ajax implementation, in regards to this component.
According to the DOCS you need to have a successCallback that will return the events to the calendar.
Here is the docs https://fullcalendar.io/docs/events-function
Here is a simple Demo https://codepen.io/nasser-ali-karimi/pen/gOOJrWV?editors=0010
And in short, I can say that you need to set the events like this.
events: function(info, successCallback, failureCallback) {
successCallback([
{"resourceId":"a","title":"event 1","start":"2019-11-23","end":"2019-11-25"},
{"resourceId":"b","title":"event 3","start":"2019-11-24T12:00","end":"2019-11-25T06:00"},
{"resourceId":"b","title":"event 4","start":"2019-11-24T07:30","end":"2019-11-24T09:30"},
{"resourceId":"b","title":"event 5","start":"2019-11-24T10:00","end":"2019-11-24T15:00"},
{"resourceId":"a","title":"event 2","start":"2019-11-24T09:00","end":"2019-11-24T14:00"}
])
}
you didn't mention the events data that comes from Ajax request, so I can say you need to provide the data like what said on docs.
Addition
Note: Event's date are on 11/28 and 11,29 so navigate to those dates to see the events.
Demo https://codepen.io/nasser-ali-karimi/pen/qBBGVbG?editors=0010
events: function(info, successCallback, failureCallback) {
var arrevents = [];
jQuery.get( "https://api.myjson.com/bins/16ubhe", function( data ) {
// var response = JSON.parse(data);
// $.each(response, function(k, v) {
// arrevents.push(v);
// });
arrevents = data;
successCallback(arrevents);
});
},

Meteor when many subscriptions are ready

I'm creating a chat app. I hope i can add a new "hello" message if i check the messages count of current chat is equal to 0 (Problem #1). Also i have a dictionary as a collection for translation. But t() returns EN variant (Problem #2)
t = function(text) {
var res = Dictionary.findOne({o:text});
return res && res.t || text;
}
Meteor.startup(function () {
Deps.autorun(function () {
Meteor.subscribe('dictionary', Session.get('lang'), function(){
Session.set('dictionaryReady', true);
});
Meteor.subscribe('chats', Session.get('domain'), function(){
if (chatCurrent(Meteor.userId(), Session.get('domain')).count()===0 //true, even is not actually [problem_#1]
&& Session.get('dictionaryReady') //true, but next function t() doesn't work properly [problem #2]
) {
var mudata = Session.get('my_manager') ? udata(Session.get('my_manager'), Session.get('domain')) : null,
hello = mudata && mudata.hello || t('Hello! How I can help you?'),
name = mudata && mudata.name || t('Anna');
Meteor.call('create_message', {chat: Meteor.userId(), to: Meteor.userId(), text: hello, name: name, from: Session.get('my_manager'), domain: Session.get('domain'), last_manager: Session.get('my_manager')});
});
});
});
Problem #1 and Problem #2 everytime when page just loaded. So when i refresh the page i get another "hello message" on default EN locale.
Here is how you can render your template only once your subscriptions are ready. This is a solution taken from meteor kitchen generated code.
first you create a "loading" template
<template name="loading">
<div class="loading">
<i class="fa fa-circle-o-notch fa-4x fa-spin"></i>
</div>
</template>
Second, attach to your template a route controller. Here is a simplified version of it (but it should work):
this.myTemplateController = RouteController.extend({
template: "myTemplate",
onBeforeAction: function() {
this.next();
},
action: function() {
if(this.isReady()) { this.render(); } else { this.render("loading"); }
},
isReady: function() {
var subs = [
Meteor.subscribe("sub1", this.params.yourParam),
Meteor.subscribe("sub2", this.params.yourParam),
Meteor.subscribe("sub3", this.params.yourParam)
];
var ready = true;
_.each(subs, function(sub) {
if(!sub.ready())
ready = false;
});
return ready;
},
data: function() {
return {
params: this.params || {},
yourParamWhatever: Chat.findOne({_id:this.params.yourParam}, {})
};
},
});
Now you should have all your subscriptions ready when your template is loaded.
Concerning the translation, you could have a look at TAPi18n package that I highly recommend. It is quite easy to implement.

fullCalendar only display events on agendaView

I'm trying to get the fullCalendar JS application to display events only when on the agendaView view, not on the month view.
This is my current code. The problem is the events function is only called once, on the initial page load. According to documentation (and another site I have with fullCalendar) this function should call every time I change view, or date range. It does not.
$('#calendar').fullCalendar({
events: function ( start, end, timezone, callback ) {
var view = $('#calendar').fullCalendar('getView');
console.log(view.name);
if(view.name == 'agendaDay') {
$.ajax({
type: 'POST',
url: 'index.php?events=true',
data: {
start: start,
end: end
},
async: true,
success: function ( data ) {
callback(data);
}
});
}
},
dayClick: function ( date, jsEvent, view ) {
if(view.name == 'month' && jsEvent.currentTarget.className.indexOf('date-disabled') <= -1) {
$('#calendar').fullCalendar('changeView', 'agendaDay');
$('#calendar').fullCalendar('gotoDate', date);
} else if(view.name == 'agendaDay') {
var check = moment(date).format('YYYY-MM-DD');
var today = moment(new Date()).format('YYYY-MM-DD');
if(check > today) {
alert(date);
}
}
},
header: {
left: 'title',
center: '',
right: 'today month,agendaDay prev,next'
},
dayRender: function ( date, cell ) {
var check = moment(date).format('YYYY-MM-DD');
var today = moment(new Date()).format('YYYY-MM-DD');
if(check <= today) cell[0].className += ' date-disabled';
}
});
I know this for fact as the console.log only logs once, the word month. So it's only called when I refresh the page, first load it. Not when changing views which it should.
I was missing the lazyFetching option. This must be a new option in v2 as I was not expecting it.
http://arshaw.com/fullcalendar/docs/event_data/lazyFetching/
My code was correct. I simply needed to tell fullCalendar to get the events at EVERY change of the view and anything else that happened event wise.
lazyFetching: false,
This now works with my code.

Remote paging grid in extjs

You are my last chance :(. Im trying do work a paging grid with mvc pattern.
The grid show the fisrt 21 records, but not refresh when click "next" pagingtoolbar icon.
All my codes are detailed below:
The Store:
Ext.define('CRUDManantiales.store.grid.AbmUsuarios', {
extend: 'Ext.data.Store',
model: 'CRUDManantiales.model.grid.AbmUsuarios',
proxy: {
type: 'ajax',
url: 'resources/bundles/usuarios/generarJsonTodos.php',
reader: {
type: 'json',
root: 'data',
successProperty: 'success',
totalProperty: 'total'
}
}
});
The main view code:
Ext.define('CRUDManantiales.view.grid.AbmUsuarios', {
// [..........]
initComponent: function () {
this.store = 'grid.AbmUsuarios';
this.dockedItems = [{
xtype: 'pagingtoolbar',
store: this.store,
beforePageText: 'Página',
afterPageText: 'de {0}',
displayMsg: 'Mostrando {0} - {1} de {2} registros',
emptyMsg: 'No hay datos que mostrar',
dock: 'bottom',
displayInfo: true,
pageSize: 21
}];
this.callParent(arguments);
}
});
I wasted four days in this code, appreciate your assistance. Thanks !!
Thanks for all. The problem has been resolute. The fail was that i was using POST array in my PHP script and needed use GET method. :)

Disabling JSON reordering

I am creating some JSON data to be validated through an ajax call.
Here's my constructed JSON :
{"telephone1":"66",
"telephone2":"66",
"fax":"66",
"mobilePhone":"66",
"dateEffectiveChangementAdresseOuTel":"66",
"adresse1IdentiqueAdresse2":true}
Here's the one obtained :
{ "adresse1IdentiqueAdresse2" : true,
"dateEffectiveChangementAdresseOuTel" : "66",
"fax" : "66",
"mobilePhone" : "66",
"telephone1" : "66",
"telephone2" : "66"
}
As you can notice, my key are reordered in alphabetical order, which I do not want.
This causes errors to be returned to the page in the 2nd order, but I need them in the 1st order. I want my error summary (Html.ValidationSummary) to follow the errors on the page (1st error = 1st field in error).
Is there any way to preserve my original order?
Or someway to bypass this?
edit
var coord = {
telephone1: $("#Telephone1").val(),
telephone2: $("#Telephone2").val(),
fax: $("#Fax").val(),
mobilePhone: $("#MobilePhone").val(),
dateEffectiveChangementAdresseOuTel: $("#DateEffectiveChangementAdresseOuTel").val(),
adresse1IdentiqueAdresse2: $("#Adresse1IdentiqueAdresse2").is(":checked")
};
$.ajax({
type: 'POST',
url: urlControleur + '_ActionTransmettre',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: JSON.stringify(coord),
success: function (data, textStatus, jqXHR) {
if (typeof (data) == "string") {
window.location = data
MsgErreur("");
}
else {
ListeMsgErreur(data);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
handleAjaxError(XMLHttpRequest, "M000017");
}
});
ajax call return (in error)
["The value {0} is not valid for Effective.",
"Le numéro saisi doit respecter le format 999 999-9999",
"Le numéro saisi doit respecter le format 999 999-9999",
"Le numéro saisi doit respecter le format 999 999-9999 ou, si vous devez saisir un numéro de poste, le format est 999 999-9999 x 9999999.",
"Le numéro saisi doit respecter le format 999 999-9999"]
It's impossible to reorder the return as is.
I would review the code that returns the json. this is where it's happening. if you cannot change the code which renders the JSON then remodel the data before passing it along
return {
telephone1: theJson.telephone1,
telephone2: theJson.telephone2,
fax: theJson.fax,
mobilePhone: theJson.mobilePhone,
dateEffectiveChangementAdresseOuTel: theJson.dateEffectiveChangementAdresseOuTel,
adresse1IdentiqueAdresse2: thsJson.adresse1IdentiqueAdresse2
};

Resources