Our pure JavaScript Scheduler component


Post by eugen »

In our Angular application, we currently use version 5.6.8 of the Scheduler Pro.

As normal, we bind our resources directly into the HTML. So in the TS-file we have a variable

protected myResources!: Partial<MyCustomResource>[];

that is bound in the HTML to the bryntum-scheduler-pro tag using

[resources]="myResources"

Whenever the resources update, we update this variable in the TS-file and the UI is updating itself without any problem. Now we needed to add custom sorting logic. We did this in our component like the following:

@ViewChild(BryntumSchedulerProComponent, { static: true }) schedulerComponent!: BryntumSchedulerProComponent;
private scheduler!: SchedulerPro;

public ngAfterViewInit(): void {
    this.scheduler = this.schedulerComponent.instance;
    this.scheduler.store.onSort = ({ source, sorters, records }: any) => {
      this.resourceSortColumn = sorters[0].field;
      this.resourceSortDirection = sorters[0].ascending ? 'asc' : 'desc';

  records.sort((a: any, b: any) => {
    return this.dataProcessingService.compareResources(
      a,
      b,
      this.resourceSortColumn,
      this.resourceSortDirection
    );
  });
};
}

Also this on its own is working perfectly.

However, a problems arises, when we have already sorted a column and then change the myResources variable. Even when this variable is sorted correctly on setting it, the scheduler changes the sort again, but without triggering the onSort callback, what leads to the problem that our sorting is breaking in that case. So the question is: How can we prohibit the scheduler doing this in that case or what would be the event-handler we need to listen to, to sort the resources again in that case?

Thanks for your answer,
Eugen :)


Post by marcio »

Hi Eugen,

To handle this, you can listen to the dataChange event on the Scheduler Pro component. This event is triggered whenever the data in the store changes, including when resources are updated.

Here's how you can set up the listener:

export class AppComponent implements AfterViewInit {
    @ViewChild(BryntumSchedulerProComponent, { static: true }) schedulerComponent!: BryntumSchedulerProComponent;
    private scheduler!: SchedulerPro;

    public ngAfterViewInit(): void {
        this.scheduler = this.schedulerComponent.instance;

        this.scheduler.store.onSort = ({ source, sorters, records }: any) => {
            this.resourceSortColumn = sorters[0].field;
            this.resourceSortDirection = sorters[0].ascending ? 'asc' : 'desc';

            records.sort((a: any, b: any) => {
                return this.dataProcessingService.compareResources(
                    a,
                    b,
                    this.resourceSortColumn,
                    this.resourceSortDirection
                );
            });
        };

        this.scheduler.on('dataChange', ({ store, action, records }) => {
            if (store === this.scheduler.resourceStore) {
                // Apply custom sorting logic here
                records.sort((a: any, b: any) => {
                    return this.dataProcessingService.compareResources(
                        a,
                        b,
                        this.resourceSortColumn,
                        this.resourceSortDirection
                    );
                });
            }
        });
    }
}

This setup should ensure that your custom sorting logic is applied whenever the resources are updated, even if the onSort callback is not triggered.

Best regards,
Márcio

How to ask for help? Please read our Support Policy


Post by eugen »

Hi Márcio,

Thanks for your answer! The hint of adding an event-handler on "dataChange" helped quite well, even when it did not solve the problem completely. When I added the code like you wrote it, so sorting is done directly in this event-handler, the sort was successfull in the event-handler, but for some reason the display was different again compared to what we sorted inside the handler.

The solution at the end was updating the sorter in the "dataChange" event-handler, so the "onSort" is called again like that:

    this.scheduler.store.onSort = ({ source, sorters, records }: any) => {
      if (sorters.length == 0) {
        return false;
      }

  this.resourceSortColumn = sorters[0].field;
  this.resourceSortDirection = sorters[0].ascending ? 'asc' : 'desc';

  records.sort((a: any, b: any) => {
    return this.dataProcessingService.compareResources(
      a,
      b,
      this.resourceSortColumn,
      this.resourceSortDirection
    );
  });

  return true;
};

this.scheduler.on('dataChange', ({ store, action, records }: any) => {
  if (store === this.scheduler.resourceStore) {
    if (this.resourceSortColumn != '' && this.resourceSortDirection != '') {
      this.scheduler.resourceStore.addSorter({
        ascending: this.resourceSortDirection == 'asc',
        columnOwned: true,
        field: this.resourceSortColumn,
      });
    }
  }
});

Thanks again for the help,
Eugen :)


Post Reply