Linking multiple events so changes in one event update the others (Scheduler v7)

Hi,

I’m using DHTMLX Scheduler v7 and I’m trying to implement a feature where multiple events can be logically linked together.

Use case

I have multiple events that may:

  • belong to the same or different section_id
  • be scheduled on different dates
  • but represent the same logical job/task

Because of this, I want these events to be linked via a common property (for example group_id or job_id ).

Example:

Event A
{
  id: 1,
  text: "Task A",
  start_date: "...",
  end_date: "...",
  section_id: 1,
  group_id: "job_101"
}

Event B
{
  id: 2,
  text: "Task B",
  start_date: "...",
  end_date: "...",
  section_id: 5,
  group_id: "job_101"
}

Expected behavior

If a user modifies one event (drag, resize, or date change), I want the same change to be applied to all events that share the same group_id .

For example:

If Event A is moved +1 day , then Event B should also move +1 day .

Similarly:

  • resizing should update durations accordingly
  • section change should optionally reflect in linked events as well

Question

Is there any built-in feature in DHTMLX Scheduler v7 that supports this type of linked or grouped events synchronization ?

Or is the recommended approach to implement this manually using event handlers like:

  • onEventChanged
  • onEventAdded
  • onBeforeEventChanged

If anyone has implemented something similar, I’d appreciate guidance or best practices.

Thanks!

Hello @krjani,

I received your request in our support system, and will repeat answer here in case if somebody will look for the same.

Regarding this point:

I have multiple events that may:
belong to the same or different section_id
be scheduled on different dates
but represent the same logical job/task

There is no built-in option for that, as scheduler’s multisection events are rendered on the same date - so they are more like “single event splitted to different sections”.

Or is the recommended approach to implement this manually using event handlers like:
onEventChanged
onEventAdded
onBeforeEventChanged

Yes, the best solution for your case, will be to manually listen changes of connected events.

Here is an example of possible solution:
https://snippet.dhtmlx.com/d8ck7uzx

Main points of solution:

  1. Link events by group_id
    Dragged event finds all related events by same group_id (excluding itself).
function getLinkedIds(sourceId) {
	const source = scheduler.getEvent(sourceId);
	if (!hasGroup(source)) {
		return [];
	}
	return scheduler.getEvents()
		.filter(function(ev) {
			return ev.id != sourceId && ev.group_id === source.group_id;
		})
		.map(function(ev) {
			return ev.id;
		});
}
  1. Store initial state before drag
scheduler.attachEvent("onBeforeDrag", function(id, mode) {
	if (!isSyncDragMode(mode)) {
		dragContext = null;
		return true;
	}

	const main = scheduler.getEvent(id);
	const linkedIds = getLinkedIds(id);

	dragContext = {
		mainId: id,
		mainInitial: saveEventState(main),
		linkedIds: linkedIds,
		linkedInitial: saveInitialState(linkedIds)
	};

	return true;
});
  1. Apply time + section sync to linked events
function syncLinkedEvents(context, mode, mainEvent) {
	const startShift = mainEvent.start_date.valueOf() - context.mainInitial.start_date.valueOf();
	const endShift = mainEvent.end_date.valueOf() - context.mainInitial.end_date.valueOf();
	const sectionShift = getSectionShift(context.mainInitial.section_id, mainEvent.section_id);

	context.linkedIds.forEach(function(linkedId) {
		const linked = scheduler.getEvent(linkedId);
		const initial = context.linkedInitial[linkedId];

		linked.start_date = new Date(initial.start_date.valueOf() + startShift);
		linked.end_date = new Date(initial.end_date.valueOf() + endShift);

		if (mode === "move" && sectionShift !== 0) {
			linked.section_id = getShiftedSectionId(initial.section_id, sectionShift);
		}

		scheduler.updateEvent(linkedId);
	});
}

Kind regards,