Our pure JavaScript Scheduler component


Post by v-paulrausch »

Hi Team,
Is it possible to place a custom search box on the column?. I tried using renderer and header renderer, but nothing shows up, looks like it only accepts string values. I am trying to place a search box in the place of search box here placeholder.

Screenshot 2024-02-26 105036.png
Screenshot 2024-02-26 105036.png (56.81 KiB) Viewed 158 times

Regards,
Paul


Post by tasnim »

Hi,

Sounds like you're looking for this feature https://bryntum.com/products/schedulerpro/docs/api/Grid/feature/FilterBar?
If this is not you're looking for, Could you please provide more details about your use case?

Good Luck :),
Tasnim


Post by v-paulrausch »

Hi Tasnim,
Filter Bar will not work for us as its position is just above the resource info header but we need it on top header. we are trying to achieve this :

Screenshot 2024-02-26 130408.png
Screenshot 2024-02-26 130408.png (11.72 KiB) Viewed 153 times

thanks,
Paul


Post by alex.l »

Hi,

We have a demo that has a widget placed in a header, please see https://bryntum.com/products/grid/examples/renderers/
Try to adjust your code according to demo. If no luck, we need to review your solution, because it works well on our side.

All the best,
Alex


Post by tasnim »

Hi,

Here are the steps to follow to achieve it
First you'd need to have the filterBar feature enabled and then you'd need to have some styles applied to it.
You can see the result by applying this code locally in our scheduler examples folder scheduler/examples/header-summary example

async function launchScheduler() {

const crudManager = new CrudManager({
    loadUrl : 'data/data.json'
});

await crudManager.load();

const chainedResourceStore = crudManager.resourceStore.chain();
chainedResourceStore.group('summary');
const titles = chainedResourceStore.getGroupTitles();

const headerConfigs = titles.map(title => {
    const reocrds = crudManager.eventStore.records.filter(record => record.summary === title);
    return {
        unit     : 'day',
        // Show a number indicating number of events intersecting each day
        renderer : (startDate, endDate, headerConfig, index, scheduler) => {
            let events = 0;
            scheduler.eventStore.forEach(event => {
                if (DateHelper.intersectSpans(event.startDate, event.endDate, startDate, endDate)) {
                    events++;
                }
            });

            return events || '';
        }
    };
});

const scheduler = new Scheduler({
    appendTo          : 'container',
    eventColor        : 'blue',
    barMargin         : 10,
    startDate         : new Date(2024, 6, 1),
    endDate           : new Date(2024, 6, 21),
    resourceImagePath : '../_shared/images/users/',
    crudManager,
    rowHeight         : 40,
    columns           : [
        {
            type     : 'resourceInfo',
            width    : 200,
            sortable : false,
            headerRenderer(props) {
                const icons = {
                    Required : {
                        icon : '<i class="b-fa-regular b-fa-clock" style="color: #ff9bad"></i>'
                    },
                    Staffing : {
                        icon : '<i class="b-fa b-fa-people-group" style="color: #35d235"></i>'
                    },
                    Zoo : {
                        icon : '<i class="b-fa b-fa-hippo" style="color:#35a2b0"></i>'
                    }
                };
                const { column } = props;
                const html = titles.map(title => `<div class="header-custom" style="flex: 1 0 2em; border-top: 1px solid #d8d9da; width: 100%; display:flex; align-items:center;padding-left:20px;">
            ${icons[title]?.icon ?? icons.Required}<span style="margin-left:10px">${title}</span>
            </div>`).join('');
                console.log(html);
                return html;
            },
            filterable : {
                filterField : {
                    type        : 'textfield',
                    placeholder : 'search',
                    cls         : 'b-searchbox',
                    triggers    : {
                        plug : {
                            cls : 'b-fa b-fa-magnifying-glass'
                        }
                    }
                }
            }
        }
    ],
    features : {
        filterBar : true,
        group     : {
            field : 'summary',
            renderer(props) {
                const { rowElement, groupRowFor } = props;
                if (rowElement.closest('[data-region="locked"]')) {
                    const icon = groupRowFor === 'Staffing'
                        ? `<i class="b-fa b-fa-people-group" style="color: #35d235"></i>`
                        : groupRowFor === 'Required'
                            ? `<i class="b-fa-regular b-fa-clock" style="color: #ff9bad"></i>` : '';
                    return [
                        { html : `${icon}<span style="text-transform:none;margin-left:10px;font-weight: 300;">${groupRowFor}</span>` }
                    ];
                }
            }
        }
    },
    viewPreset : {
        base           : 'weekAndDayLetter',
        rowHeight      : 40,
        timeResolution : {
            unit      : 'day',
            increment : 1
        },

        headers : [
            {
                unit       : 'week',
                dateFormat : 'LL'
            },
            {
                unit       : 'd',
                dateFormat : 'dd'
            },
            ...headerConfigs
        ]
    }
});

scheduler.eventStore.on('change', () => scheduler.timeAxisColumn.refreshHeader());

}

launchScheduler();

And this is the CSS

.b-searchbox {
    padding : 0;
    margin : 0;
}
[data-region="locked"] .b-searchbox.b-textfield div {
    height: 55px;
}

.b-grid-header-text-content {
	height: 100%;
    align-items: center;
    display: flex;
    flex-direction: column;
	flex : 1 1 100%;
}

.b-grid-header-text {
    flex: 1;
}

[data-region="locked"] .b-grid-header .b-searchbox div:hover,
[data-region="locked"] .b-grid-header .b-searchbox.b-contains-focus div {
    border-color: #000;
}
.b-grid-header-text {
    margin: 0;
    padding: 0;
}

[data-region="locked"] .b-grid-header {
    border-bottom : 1px solid #d8d9da;
}
.b-grid-header-text-content {
	flex : 1 0 100%;
}
[data-region="locked"] .b-grid-header {
    padding-inline : 0;
	flex-direction : column-reverse;
}
.b-searchbox.b-textfield div {
    padding-inline: 5px;
    height: 40px;
    border: none;
    border-bottom : 1px solid green;
}

.b-group-state-icon {
    display : none;
}

[data-region="locked"] .b-group-row .b-grid-cell {
	margin-left : 30px;
}

Here is a screenshot of it

Screenshot 2024-02-26 205009.png
Screenshot 2024-02-26 205009.png (24.9 KiB) Viewed 117 times

Hope this helps.

Best regards,
Tasnim


Post by tasnim »

Just a quick update that we're building a demo about it

msedge_mBBbsyloPC.gif
msedge_mBBbsyloPC.gif (979.01 KiB) Viewed 94 times

Post Reply