The attached code will convert recurring events created or updated by the user to separate independant events in the database. However, I have two problems:
-
If I don’t put an alert statement and an if statement around the actual scheduler.addEvent() statement, the number of events that are added to the DB are doubled (created twice). As long as I call an alert statement and I enclose the addEvent statement in an ‘if’ statement, the correct number of events are created in the DB. How can I make the code work without the alert and if statements?
-
There seems to be a bug in the recurring event code. If the user selects both ‘Every workday’ and ‘After xx occurences’ at the same time in the recurring event dialog in the lightbox, an extra event is created every time. You will see in my code my workaround. Is this a bug in your code?
Thanks!
function doRecurringEvents(id, ev){
type = ev.rec_type;
event_length = ev.event_length;
client_id = ev.client_id;
eventText = ev.text;
repeatArray = scheduler.getRecDates(ev.id);
length = repeatArray.length;
sp = type.split("#");
day = sp[0].split("_");
if (sp[1] && day[0] == 'week') length--; // this is to fix 'workday' and 'After 'x' occurrences' selection combonation problem
// two events get created unless I call alert: ???
// it appears I must call alert & use the if statement??
//alert("Recurring Events. type="+type+", ev="+JSON.stringify(ev));
//alert("Recurring Events. type="+type+", repeatArray="+JSON.stringify(repeatArray));
alert("Recurring Events. type="+type+", id="+id);
if (type != '' && type != null){
//alert("Recurring Events. id="+id+", type="+type+", event_length="+event_length+", ev="+JSON.stringify(ev));
for (i = 0; i < length; i++){
start_date = repeatArray[i]['start_date'];
end_date = repeatArray[i]['end_date'];
scheduler.addEvent({
start_date: start_date,
end_date: end_date,
text:eventText,
event_pid:'0',
rec_type:'',
event_length:'0',
client_id: client_id
});
};
scheduler.deleteEvent(id); // finally, delete the originally created recurring event
};
return true;
};
scheduler.attachEvent("onEventChanged", function(id,ev){
// called after the event has already been changed
type = ev.rec_type;
//alert("Event Changed. id="+id+",type="+type+", ev="+JSON.stringify(ev));
if (type != '' && type != null){
doRecurringEvents(id,ev);
}
return true;
});
scheduler.attachEvent("onEventIdChange", function (old_id,new_id){
// fires after new event has been saved after making changes in the light box
id = new_id.split("#");
event_length = id[1];
id = id[0];
ev = scheduler.getEvent(id);
type = ev.rec_type;
if (type != '' && type != null){
//alert("Event Id Change. old_id="+old_id+", new_id="+new_id+", id="+id[i]+", type="+type+", event_length="+event_length+", e="+JSON.stringify(ev));
doRecurringEvents(id,ev,new_id);
}
return true;
});
I guess I said something wrong… I’ve tried everything to get this to work. My only other option is to disable recurring events…which really limits the functionality of my app. Or, roll my own, which defeats the whole purpose.
Hello,
the recurring extension triggers changeEventId for the displayed instances, so your onEventIdChanged handler is triggered multiple times.
Also note that when you add events in a loop, it creates a huge amount of ajax requests to your server. Try disabling auto sending changes to the server before the loop and then send them all at once
docs.dhtmlx.com/api__dataprocess … emode.html
docs.dhtmlx.com/api__dataprocessor_senddata.html
Also, note that user can create infinite recurring series (without end date), you can’t save such series as array of single events.
Regarding incurrect number of recurrings - thanks for the info, we’ve confirmed the problem.
Hi Aliaksandr,
BTW, If the user does not set ‘end_date’ your software limits the number of recurring events to 100, so your statement that an infinite number of events is created is not correct.
Also, I have looked at your links and have tried to implement them. Still does not fix the issue.
I have my code working perfectly, AS LONG AS I PUT IN A VERY ANNOYING alert statement after the sendData() call.
It is hard to believe that no one has brought up this issue before! (converting a recurring event into multiple single events). Has anyone been able to look into this issue?
This issue is the only thing holding me back from purchasing your Enterprise License. Seems like it would be worth your while to look into this.
THANK YOU in advance!
Hi,
that is not exactly correct. If you create endless series from the UI, it won’t be limited to 100 instances but will span till the end of times (more precisely, the end date of the series will set to year 9999 which should be sufficient. So if you create such series and scroll calendar several years ahead - it’s still be there).
For that reason scheduler.getRecDates requires setting a limit for number of entities it calculates. If you do not specify this number it will take 100 items by default. If you’d call scheduler.getRecDates(eventId, 10000) for the series with no end date - you’d get 10k instances. So this is mostly the question how do you choose to interpret the endless series in your app.
Regarding the code, probably something following should do:
[code]// initialize dataprocessor
var dp = new dataProcessor(“data/events_rec.php”);
dp.init(scheduler);
// the solution
function copyEvent(master){
var copy = {};
var skip = {
“_”:true,
“$”:true};
var ignore = {
“rec_type”: true,
“rec_pattern”: true,
“event_length”: true,
“event_pid”: true
};
for(var i in master){
if(skip[i.charAt(0)]){
continue;
} else if(ignore[i]){
copy[i] = "";
}else{
copy[i] = master[i];
}
}
return copy;
}
function splitRecurrings(recurringId, dataProcessor){
dataProcessor.setUpdateMode(“off”);
var masterEvent = scheduler.getEvent(recurringId);
var evDates = scheduler.getRecDates(recurringId, 100);
dataProcessor.setUpdated(recurringId, false)
scheduler.deleteEvent(recurringId, true);
evDates.forEach(function(date){
var current = copyEvent(masterEvent);
current.id = scheduler.uid();
current.start_date = date.start_date;
current.end_date = date.end_date;
scheduler.addEvent(current);
});
dataProcessor.setUpdateMode("cell");
dataProcessor.setTransactionMode("POST", true);//send all events at once
dataProcessor.sendData();
}
dp.attachEvent(“onBeforeUpdate”, function(id, state, data){
if(data.rec_type && state !=“deleted”){
setTimeout(function(){
splitRecurrings(id, dp);
}, 1);
return false;
}
return true;
});[/code]
You are the man (I’m assuming)!!! THANK YOU again!!!