This is a migrated thread and some comments may be shown as answers.

How to select grid's data source item when it is not available in data source (because of initial page size)?

3 Answers 119 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Junius
Top achievements
Rank 2
Junius asked on 28 Jun 2019, 03:10 AM

Hi there,

I have a schedules grid which has 4 columns (2 columns are hidden), server paging is set to true, scrollable is endless and page size is 20.  Grid constructor code below.

$("#schedules-grid").kendoGrid({
                dataSource: {
                    transport: {
                        read: {
                            url: `/${window["routeContext"].TenantName}/Scheduler/GetSchedules`,
                            dataType: "json",
                            contentType: "application/json",
                            type: "GET",
                            headers: window["authenticationBearerToken"]
                        },
                    },
                    autoSync: true,
                    serverFiltering: false,
                    serverPaging: true,
                    serverSorting: false,
                    error: (e: kendo.data.DataSourceErrorEvent) => {
                        console.log(e);
                    },
                    pageSize: 20,
                    schema: {
                        model: {
                            id: "scheduleId"
                        },
                        total: data => {
                            if (data && data[0].total) {
                                return data[0].total;
                            }
                            return 0;
                        },
                        data: data => {
                            if (data) {
                                return data;
                            }
                            return [];
                        }
                    }
                },
                scrollable: {
                    endless: true
                },
                filterable: true,
                sortable: true,
                selectable: true,
                resizable: true,
                change: (e) => {
                    var selectedItem: any = e.sender.dataItem(e.sender.select());
                    if (this.onScrollToSelectedRow) this.onScrollToSelectedRow(selectedItem);
                },
                columns: [
                    {
                        field: "code",
                        title: "Code",
                        hidden: true
                    },
                    {
                        field: "recurrenceType",
                        title: "Recurrence",
                        width: 130
                    },
                    {
                        field: "title",
                        title: "Name"
                    },
                    {
                        field: "scheduleId",
                        title: "Schedule Id",
                        hidden: true
                    }
                ]
            });

 

In the grid, a function "onScrollToSelectedRow" is called when the schedules grid change event fires.  Code snippet below which scrolls to and highlight the selected item.

function (dataItem) {
            var scheduleGrid = $("#schedules-grid").data("kendoGrid");
 
            if (scheduleGrid) {
                var scrollContentOffset = scheduleGrid.element.find("tbody").offset().top;
                var selectContentOffset = scheduleGrid.select().offset().top;
                var distance = selectContentOffset - scrollContentOffset;
 
                scheduleGrid.element.find(".k-grid-content").animate({
                    scrollTop: distance
                }, 400);
            }
        }

 

The issue that I'm struggling with is when a user select a schedule (let's say another grid from another page) and, that selected item is not available in the schedules grid data source first 20 data items, the selectedItem variable in grid's change event will be undefined.

So, what I did I use insert method of schedules grid data source to append the selected item as last item in the data source.

function selectGridScheduleItem() {
        var schedGrid = window.Scheduler.scheduleGrid;
 
        if (schedGrid) {
            if (window.az_ScheduleviewModel) {
                var scheduleRowItem = schedGrid.dataSource.get(window.az_ScheduleviewModel.data.az_ScheduleId);
 
                if (scheduleRowItem) {
                    schedGrid.select("tr[data-uid='" + scheduleRowItem.uid + "']");
                } else {
                    var schedule = {
                        autoTitle: window.az_ScheduleviewModel.data.az_Schedule.az_AutoTitle,
                        code: window.az_ScheduleviewModel.data.az_Schedule.az_Code,
                        company: window.az_ScheduleviewModel.data.az_CompanyId,
                        cultureInfo: null,
                        dateEnd: window.az_ScheduleviewModel.data.az_Schedule.az_EndDate,
                        dateStart: window.az_ScheduleviewModel.data.az_Schedule.az_StartDate,
                        desc: window.az_ScheduleviewModel.data.az_Schedule.az_Description,
                        entityMetadata: window.az_ScheduleviewModel.data.az_EntityMetadataId,
                        init: window.az_ScheduleviewModel.data.az_InitObject,
                        jobType: window.az_ScheduleviewModel.data.az_JobType,
                        linkedJobs: 0,
                        platformResource: window.az_ScheduleviewModel.data.az_PlatformResourceId,
                        scheduleId: window.az_ScheduleviewModel.data.az_ScheduleId,
                        state: window.az_ScheduleviewModel.data.az_Schedule.az_State,
                        title: window.az_ScheduleviewModel.data.az_Schedule.az_Name,
                        total: 0
                    }
 
                    var schedRecurrence = undefined;
                    var recurrence = window.az_ScheduleviewModel.data.az_Schedule.az_Recurrence;
 
                    if (recurrence !== null || recurrence !== undefined) {
                        schedRecurrence = JSON.parse(recurrence);
                    }
 
                    if (schedRecurrence) {
                        schedule.recurrence = {
                            end: schedRecurrence.End,
                            repeatEvery: schedRecurrence.RepeatEvery,
                            repeatOn: schedRecurrence.RepeatOn,
                            time: schedRecurrence.Time,
                            type: schedRecurrence.Type
                        };
 
                        schedule.recurrenceType = schedRecurrence.Type;
                    }
 
                    schedGrid.dataSource.insert(schedGrid.dataSource.data().length, schedule);
                    schedGrid.setDataSource(schedGrid.dataSource);
 
                    scheduleRowItem = schedGrid.dataSource.get(window.az_ScheduleviewModel.data.az_ScheduleId);
                    schedGrid.select("tr[data-uid='" + scheduleRowItem.uid + "']");
                }
 
                console.log(scheduleRowItem);
            } else {
                console.log("Schedule view model is undefined");
            }
        } else {
            console.log("Schedules grid is undefined");
        }
    }

 

The function "selectGridScheduleItem" select the schedule row item in schedules grid and fires the change event of the grid if item is available in the data source.  Otherwise, it uses insert method to insert the selected item in schedules grid data source and select the data item.  

I'm not 100% sure using the insert method (if that solves the problem).  If there's a better way to do it please enlighten me.

And another thing I noticed, it doesn't scroll and highlight the row of the selected item.

 

Cheers,

Junius

3 Answers, 1 is accepted

Sort by
0
Boyan Dimitrov
Telerik team
answered on 01 Jul 2019, 12:31 PM
Hello Junius,

Such approach hides some potential problems, because it adds an item in the DataSource that already exists. I think that will add lots of duplicate items only to select an item and scroll to that item. My suggestion is rather use standard paging with the Kendo UI Grid and try to find the page number of the item you are looking for, page to that page and select the item. 

In the endless scrolling mode the Kendo UI Grid can not jump to specific page, because it loads the next page only when scrollbar is scrolled to the bottom. However just in case I implemented the desired scenario - endless scrolling and adding an item to the bottom of the current page and scroll to that item. Please refer to the https://dojo.telerik.com/ApEbuLun example. 
 
Regards,
Boyan Dimitrov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Junius
Top achievements
Rank 2
answered on 03 Jul 2019, 04:45 AM

Hi Boyan,

Thank you for your response, and also for providing an example. 

You are right, it will create duplicate items just only to select an item and scroll to it.

The business requirement says we don't use paging with all the grids in the page, so it's a problem if finding an item through page number.

I'm thinking if there's way to programmatically scroll the grid's scrollbar to the bottom of the grid, is that possible?

 

Cheers,

Junius

0
Boyan Dimitrov
Telerik team
answered on 04 Jul 2019, 04:37 PM
Hello Junius,

In endless scrolling mode it is hard to select an item that is not in the current view, because it needs to be loaded first. The only option I can think of is to scroll to the bottom of the grid until the item is loaded in the current view. 

Scrolling to the bottom of the grid will load the next portion of items. In endless scrolling mode there is no way to force the grid to load all items items with a single scroll. Actually if you are looking for such solution you can try to remove the endless scrolling mode and load all items on a single page. This way you will be able to find and select the desired item because all of them are loaded on a single page.  

Regards,
Boyan Dimitrov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Tags
Grid
Asked by
Junius
Top achievements
Rank 2
Answers by
Boyan Dimitrov
Telerik team
Junius
Top achievements
Rank 2
Share this question
or