bryntum / support

An issues-only repository for the Bryntum project management component suite which includes powerful Grid, Scheduler, Calendar, Kanban Task Board and Gantt chart components all built in pure JS / CSS / TypeScript
https://www.bryntum.com
53 stars 6 forks source link

Labels are wrong when renderer returns HTML or simple string value conditionally #3006

Open pmiklashevych opened 3 years ago

pmiklashevych commented 3 years ago

https://www.bryntum.com/forum/viewtopic.php?p=87905#p87905

According to the docs, renderer supports HTML as a value to return:

renderer : Function A function, which when passed an object containing eventRecord, resourceRecord, assignmentRecord and domConfig properties, returns the HTML to display as the label

Testcase:

Scheduler/examples/basic/app.js

/* eslint-disable no-unused-vars */
import '../_shared/shared.js'; // not required, our example styling etc.
import Scheduler from '../../lib/Scheduler/view/Scheduler.js';
import '../../lib/Scheduler/feature/Labels.js';

//region Data

const resources = [
    {
        id   : 1,
        name : 'Foo'
    },
    {
        id   : 2,
        name : 'Bar'
    }
];

const orangeEvents = [
    {
        id         : 1,
        resourceId : 1,
        startDate  : new Date(2021, 0, 29, 0),
        endDate    : new Date(2021, 0, 29, 2),
        eventColor : 'orange',
        name       : 'section 1',
        itemType   : 'section'
    },
    {
        id         : 130,
        resourceId : 1,
        startDate  : new Date(2021, 0, 29, 2),
        endDate    : new Date(2021, 0, 29, 4),
        eventColor : 'orange',
        name       : 'text 1',
        itemType   : 'text-only'
    },
    {
        id         : 2,
        resourceId : 1,
        startDate  : new Date(2021, 0, 29, 4),
        endDate    : new Date(2021, 0, 29, 6),
        eventColor : 'orange',
        name       : 'section 2*',
        itemType   : 'section'
    },
    {
        id         : 260,
        resourceId : 1,
        startDate  : new Date(2021, 0, 29, 6),
        endDate    : new Date(2021, 0, 29, 8),
        eventColor : 'orange',
        name       : 'text 2',
        itemType   : 'text-only'
    },
    {
        id         : 3,
        resourceId : 1,
        startDate  : new Date(2021, 0, 29, 8),
        endDate    : new Date(2021, 0, 29, 10),
        eventColor : 'orange',
        name       : 'section 3',
        itemType   : 'section'
    },
    {
        id         : 390,
        resourceId : 1,
        startDate  : new Date(2021, 0, 29, 10),
        endDate    : new Date(2021, 0, 29, 12),
        eventColor : 'orange',
        name       : 'text 3*',
        itemType   : 'text-only'
    },
    {
        id         : 4,
        resourceId : 1,
        startDate  : new Date(2021, 0, 29, 12),
        endDate    : new Date(2021, 0, 29, 14),
        eventColor : 'orange',
        name       : 'section 4',
        itemType   : 'section'
    }
];

const violetEvents = [
    {
        id         : 1,
        resourceId : 1,
        startDate  : new Date(2021, 0, 29, 0),
        endDate    : new Date(2021, 0, 29, 5),
        eventColor : 'violet',
        name       : 'section 1',
        itemType   : 'section'
    },
    {
        id         : 130,
        resourceId : 1,
        startDate  : new Date(2021, 0, 29, 5),
        endDate    : new Date(2021, 0, 29, 7),
        eventColor : 'violet',
        name       : 'text 1',
        itemType   : 'text-only'
    },
    // id 2 is missing
    {
        id         : 3,
        resourceId : 1,
        startDate  : new Date(2021, 0, 29, 7),
        endDate    : new Date(2021, 0, 29, 9),
        eventColor : 'violet',
        name       : 'section 3',
        itemType   : 'section'
    },
    {
        id         : 260,
        resourceId : 1,
        startDate  : new Date(2021, 0, 29, 9),
        endDate    : new Date(2021, 0, 29, 11),
        eventColor : 'violet',
        name       : 'text 2',
        itemType   : 'text-only'
    },
    // id 390 is missing
    {
        id         : 4,
        resourceId : 1,
        startDate  : new Date(2021, 0, 29, 11),
        endDate    : new Date(2021, 0, 29, 13),
        eventColor : 'violet',
        name       : 'section 4',
        itemType   : 'section'
    }
];

const commonEvents = [
    {
        id         : 11111,
        resourceId : 2,
        startDate  : new Date(2021, 0, 29, 0),
        endDate    : new Date(2021, 0, 29, 3),
        name       : 'section 1',
        itemType   : 'section'
    },
    {
        id         : 140,
        resourceId : 2,
        startDate  : new Date(2021, 0, 29, 3),
        endDate    : new Date(2021, 0, 29, 5),
        name       : 'text 1',
        itemType   : 'text-only'
    }
];

//endregion

let counter = 0;

const scheduler = new Scheduler({
    tbar : [{
        type : 'button',
        text : 'Reload data',
        onClick() {
            counter++;
            scheduler.eventStore.data = [...commonEvents, ...(counter % 2 === 0 ? orangeEvents : violetEvents)];
        }
    }],
    features : {
        labels : {
            top : {
                renderer({ eventRecord }) {
                    const value = `<div>
                        <span class="test">ID ${eventRecord.id} (${counter})</span>
                    </div>`;

                    return eventRecord?.itemType === 'section' ? value : '';
                }
            }
        }
    },
    eventRenderer({ eventRecord }) {
        return `${eventRecord.name} (ID ${eventRecord.id})`;
    },
    appendTo         : 'container',
    resources        : resources,
    startDate        : new Date(2021, 0, 29),
    endDate          : new Date(2021, 0, 30),
    viewPreset       : 'hourAndDay',
    rowHeight        : 50,
    barMargin        : 5,
    multiEventSelect : true,

    columns : [
        { text : 'Name', field : 'name', width : 130 }
    ]
});

Nothing is rendered initially. Click "Reload data" button to load violet tasks.

Снимок экрана 2021-06-09 в 15 25 37 Снимок экрана 2021-06-09 в 15 19 33

Click "Reload data" button again to load orange tasks. See the label is rendered wrong for a task with type "text".

Снимок экрана 2021-06-09 в 15 20 41

Click "Reload data" button again to load violet tasks again. See the label is rendered wrong for another task with type "text".

Снимок экрана 2021-06-09 в 15 23 15

======================= NOTE:

  1. If you sort the resources to let Bar to be at the top, labels are rendered correctly.
  2. If you return a simple string instead of HTML from the label renderer, labels are rendered correctly.
    features : {
        labels : {
            top : {
                renderer({ eventRecord }) {
                    return eventRecord?.itemType === 'section' ? `ID ${eventRecord.id} (${counter})` : '';
                }
            }
        }
    },
  3. If you always return HTML from the renderer, labels are rendered correctly.
    features : {
        labels : {
            top : {
                renderer({ eventRecord }) {
                    return `<div>
                        <span class="test">${eventRecord?.itemType === 'section' ? `ID ${eventRecord.id} (${counter})` : '&nbsp;'}</span>
                    </div>`;
                }
            }
        }
    },
matsbryntse commented 3 years ago

Some unrelated cleanup added in 3006-labels branch