Creating an event with a multi-select calendar GUI

Stanislav,

First, thanks for all your help on these boards. You’ve answered many of my questions without even knowing it!

My calendar is in Matrix cell view, where the y-axis has 10+ schedules. I only work with all day events, none recurring. I want to be able to create a new event for someone and select ALL the days on which that event occurs.

For example:
“Mark is to work on reports on May 5, 6, 7, 12, 24, 30”

This would create 6 events in the DB with different start/end dates.

And for the date selector, I’d like to render a single UI calendar in the lightbox. The user can then select the multiple dates using something like this: multidatespickr.sourceforge.net/

How do I go about this? Thanks in advance!

There is no simple way, but it possible to do the next

a) create custom form section which will show input with linked multi-select calendar ( one from above links )
docs.dhtmlx.com/doku.php?id=dhtm … om_editors

b) add that custom section to lightbox
c) attach custom handler to onEventAdded and from it check value from new section, if it provides some dates, call scheduler.addEvent for each of them

Cool idea by the way, we will think about creating similar extension.

Thanks for the help!

I have created the custom form section with the mini-calendar. I can now add events by selecting multiple dates via the mini-calendar. However, I’m running into a small problem. When I press “Save” for the event, all the proper data is sent to the database as a separate event just like I need, but the lightbox freezes and will not go away. The script throws an error:

Uncaught TypeError: Cannot set property ‘test_date’ of undefined

Here is my ‘onEventSave’ code, where ‘test_date’ is my mini-cal field:

	[code]scheduler.attachEvent("onEventSave", function(event_id,event_object){
		
		//if using the mini-cal to enter dates and event id is there…
		if(event_id!='' && event_object['test_date'] != ''){                           
			
			var new_id;

			var miniCalDates = event_object['test_date'].split(','); //split up dates seperated by comma
			
			scheduler.deleteEvent(event_id); // delete single event id
				
			//for every date selected, make a new db entry
			for (var i = 0; i < miniCalDates.length; i++){
				
				new_id = scheduler.uid(); // get a new id for this entry
				
				start_date = new Date(Date.parse(miniCalDates[i] + " 00:00:00")); // create start date object from mini-cal text
				end_date = new Date(); // create end date object
				end_date.setDate(start_date.getDate()+1); // 
				end_date.setHours(0,0,0,0);
				
				scheduler.addEvent({
					id: new_id, //added
					start_date: start_date,
					end_date: end_date,
					text: event_object.text,
					client_code: event_object.client_code,
					work_type: event_object.work_type,
					task_type: event_object.task_type,
					hours: event_object.hours,
					vacation: event_object.vacation,
					work_start: event_object.work_start,
					booked: event_object.booked,
					rpeep_id: event_object.rpeep_id,
					test_date: event_object.test_date                       
				});
			  	if (new_id!=event_id){ //added
					dp.setUpdated(new_id, true, "inserted"); //added
				}
			}
			return true;
		}
		else return true;
    });[/code]

What is throwing this error?

Thanks for any help!
Ryan

You can ignore the above code. I’ve revised it to the below, and all events are getting put in as they should.

Here is the working code:

[code]scheduler.attachEvent(“onEventAdded”, function(event_id,event_object){

		//if using the mini-cal to enter dates and event id is there…
		if(!event_object['event_group_id']){                           

			var miniCalDates = event_object['test_date'].split(','); //split up dates seperated by comma			
			var group_id = event_id;
            
			for (var i = 0; i < miniCalDates.length; i++){

				start_date = parseDate(miniCalDates[i]);
				end_date = new Date(start_date); // create end date object
				end_date.setDate(end_date.getDate()+1); // 
				//throw new Error(start_date);
				
				scheduler.addEvent({
					id: event_id,
					start_date: start_date,
					end_date: end_date,
					text: event_object.text,
					test_date: event_object.test_date,
					client_code: event_object.client_code,
					work_type: event_object.work_type,
					task_type: event_object.task_type,
					hours: event_object.hours,
					vacation: event_object.vacation,
					work_start: event_object.work_start,
					booked: event_object.booked,
					rpeep_id: event_object.rpeep_id,
					event_group_id: group_id
			                   
				});
				
				event_id = scheduler.uid();
			}
		}
		else return true;
    });[/code]

However, if I try to click on an event after I’ve added it, I get an error instead of the Lightbox.
this.getEvent(F) is undefined

This only happens with the first event in a series. All other events will correctly launch a Lightbox with event info. I should also note that once I refresh the browser, the first event(s) all launch their Lightbox correctly.

Any help would be great, Stanislav! Thanks.

Such error can occur if you have different event ID in the html view, and in the inner model

There are two possible culprit

a) the server side code - be sure that it returns valid response with correct sid and tid values
b) you are calling addEvent from the onEventAdded handler, but in this moment the event already was added. If you adding some extra event - you need to have different event_id for it, not the same as id of already existing event.

A) What is the best way to check for that?

B) I changed the code so it wouldn’t use the event_id that triggered OnEventAdded, but instead create all new event_id’s using scheduler.uid(). I then would call deleteEvent(event_id) on the original event_id. However, this would throw an error too: Uncaught TypeError: Cannot read property ‘!nativeeditor_status’ of undefined

Ryan

a) If you are using connector - the server side most probably works fine, but you can use firebug or dev-tools to check the actual response

b) here is the case

  • new event created
  • dataprocessor send data to server side, to save new event
  • onEventAdded called
  • your custom logic called
  • event deleted
  • saving callback caome from server side, it returns info about saving of record which already deleted and tries to modify it, which can cause the problems.

You can try

a) move delete call in delayed call

scheduler.attachEvent("onEventAdded", function(event_id,event_object){ setTimeout(function(){ scheduler.deleteEvent(event_id); },1); //timeout value doesn't matter });

with such code, event will be deleted only when event adding is fully done ( but still before callback from server side ) which must resolve issue.

b) if issue still occurs - you can move the event deleting to callback of dataprocessor - onAfterUpdate event of dp, which will be called after receiving callback from the server side

Thanks a ton. Got it working.

One other question. If I edit an event, I want all events related to that event to be updated.

For example, I create an event that spans 5 days, thus creating 5 new events in the database. (That works great!) They are linked with a group_id. Now, If I edit a few of the custom fields in 1 of those 5 events, how can I force those edits to all related events (having same group_id) upon save?

I assume I’d use “OnEventChanged” and I’d need to have all the related event objects, which I’ve done. Now I need to loop through the event objects and update each one, but I don’t see an API call that allows me to edit custom fields of a record. I see setText, and setStartDate, etc… but nothing else. Am I missing something? How can I edit/update a custom field via the API?

but I don't see an API call that allows me to edit custom fields of a record. I see setText, and setStartDate, etc.. but nothing else. Am I missing something? How can I edit/update a custom field via the API?

You can edit any field by

scheduler.getEvent(id).field_name = new_value; dp.setUpdated(id, true);

second line is necessary to trigger data saving after property was changed.

Alternative solution will be to update data in DB ( single custom sql call from onAfterUpdate server side event ) and reload data on client side.