Premium support for our pure JavaScript UI components


Post by jk@datapult.dk »

Hi there

I have this very basic example: https://www.dropbox.com/s/446ivba0kckgcwy/Screen%20Recording%202023-03-15%20at%2014.26.26.mov?dl=0

When I delete the first event, I expect to have happen what happened on the second delete event.

This happens if I do not set overlappingEventSorter: https://www.dropbox.com/s/1dmvr1nlgz4w1ue/Screen%20Recording%202023-03-15%20at%2014.29.15.mov?dl=0

import { Scheduler, DateHelper } from '../../build/scheduler.module.js?466040';
import shared from '../_shared/shared.module.js?466040';

//region Data

const
    resources = [
        { id: 'r1', name: 'Mike' },
        { id: 'r2', name: 'Linda' },
        { id: 'r3', name: 'Don' },
        { id: 'r4', name: 'Karen' },
        { id: 'r5', name: 'Doug' },
        { id: 'r6', name: 'Peter' },
        { id: 'r7', name: 'Sam' },
        { id: 'r8', name: 'Melissa' },
        { id: 'r9', name: 'John' },
        { id: 'r10', name: 'Ellen' }
    ],
    events = [
        {
            id: 1,
            resourceId: 'r1',
            startDate: new Date(2017, 0, 1, 10),
            endDate: new Date(2017, 0, 1, 12),
            name: 'Click me',
            iconCls: 'b-fa b-fa-mouse-pointer'
        },
        {
            id: 2,
            resourceId: 'r1',
            startDate: new Date(2017, 0, 1, 12),
            endDate: new Date(2017, 0, 1, 13, 30),
            name: 'Drag me',
            iconCls: 'b-fa b-fa-arrows-alt'
        },
        {
            id: 3,
            resourceId: 'r1',
            startDate: new Date(2017, 0, 1, 14),
            duration: 2,
            durationUnit: 'h',
            name: 'Double click me',
            eventColor: 'purple',
            iconCls: 'b-fa b-fa-mouse-pointer'
        },
        {
            id: 4,
            resourceId: 'r1',
            startDate: new Date(2017, 0, 1, 8),
            endDate: new Date(2017, 0, 1, 11),
            name: 'Right click me',
            iconCls: 'b-fa b-fa-mouse-pointer'
        },
        {
            id: 5,
            resourceId: 'r1',
            startDate: new Date(2017, 0, 1, 15),
            endDate: new Date(2017, 0, 1, 17),
            name: 'Resize me',
            iconCls: 'b-fa b-fa-arrows-alt-h'
        },
        {
            id: 6,
            resourceId: 'r1',
            startDate: new Date(2017, 0, 1, 16),
            endDate: new Date(2017, 0, 1, 19),
            name: 'Important meeting (read-only)',
            iconCls: 'b-fa b-fa-exclamation-triangle',
            eventColor: 'red',
            readOnly: true
        },
        {
            id: 7,
            resourceId: 'r1',
            startDate: new Date(2017, 0, 1, 6),
            endDate: new Date(2017, 0, 1, 8),
            name: 'Sports event',
            iconCls: 'b-fa b-fa-basketball-ball'
        },
        {
            id: 8,
            resourceId: 'r1',
            startDate: new Date(2017, 0, 1, 9),
            endDate: new Date(2017, 0, 1, 11, 30),
            name: 'Dad\'s birthday!',
            iconCls: 'b-fa b-fa-birthday-cake',
            // Custom styling from data
            style: 'background-color : teal; font-size: 18px',
            // Prevent default styling
            eventStyle: 'none'
        }
    ];

//endregion

const scheduler = new Scheduler({
    appendTo: 'container',
    resources: resources,
    events: events,
    startDate: new Date(2017, 0, 1, 6),
    endDate: new Date(2017, 0, 1, 20),
    viewPreset: 'hourAndDay',
    rowHeight: 50,
    barMargin: 5,
    multiEventSelect: true,
    columns: [
        { text: 'Name', field: 'name', width: 130 }
    ]
});

scheduler.overlappingEventSorter = function (a, b) {
    // Always sort b-fa-mouse-pointer on the bottom
    if (a.iconCls === 'b-fa b-fa-mouse-pointer' && b.iconCls !== 'b-fa b-fa-mouse-pointer') {
        return 1
    }
    return 0
}

Post by alex.l »

Hi, thank you for clear test case! That looks like a bug, I've opened a ticket to investigate this problem https://github.com/bryntum/support/issues/6388

All the best,
Alex


Post by alex.l »

Hi, we checked it deeply. All you need is to fix your custom sort method to have expected result.
Please check docs https://bryntum.com/products/scheduler/docs/api/Scheduler/view/mixin/SchedulerEventRendering#config-overlappingEventSorter

NOTE: The algorithms (stack, pack) that lay the events out expects them to be served in chronological order, be sure to first sort by startDate to get predictable results.

All the best,
Alex


Post by jk@datapult.dk »

Hi alex,

I added this line right before overlappingEventSorter and I can still replicate the issue: https://www.dropbox.com/s/mjrhdlqqm2ii5et/Screen%20Recording%202023-03-16%20at%2008.37.11.mov?dl=0

scheduler.eventStore.sort([{field: 'startDate', ascending: true,},])

import { Scheduler, DateHelper } from '../../build/scheduler.module.js?466040';
import shared from '../_shared/shared.module.js?466040';

//region Data

const
    resources = [
        { id: 'r1', name: 'Mike' },
        { id: 'r2', name: 'Linda' },
        { id: 'r3', name: 'Don' },
        { id: 'r4', name: 'Karen' },
        { id: 'r5', name: 'Doug' },
        { id: 'r6', name: 'Peter' },
        { id: 'r7', name: 'Sam' },
        { id: 'r8', name: 'Melissa' },
        { id: 'r9', name: 'John' },
        { id: 'r10', name: 'Ellen' }
    ],
    events = [
        {
            id: 1,
            resourceId: 'r1',
            startDate: new Date(2017, 0, 1, 10),
            endDate: new Date(2017, 0, 1, 12),
            name: 'Click me',
            iconCls: 'b-fa b-fa-mouse-pointer'
        },
        {
            id: 2,
            resourceId: 'r1',
            startDate: new Date(2017, 0, 1, 12),
            endDate: new Date(2017, 0, 1, 13, 30),
            name: 'Drag me',
            iconCls: 'b-fa b-fa-arrows-alt'
        },
        {
            id: 3,
            resourceId: 'r1',
            startDate: new Date(2017, 0, 1, 14),
            duration: 2,
            durationUnit: 'h',
            name: 'Double click me',
            eventColor: 'purple',
            iconCls: 'b-fa b-fa-mouse-pointer'
        },
        {
            id: 4,
            resourceId: 'r1',
            startDate: new Date(2017, 0, 1, 8),
            endDate: new Date(2017, 0, 1, 11),
            name: 'Right click me',
            iconCls: 'b-fa b-fa-mouse-pointer'
        },
        {
            id: 5,
            resourceId: 'r1',
            startDate: new Date(2017, 0, 1, 15),
            endDate: new Date(2017, 0, 1, 17),
            name: 'Resize me',
            iconCls: 'b-fa b-fa-arrows-alt-h'
        },
        {
            id: 6,
            resourceId: 'r1',
            startDate: new Date(2017, 0, 1, 16),
            endDate: new Date(2017, 0, 1, 19),
            name: 'Important meeting (read-only)',
            iconCls: 'b-fa b-fa-exclamation-triangle',
            eventColor: 'red',
            readOnly: true
        },
        {
            id: 7,
            resourceId: 'r1',
            startDate: new Date(2017, 0, 1, 6),
            endDate: new Date(2017, 0, 1, 8),
            name: 'Sports event',
            iconCls: 'b-fa b-fa-basketball-ball'
        },
        {
            id: 8,
            resourceId: 'r1',
            startDate: new Date(2017, 0, 1, 9),
            endDate: new Date(2017, 0, 1, 11, 30),
            name: 'Dad\'s birthday!',
            iconCls: 'b-fa b-fa-birthday-cake',
            // Custom styling from data
            style: 'background-color : teal; font-size: 18px',
            // Prevent default styling
            eventStyle: 'none'
        }
    ];

//endregion

const scheduler = new Scheduler({
    appendTo: 'container',
    resources: resources,
    events: events,
    startDate: new Date(2017, 0, 1, 6),
    endDate: new Date(2017, 0, 1, 20),
    viewPreset: 'hourAndDay',
    rowHeight: 50,
    barMargin: 5,
    multiEventSelect: true,
    columns: [
        { text: 'Name', field: 'name', width: 130 }
    ]
});

scheduler.eventStore.sort([{field: 'startDate', ascending: true,},])

scheduler.overlappingEventSorter = function (a, b) {
    // Always sort b-fa-mouse-pointer on the bottom
    if (a.iconCls === 'b-fa b-fa-mouse-pointer' && b.iconCls !== 'b-fa b-fa-mouse-pointer') {
        return 1
    }
    return 0
}

Post by alex.l »

you don't need to pre-sort eventStore, you need to sort events by startDate inside your custom overlappingEventSorter method.
Please check comments in the ticket https://github.com/bryntum/support/issues/6388 , it contains original code of overlappingEventSorter.

All the best,
Alex


Post by jk@datapult.dk »

Hi alex

Just 3 comments:

  1. It is not clear from the documentation so maybe add the inside part to the docs as well.
  2. Unsure what to look for in the ticket. This read like an internal todo and not a wontfix "We need to make it easier to add special conditions So maybe call the custom overlappingEventSorter to see if it has opinions about the two events"
  3. The code supplied in the ticket is not in userland. It belongs to your lib.

Post by alex.l »

Hi,

  1. thank for the feedback, we will review docs to make it more clear.
    2-3. All I meant is that the ticket I mentioned contains the original code of sorting that used when overlappingEventSorter is not customized, also the name of class and method that you can find and review to make your sorter better. So, it might be helpful for you to review it and use for your custom sorter method. I will post the code here, to be more clear
        eventSorter(a, b) {
            if (this.overlappingEventSorter) {
                return this.overlappingEventSorter(a.eventRecord || a, b.eventRecord || b);
            }
    
    const
        // TODO: Rename startMS -> startDateMS to not have to have isModel check here (and to be consistent)
        startA    = a.isModel ? a.startDateMS : a.dataStartMS || a.startMS, // dataXX are used if configured with fillTicks
        endA      = a.isModel ? a.endDateMS : a.dataEndMS || a.endMS,
        startB    = b.isModel ? b.startDateMS : b.dataStartMS || b.startMS,
        endB      = b.isModel ? b.endDateMS :  b.dataEndMS || b.endMS,
        nameA     = a.isModel ? a.name : a.eventRecord.name,
        nameB     = b.isModel ? b.name : b.eventRecord.name;
    
    return startA - startB || endB - endA || (nameA < nameB ? -1 : nameA == nameB ? 0 : 1);
        }
    
    In total, you need to sort events by startDate inside your overlappingEventSorter method before sort by other params, if you want to see it sorted same as with original sorter and react on events removing as you expect.

All the best,
Alex


Post Reply