Our pure JavaScript Scheduler component


Post by doonamis »

Hello!

I've created a project following this demo:

https://www.bryntum.com/examples/scheduler/vue/javascript/drag-from-grid/dist/index.html

In our case for example the events are rides and the resources are the drivers performing it

So every ride has a number of people and the resources has a vehicleCapacity field

Also now I've added some validation on the eventDrag,

If you try to drag a ride with a higher number of people than the vehicleCapacity the validation works and you can't do it

Is there a way to have the same thing but from the rides you're dragging from the grid? (The ones aren't assigned)

Thanks!

Post by mats »

You should consider our demos purely inspirational, so it's a good idea to read their sources and learn from them to then create a production ready solution. If you open our drag-from-grid demo, you'll see that it has some basic validation built in:

Drag.js
 onTaskDrag({ event, context }) {
        const
            me         = this,
            coordinate = DomHelper[`getTranslate${me.schedule.isHorizontal ? 'X' : 'Y'}`](context.element),
            date       = me.schedule.getDateFromCoordinate(coordinate, 'round', false),
            // Coordinates required when used in vertical mode, since it does not use actual columns
            resource   = context.target && me.schedule.resolveResourceRecord(context.target, [event.offsetX, event.offsetY]);

        // Don't allow drops anywhere, only allow drops if the drop is on the timeaxis and on top of a Resource
        context.valid = context.valid && Boolean(date && resource);

        // Save reference to resource so we can use it in onTaskDrop
        context.resource = resource;
    }
So, you should simply extend this bit of validation to add your own application logic. Good luck!

Post by doonamis »

Hello Mats,

Sure thanks this works, I think my question was not right, I was thinking if theres anyway to add a validation like the ones you have when you drag or resize an event inside the scheduler, meaning I can show an error text on the top of the event

If not I'll stay with this and add some custom error message shown by myself

Thanks!

Post by Maxim Gorkovsky »

Here is a demo of showing a tooltip on invalid drop (for demo purpose all drop are invalid)
// examples/dragfromgrid/lib/Drag.js
onTaskDrag({ context }) {
    context.message = 'Overbooked';
    context.valid = false; 

    // Save reference to resource so we can use it in onTaskDrop
    context.resource = resource;
}

onTaskDrop({ context, event }) {
    const
        me               = this,
        { task, target } = context;

    // If drop was done in a valid location, set the startDate and transfer the task to the Scheduler event store
    if (context.valid && target) {
        ...
    }
    else {
        const
            element    = DomHelper.createElement({
                parent    : document.body,
                style     : `position:absolute;left:${event.pageX}px;top:${event.pageY}px;width:1px;height:1px;`,
                className : 'myplaceholder'
            }),
            tooltip = new Tooltip({
                forSelector : '.myplaceholder',
                html        : context.message
            });
        
        tooltip.show();
        
        setTimeout(() => {
            tooltip.hide();
            element.remove();
        }, 1000);
        
        me.abort();
    }

    me.schedule.element.classList.remove('b-dragging-event');
}

Post by Maxim Gorkovsky »

And in case you want to show tooltip while dragging the ride, you can do smth like:
// examples/dragfromgrid/lib/Drag.js
constructor() {
  me.tooltip = new Tooltip();
}

onTaskDrag({ event, context }) {
    const
        me         = this,
        coordinate = DomHelper[`getTranslate${me.schedule.isHorizontal ? 'X' : 'Y'}`](context.element),
        date       = me.schedule.getDateFromCoordinate(coordinate, 'round', false),
        // Coordinates required when used in vertical mode, since it does not use actual columns
        resource   = context.target && me.schedule.resolveResourceRecord(context.target, [event.offsetX, event.offsetY]);

    // Don't allow drops anywhere, only allow drops if the drop is on the timeaxis and on top of a Resource
    context.valid = context.valid && Boolean(date && resource);
    
    // allow dropping on even resources only
    if (resource && me.schedule.resourceStore.indexOf(resource) % 2 !== 0) {
        context.valid = false;
        me.tooltip.html = 'Vehicle capacity is not enough';
        me.tooltip.showByTarget(context.target);
    }
    else {
        me.tooltip.hide();
    }
    
    // Save reference to resource so we can use it in onTaskDrop
    context.resource = resource;
}

Post Reply