Collsion with other criteria

Hi,

i have three tables (user, event_user and event_shared). User = user_id, firstname, lastname and other. Event_user = event_user_id, event_id, user_id and event_shared = event_id, start_date usw…

if I make an appointment with 1-4 users I need a test for the next event whether the user is still free for that period. Is that possible? With the only events in the same time are blocked (no criterias).

Thank you for your help.

Hello,

Didn’t get that part. So is there another event in the same time frame? If so onEventCollision event will be called and there you can check if actual users’ schedule collide or not.

Kind regards,
Ilya

Hi,

thanks for the quick response.

I have multiple checkboxes with userId’s. For every event i can choose any number of employees. If I have a new event it should be checked whether the selected employees are not already registered for other dates (Table: event_share -> event_user_id|event_id|user_id) in the same period.

I found the following function “scheduler.attachEvent(“onEventSave”,function(id,data){”. With data.user_id i get the current user_id('s) and I wanted to compare all other user_id with every time period. how can I get all the user_id from any other event?

I have not found a solution with onEventCollision staff and periods to proof.

Sorry, for my bad english.

…a small example would be helpful :wink:! For example:

scheduler.attachEvent(“onEventCollision”, function (ev, evs){

var user = data.user_id;
    var start = data.start_date;
    //...

     var evs = scheduler.getEvents(new Date(1990,1,1),new Date(2020,1,1));
     for (var i=0; i<evs.length; i++)
     {
      //Here  then a pure test
     // if (user = evs[i].user_id) AND (evs[i].start_date >= start)....
      alert(evs[i].user_id); //isn't possible
      alert(evs[i].start_date); //is possible
     }
    //...
})

regards

Hello,

In your case event collision won’t help you. You simply need to perform necessary check in the onEventSave event.
Logic should be following:

  • onEventSave
  • get each user for the current event
  • get all events(?) and check if users from the current event are subscribed to any other event

If so - block save process, display message. If not - return true; save event.

How do you store that information in event?
It probably could be event.users=“1,56,74” where 1, 56, 74 - users’ id.
Same way you can get that information for other events (which you receive from getEvents() function).

Kind regards,
Ilya

Hi,

In your case event collision won’t help you. You simply need to perform necessary check in the onEventSave event.

-> ok, I think so too

  • onEventSave

-> ok

  • get each user for the current event

-> that’s the Problem! I do not know how I can verify all user with the current event entry

  • get all events(?) and check if users from the current event are subscribed to any other event

-> like this:

scheduler.attachEvent("onEventSave",function(id,data){

	var user = data.user_id;
	var start = data.start_date;
	var end = data.end_date;
	
     var evs = scheduler.getEvents(new Date(1990,1,1),new Date(2020,1,1));
     for (var i=0; i<evs.length; i++)
     {
      //alert(evs[i].user_id); doesn't work
     }
  • If so - block save process, display message. If not - return true; save event.

-> that is clear :slight_smile:
return true;
})

i have multiple checkboxs:

{name:“userselect”, height:22, map_to:“user_id”, type:“multiselect”, options: scheduler.serverList(“user_id”), script_url: ‘events_multiselect_options.php’, vertical:“false”},

the php script:

require_once ('codebase/connector/scheduler_connector.php');
require_once('codebase/connector/crosslink_connector.php');
require_once ('samples/common/config.php');

$res=mysql_connect($server, $user, $pass);
mysql_select_db($db_name);

$cross = new CrossOptionsConnector($res);
$cross->dynamic_loading(true);
$cross->options->render_table("user","user_id","user_id(value),kuerzel(label)");
$cross->link->render_table("event_user","event_id", "user_id,event_id");	

$scheduler = new SchedulerConnector($res);

$scheduler->set_options("user_id", $cross->options);

$scheduler->render_table(“events_shared”,“event_id”,“start_date,end_date,text,user,anzahluser,details,reccuring,customer,event_type,userId”);

That only works half…i just do not get all the user_id’s - only from the new created schedule.

Thank you for your help!!!

Hello,

Please check
scheduler\samples\03_extensions\22_multiselect_initial_loading.html sample.
Points of interest:

  • static loading of all options. So all your events already have the user list in them. It’s done in php/events_multiselect_static.php file (basically by not using dynamic_loading = true).
  • template there shows how you can get user id

So in onEventSave event you can get user_id the same way, get events and then check your custom logic.

Kind regards,
Ilya

  • Thank you for the example…i will look at the code now
  • If I have more questions, I’ll get back to you.

Thank you again.

Kind regards,

shufro

Hello,

your informations are very helpful, but one thing is not working: comparison of the time span.

The dates will be issued as follows f.e. “Thu Nov 17 2011 08:00:00 GMT+0100” but I need the same format as in this contribution: viewtopic.php?f=14&t=10877 otherwise I can not compare the two time periods. The function “doesn’t” work.

kind regards,

shufro

Scheduler stores all dates as objects, so instead of comparing as a string, you can use

ev.start_date.getMonth();

or any other date object API

Thank you.

kind regards

Hi,

first of all…many man thanks for your help.

My solution is not really elegant, but it works (partially). I have the following code:

	scheduler.attachEvent("onEventSave",function(id,data,is_new_event){

		if (!data.user_id) {
			alert("Bitte wählen Sie mindestens einen Mitarbeiter aus!");
			return false;
		}		
		

		var user = data.user_id.split(",");
		var start = data.start_date;
		var end = data.end_date;
		

        var sd=scheduler.getEvent(id).start_date;
        var ed=scheduler.getEvent(id).end_date;
        var convert = scheduler.date.date_to_str("%H%i|%d%m%Y");
        sd2 = convert( sd ); 
        ed2 = convert( ed ); 
		var msg = "a";
	
		var testsplit1 = sd2.split("|"); //Startzeit testsplit1[0] = Zeit, testsplit1[1] ) datum
		var testsplit2 = ed2.split("|"); //Endzeit   testsplit2[0] = Zeit, testsplit2[1] ) datum	


		scheduler.templates.event_text = function(start, end, event, user_id) {

			var users=[];
			if (event.user_id){
				users = event.user_id.split(",");
	
			  for (var e=0; e < user.length; e++)
              {			 

				for (var i=0; i < users.length; i++)
				{


					if (user[e] == users[i])
					{

			        var akt1 = convert(event.start_date);
			        var akt2 = convert(event.end_date);		

			        var akt_split1 = akt1.split("|");
			        var akt_split2 = akt2.split("|");

					if (akt_split1[1] == testsplit1[1])
					{
					 if (testsplit1[0] > akt_split1[0] && testsplit1[0] < akt_split2[0])
					 {	
                      msg = "Achtung! Der Mitarbeiter " + user[e] + " ist bereits für ein anderes Event eingetragen! Zeitraum: " + event.start_date + "-" + event.end_date;
					 }
					 if (testsplit2[0] > akt_split1[0] && testsplit2[0] < akt_split2[0])
					 {
					  msg = "Achtung! Der Mitarbeiter " + user[e] + " ist bereits für ein anderes Event eingetragen! Zeitraum: " + event.start_date + "-" + event.end_date;
					 }
					 //Startzeit davor Endzeit dazwischen
					 if (testsplit1[0] < akt_split1[0] && testsplit2[0] > akt_split2[0])
					 {
					  msg = "Achtung! Der Mitarbeiter " + user[e] + " ist bereits für ein anderes Event eingetragen! Zeitraum: " + event.start_date + "-" + event.end_date;
					 }	
					 if (testsplit1[0] < akt_split1[0] && testsplit2[0] > akt_split2[0])
					 {
					  msg = "Achtung! Der Mitarbeiter " + user[e] + " ist bereits für ein anderes Event eingetragen! Zeitraum: " + event.start_date + "-" + event.end_date;	
					 }
					} 
					 
					}
				}
			 }				 
		   }	

		   

		  if (msg != "a")
          {  		  
		   alert(msg);
		   
		  scheduler.templates.event_text = function(start, end, event) {
			var result = event.text+"<br/>Users: ";
			
			var users2=[];
			if (event.user_id){
				users2 = event.user_id.split(",");
				for (var z=0; z < users2.length; z++)
					users2[z] = scheduler.getLabel("user_id",users2[z])
			}
			result += users2.join(",");
			
			return result;
		  }
		 }
		 else
		 {
		  scheduler.templates.event_text = function(start, end, event) {
			var result = event.text+"<br/>Users: ";
			
			var users2=[];
			if (event.user_id){
				users2 = event.user_id.split(",");
				for (var z=0; z < users2.length; z++)
					users2[z] = scheduler.getLabel("user_id",users2[z])
			}
			result += users2.join(",");
			
			return result;
		  }
		 }
	}

	// #######################
	// I need the "new" value of msg, but i didn't get him from scheduler.templates.event_text
	// #######################
     if (msg != "a")
     {
	  return false;
     }
     else
     {	
	  return true;	
	 }	
	})	

…look at the comment. I can validate different time periods, but i can’t stop the saving process of the scheduler (return false). Next Problem: this solution works in 80% of cases, but unfortunately not always.

Thank you for help.

regards,

shufro

in onEventSave handler you are defining logic of template, which will be called not now, but when this item (and others items) will be rendered, so it is expected that in onEventSave handler you will not have msg which is defined in the template.

Correct solution would be to not redefine template, but use the date checking logic directly in onEventSave handler.

Ok, that sounds reasonable - you mean all items? I’ve adjusted my code and now it seems to work. The only problem is, if I make a new entry, I can not save!
If I modify an entry, then the validation works great. Apparently the second Loop is the problem (it looks better?):

	scheduler.attachEvent("onEventSave",function(id,data,is_new_event){

		if (!data.user_id) {
			alert("Bitte wählen Sie mindestens einen Mitarbeiter aus!");
			return false;
		}		

		var user = data.user_id.split(",");
		var start = data.start_date;
		var end = data.end_date;		

        var sd=scheduler.getEvent(id).start_date;
        var ed=scheduler.getEvent(id).end_date;
        var convert = scheduler.date.date_to_str("%H%i|%d%m%Y");
		
        sd2 = convert( sd ); 
        ed2 = convert( ed ); 	
	
		var testsplit1 = sd2.split("|"); //Startzeit testsplit1[0] = Zeit, testsplit1[1] ) datum
		var testsplit2 = ed2.split("|"); //Endzeit   testsplit2[0] = Zeit, testsplit2[1] ) datum	
	

       var datum_past = scheduler.date.add(new Date(), -5, "day"); 
       var evs2 = scheduler.getEvents(datum_past, new Date(9999,1,1));	
	   var users=[];
	   var datestart_a=[];
	   var dateend_a=[];
       var event_laenge = evs2.length;

          for (var f=0; f<user.length; f++)
		  {		  

			  for (var e=0; e < event_laenge; e++)
              {			

		       users=evs2[e].user_id.split(",");
	           datestart_a = evs2[e].start_date;	 
	           dateend_a = evs2[e].end_date;

				for (var i=0; i < users.length; i++)
				{

					if (user[e] == users[i])
					{

			        var akt1 = convert(datestart_a);
			        var akt2 = convert(dateend_a);		

			        var akt_split1 = akt1.split("|");
			        var akt_split2 = akt2.split("|");

					if (akt_split1[1] == testsplit1[1])
					{
					
					 if (testsplit1[0] >= akt_split1[0] && testsplit1[0] <= akt_split2[0])
					 {	
                      alert("Achtung! Der Mitarbeiter " + user[e] + " ist bereits für ein anderes Event eingetragen! Zeitraum: " + datestart_a[i] + "-" + dateend_a[i]);
					  return false;
					 }
					 if (testsplit2[0] >= akt_split1[0] && testsplit2[0] < akt_split2[0])
					 {
					  alert("Achtung! Der Mitarbeiter " + user[e] + " ist bereits für ein anderes Event eingetragen! Zeitraum: " + datestart_a[i] + "-" + dateend_a[i]);
					  return false;
					 }
					 if (testsplit1[0] <= akt_split1[0] && testsplit2[0] >= akt_split2[0])
					 {
					  alert("Achtung! Der Mitarbeiter " + user[e] + " ist bereits für ein anderes Event eingetragen! Zeitraum: " + datestart_a[i] + "-" + dateend_a[i]);
					  return false;
					 }	
					 if (testsplit1[0] < akt_split1[0] && testsplit2[0] > akt_split1[0])
					 {
					  alert("Achtung! Der Mitarbeiter " + user[e] + " ist bereits für ein anderes Event eingetragen! Zeitraum: " + datestart_a[i] + "-" + dateend_a[i]);	
					  return false;
					 }
					} 
					 
					}
				}
			 }

		   }	
		   return true;
	})

kind regards,

shufro

shufro,

did you solved the problem? I´ve got the exact same problem… your code works partically but on save a new event a Typedef error occur.

TypeError: 'undefined' is not an object (evaluating 'evs2[e].user_id.split')

the debugger jumps to dhtmlxscheduler.js
line 918

 var zr = dhx_catch[i].apply(obj, arguments);

later to 906

return this[name].apply(this, arg0);

and then to line 4987

if (this.checkEvent("onEventSave") && !this.callEvent("onEventSave",[this._lightbox_id, data, this._new_event]))

finally to line 5029 and breaks;

scheduler.save_lightbox();

onEventSave is called during new event creation, and if in this moment the user_id value of event is not set - it will cause an error. You need modify the above code and check first is user_id set or not, or add some code to set the default user_id value for newly created events.

Ok i found a solution to fix this error.

I always delete the last element of all events. The last element seams to be the newly created element.

var event_laenge = evs2.length-1;

Is there a better solution?

Current code for collision check:

scheduler.attachEvent("onEventSave", function (id, data) {
"use strict";
		if (!data.user_id) {
			dhtmlx.alert("Bitte wählen Sie mindestens einen Mitarbeiter aus!");
			return false;
		}

	var user = data.user_id.split(",");     
	var sd=scheduler.getEvent(id).start_date;
	var ed=scheduler.getEvent(id).end_date;
	var datum_zeit_convert = scheduler.date.date_to_str("%H%i|%d%m%Y");
	var datum_convert = scheduler.date.date_to_str("%d.%m.%y");
	var zeit_convert = scheduler.date.date_to_str("%H:%i");
	var sd2 = datum_zeit_convert(sd); 
	var ed2 = datum_zeit_convert(ed);    

	var new_event_start = sd2.split("|"); //Startzeit new_event_start[0] = Zeit, new_event_start[1] ) datum
	var new_event_end = ed2.split("|"); //Endzeit   new_event_end[0] = Zeit, new_event_end[1] ) datum   

	var datum_past = scheduler.date.add(new Date(), -5, "day"); 
	var evs2 = scheduler.getEvents(datum_past, new Date(9999,1,1));   
	var users=[];
	var name_event=[];
	var date_start_current_events=[];
	var date_end_current_events=[];
	var event_laenge = evs2.length-1;
	var user_laenge = user.length;

			for (var f=0; f < user_laenge; f++){
				for (var e=0; e < event_laenge; e++){
					users=evs2[e].user_id.split(",");
					name_event = evs2[e].text;
					date_start_current_events = evs2[e].start_date;
					date_end_current_events = evs2[e].end_date;
						for (var i=0; i < users.length; i++){
							if (user[f] === users[i]) {
						
								var current_event_start = datum_zeit_convert(date_start_current_events);
								var current_event_end = datum_zeit_convert(date_end_current_events);

								var current_event_start_split = current_event_start.split("|");
								var current_event_end_split = current_event_end.split("|"); //


				if (current_event_start_split[1] === new_event_start[1] && new_event_start[0] < current_event_end_split[0]) // gleiches Startdatum
					{
						dhtmlx.alert("<b>Achtung!</b> Der Mitarbeiter <span style=\"color:red;\">" + scheduler.getLabel("user_id",user[f]) + "</span> ist bereits für ein andere Baustelle (" + name_event + ") eingetragen! Zeitraum: " 
						+ datum_convert(date_start_current_events) +" (" +  zeit_convert(date_start_current_events) + " Uhr) - " + datum_convert(date_end_current_events) + " (" + zeit_convert(date_end_current_events)+" Uhr)");
						return false;
					} 
				if (new_event_start[1] >= current_event_start_split[1] && new_event_end[1] <= current_event_end_split[1])
					{
						dhtmlx.alert("<b>Achtung!</b> Der Mitarbeiter <span style=\"color:red;\">" + scheduler.getLabel("user_id",user[f]) + "</span> ist bereits für eine andere Baustelle  (" + name_event + ") eingetragen! Zeitraum: " 
						+  datum_convert(date_start_current_events) +" (" +  zeit_convert(date_start_current_events) + " Uhr) - " + datum_convert(date_end_current_events) + " (" + zeit_convert(date_end_current_events) +" Uhr)");
						return false;
					}
				}
			}
		}
	}   
return true;
});

The code is also triggered if an old event is edited and saved.
Example:

  • Old Event User ID: 10, 15, 20 selected;
  • Edit;
  • Save;
  • Code compares with other events - found nothing - compares with it self and Alert current selected users (10,15,20).

Is there a way to prevent this procedure?

If you want to prevent onEventSave logic for old events - you can add as first line of it

if (!scheduler.getState().new_event) return;

Also, you can prevent check against self in your logic by changing code like next

for (var e=0; e < event_laenge; e++){ if (evs2[e].id == id) continue; //ignore the same event