My use case is :- If we drag and drop task from grid to a technician who already has a task assigned to him at the same time then it should not allow and should throw the error.
Now to achieve this I set allowOverlap to false in event but still it is not throwing error and allowing to drop the task on the same time in which a task assigned to technician.
I have attached the screenshot and sample application.
Please let me know what need to modify in code.
Support Forum
- Attachments
-
- Overlapping_Task.zip
- (2.98 MiB) Downloaded 72 times
-
- Screenshot 2021-07-21 at 2.19.17 PM.png (341.44 KiB) Viewed 822 times
I haven't found any place in your code where you set allowOverlap:false
. Setting it from the console leads to the behavior shown in the video. As you can see there's no error thrown but the drag is cancelled if it would lead to an overlap. If you need an error (popup) you would need to do it in the application.
@saki thanks for quick reply, It is working when adding here:-
<BryntumScheduler
allowOverlap={false}/>
This will set overlap false to all the technician , but I am looking at each technician level, for example we have two technician(Arcady and Dave):-
{
"id": 1,
"name": "Arcady",
"role": "Core developer",
"calendar": "day"
},
{
"id": 2,
"name": "Dave",
"role": "Tech Sales",
"calendar": "day"
}
Now I want to allow overlap true for Dave and false for Arcady.
How can we achieve this?
That is not configurable because allowOverlap is a Scheduler config option, not a resource config option. You will need to handle it in your code. The general approach to take would be:
- Add a field to the resource model (for example
allowOverlapEvents
) - In the code check the value of this field and execute the different actions depending on the true/false value.
@saki Where I should add the logic I am sharing the drag.js file , you can find the same in sample application I attached above.
/**
* Taken from the vanilla dragfromgrid example
*/
// we import schedulerpro.umd for IE11 compatibility only. If you don't use IE import:
// import { DragHelper, DomHelper, Rectangle, WidgetHelper } from '@bryntum/schedulerpro';
import { DateHelper, DragHelper, DomHelper, Rectangle, WidgetHelper } from '@bryntum/schedulerpro/schedulerpro.umd';
export default class Drag extends DragHelper {
static get defaultConfig() {
return {
// Don't drag the actual row element, clone it
cloneTarget : true,
mode : 'translateXY',
// Only allow drops on the schedule area
dropTargetSelector : '.b-timeline-subgrid',
// Only allow drag of row elements inside on the unplanned grid
targetSelector : '.b-grid-row:not(.b-group-row)'
};
}
construct(config) {
const me = this;
super.construct(config);
// Configure DragHelper with schedule's scrollManager to allow scrolling while dragging
me.scrollManager = me.schedule.scrollManager;
me.on({
dragstart : me.onTaskDragStart,
drag : me.onTaskDrag,
drop : me.onTaskDrop,
thisObj : me
});
}
onTaskDragStart({ context }) {
const
me = this,
{ schedule } = me,
mouseX = context.clientX,
proxy = context.element,
task = me.grid.getRecordFromElement(context.grabbed),
newWidth = me.schedule.timeAxisViewModel.getDistanceForDuration(task.durationMS);
// save a reference to the task so we can access it later
context.task = task;
// Mutate dragged element (grid row) into an event bar
proxy.classList.remove('b-grid-row');
proxy.classList.add('b-sch-event-wrap');
proxy.classList.add('b-sch-event');
proxy.classList.add('b-unassigned-class');
proxy.classList.add(`b-${schedule.mode}`);
proxy.innerHTML = `<i class="${task.iconCls}"></i> ${task.name}`;
// If the new width is narrower than the grabbed element...
if (context.grabbed.offsetWidth > newWidth) {
const proxyRect = Rectangle.from(context.grabbed);
// If the mouse is off (nearly or) the end, centre the element on the mouse
if (mouseX > proxyRect.x + newWidth - 20) {
context.newX = context.elementStartX = context.elementX = mouseX - newWidth / 2;
DomHelper.setTranslateX(proxy, context.newX);
}
}
proxy.style.width = `${newWidth}px`;
// Prevent tooltips from showing while dragging
me.schedule.element.classList.add('b-dragging-event');
}
onTaskDrag({ context }) {
const
me = this,
{ schedule } = me,
{ task } = context,
coordinate = DomHelper[`getTranslate${schedule.isHorizontal ? 'X' : 'Y'}`](context.element),
startDate = schedule.getDateFromCoordinate(coordinate, 'round', false),
endDate = startDate && DateHelper.add(startDate, task.duration, task.durationUnit),
// Coordinates required when used in vertical mode, since it does not use actual columns
resource = context.target && schedule.resolveResourceRecord(context.target);
// Don't allow drops anywhere, only allow drops if the drop is on the timeaxis and on top of a Resource
context.valid &= Boolean(startDate && resource) &&
(schedule.allowOverlap || schedule.isDateRangeAvailable(startDate, endDate, null, resource));
// Save reference to resource so we can use it in onTaskDrop
context.resource = resource;
}
// Drop callback after a mouse up, take action and transfer the unplanned task to the real SchedulerEventStore (if it's valid)
onTaskDrop({ context }) {
const
me = this,
task = context.task,
target = context.target;
// If drop was done in a valid location, set the startDate and transfer the task to the Scheduler event store
if (context.valid && target) {
const
date = me.schedule.getDateFromCoordinate(DomHelper.getTranslateX(context.element), 'round', false),
// Try resolving event record from target element, to determine if drop was on another event
targetEventRecord = me.schedule.resolveEventRecord(context.target);
if (date) {
// Remove from grid first so that the data change
// below does not fire events into the grid.
me.grid.store.remove(task);
task.setStartDate(date, true);
task.resource = context.resource;
debugger;
me.schedule.eventStore.add(task);
}
// Dropped on a scheduled event, display toast
if (targetEventRecord) {
WidgetHelper.toast(`Dropped on ${targetEventRecord.name}`);
}
me.context.finalize();
}
else {
me.abort();
}
me.schedule.element.classList.remove('b-dragging-event');
}
};
if I am not wrong you are suggesting to add the setting like this:-
{
"id": 1,
"name": "Arcady",
"role": "Core developer",
"calendar": "day",
"allowOverlapEvents": true
},
Can you please add a example in above code.
We do not have a ready example for that. Generally, you can add it to onTaskDrag
after you have resource
available. Pseudo-code:
if(!resource.allowEventOverlap && isOverlapping) { // isOverlapping is to be written
context.valid = false;
}
else {
context.valid = true;
}
You would use a similar logic in onTaskDrop
:
if(!resource.allowEventOverlap && isOverlapping) { // isOverlapping is to be written
me.abort();
}
else {
me.context.finalize();
}
Yes, you can. I just tested it in our examples here https://www.bryntum.com/examples/scheduler-pro/drag-from-grid/
Run in console: scheduler.allowOverlap = false
and it works just fine.
Please share your solution if you still have problems with that.
Thanks,
Alex
All the best,
Alex