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

vitual scrolling, client data, scroll to row number

10 Answers 485 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Marc
Top achievements
Rank 1
Marc asked on 06 Jun 2017, 02:37 PM

We have a large data grid with virtual scrolling (needed for performance), all data on client (server operation = false).

This is a big list of parts.

What is the best way to allow the user to scroll to a part number that is currently not rendered in the grid?

10 Answers, 1 is accepted

Sort by
0
Marc
Top achievements
Rank 1
answered on 07 Jun 2017, 04:31 PM

Nothing?

We are getting close to getting excel type functionality on a web grid with a large dataset. But missing a few key elements. Including this.

0
Stefan
Telerik team
answered on 08 Jun 2017, 07:27 AM
Hello Marc,

Currently, the Grid does not provide a feature to scroll to a specific item.

I can suggest using a filter mode row, and allow the user to search for the specific part number.

http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#configuration-filterable.mode

Also, I can suggest submitting a feature request and based on its popularity we may implement it in a future release:

http://kendoui-feedback.telerik.com/forums/127393-kendo-ui-feedback/category/170280-grid

Another option will be our Feature acceleration program which will allow purchasing a specific feature, which is not on our roadmap, but it is very important for the application.

Regards,
Stefan
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Marc
Top achievements
Rank 1
answered on 08 Jun 2017, 02:48 PM

Thanks, I'll see how this works.

 

I added a feature request. 8 years ago I wrote the line of code below in a silverlight radgrid and was able to achieve this, it would be nice to do in a kendo grid as easily.

 

PartGridView.ScrollIntoView(item);

0
Marc
Top achievements
Rank 1
answered on 09 Jun 2017, 07:23 PM

As an update to your report, simply filtering to the row the user is searching for is not an acceptable solution, because they need to see the row in the context of its parent and/or child rows which of course disappear with filtering.

 

Hopefully I can find another solution.

0
Viktor Tachev
Telerik team
answered on 12 Jun 2017, 11:09 AM
Hello Marc,

The developers will look into the feature request you have submitted and will consider the possibilities for implementing it based on the traction it gets with the community.

With that said, if the feature is crucial to your application you can consider our Feature Acceleration service. It enables you to negotiate a certain functionality to be implemented sooner.


Regards,
Viktor Tachev
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Marc
Top achievements
Rank 1
answered on 12 Jun 2017, 03:36 PM

Ok, well it possible to write a custom javascript search function that would:

1. Find the part in question in the grid datasource

2. Analyze the position of the dataitem in relation to the entire datasource

3. Calculate the page based on the page size and position of dataitem

4. grid.wrapper.find(".k-scrollbar").scrollTop to the new page

5. Perhaps highlight or do a css fade function on the part that was found since it may not be exactly on the top of the page

 

Let me know if this approach is possible, and I will write it. Thanks

0
Stefan
Telerik team
answered on 14 Jun 2017, 07:58 AM
Hello Marc,

Due to some of the specifics of the Virtual scrolling, this approach may not work as expected, because when the page is changed the DOM elements are replaced with the ones for the new page. This will result in the page with the searched item not being rendered, so the Grid will not scroll to it as it is not part of the DOM.

Regards,
Stefan
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data (charts) and form elements.
0
Marc
Top achievements
Rank 1
answered on 20 Jul 2017, 05:44 PM

Per your post, this is partially working. On the server I've given all the items in my data a page number based on the page size of the grid.

I then find all matching items in the grid.

        var grid = $("#grid").data("kendoGrid");
        var data = grid.dataSource._data;
        var matchingParts = $.grep(data, function (d) {
            return d.PartNumber.indexOf(partNumber) === 0;
        });

 

Then allowing the user to iterate through all the items by determining the page number each item and scrolling to that page.

var pageNumber = matchingPart.PageNumber;

     var rowHeight = grid.tbody.children().eq(0).height();

     var pageSize = grid.dataSource.pageSize();
     var scrollTop = rowHeight * pageSize * (pageNumber - 1);
     grid.wrapper.find(".k-scrollbar").scrollTop(scrollTop);

 

This will render the proper 'page' (effect of scrolling), but the actual item may not be in the viewable area.

Is there any way once the virtual page is rendered, to center the item that was searched for?

If so, this approach would be workable for me.

 

0
Stefan
Telerik team
answered on 24 Jul 2017, 07:59 AM
Hello Marc,

I'm glad to hear that the desired result is almost achieved.

In general, the provided logic to scroll the Grid should works as expected. I can assume that some modification of the variables may be needed. I made a test scenario and it was working as expected:

http://dojo.telerik.com/AYoPa

Also, we recommend using the data method of the dataSource instead of the private _data variable:

https://admin.telerik.com/docs.telerik.com/kendo-ui/api/javascript/data/datasource#methods-data

Regards,
Stefan
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data (charts) and form elements.
0
Marc
Top achievements
Rank 1
answered on 23 Aug 2017, 10:04 PM

I'll post my current solution in case it helps someone, or someone wants to improve it. I basically calculate the offset by calculating the page number and index number (per 100 records). Then scroll to the row and highlight it. If the scroll is going to a new page, then the databound event handler highlights the row after it's been rendered.

I'm using a constant (18.6), since it's more exact than multiplying the row height (19px). I suppose this could be dynamically adjusted per the users zoom or other factors.

 

01.    var searchedPartNumber; // part number that is being searched for
02.    var searchedPartIndex; // the index of the array of parts currently being searched
03.    var selectOrderNumber; // the number of the row
04.    var searchDataBound = false;
05. 
06. 
07.function onGridDataBound(e) {
08.        if ($("#partNumberSearchInput").val() && searchDataBound) {
09.            setTimeout(function() { selectRow($("#partNumberSearchInput").val()); }, 200);
10.        }
11.    }
12. 
13. function searchPartNumber() {
14.        searchDataBound = true;
15.        var partNumber = $("#partNumberSearchInput").val().trim();
16.        if (searchedPartNumber && (partNumber !== searchedPartNumber)) {
17.            searchedPartNumber = undefined;
18.            selectOrderNumber = undefined;
19.            searchedPartIndex = undefined;
20.        }
21. 
22.        var grid = $("#MyGrid").data("kendoGrid");
23.        var data = grid.dataSource._data;
24.        var matchingParts = $.grep(data, function (d) {
25.            return d.PartNumber.indexOf(partNumber) === 0;
26.        });
27. 
28.        if (matchingParts.length > 0) {
29.            var matchingPart;
30.            if (matchingParts.length === 1) {
31.                matchingPart = matchingParts[0];
32.            } else {
33.                searchedPartNumber = partNumber;
34.                if (searchedPartIndex === undefined) {
35.                    searchedPartIndex = 0;
36.                } else {
37.                    searchedPartIndex++;
38.                }
39.                if (searchedPartIndex > matchingParts.length - 1) {
40.                    searchedPartIndex = 0;
41.                }
42.                matchingPart = matchingParts[searchedPartIndex];
43.            }
44. 
45.            var pageNumber = matchingPart.PageNumber;
46.            selectOrderNumber = matchingPart.OrderNumber;
47.            var orderNumber = selectOrderNumber.toString();
48. 
49.            if (orderNumber.length > 1) {
50.                orderNumber = orderNumber.substr(orderNumber.length - 2);
51.            }
52. 
53.              var orderNumberInt = parseInt(orderNumber, 10);
54.              var numberOffset = (orderNumberInt - 1) * 18.6;
55.              var scrollTop = (1860.65 * (pageNumber - 1)) + numberOffset;
56.                grid.wrapper.find(".k-scrollbar").scrollTop(scrollTop);
57.               if (pageNumber === grid.dataSource._page) {
58.                selectRow(partNumber);
59.               } // else called on databound
60. 
61.            if (!searchedPartIndex) {
62.                searchedPartIndex = 0;
63.            } //recycle back to start of search
64. 
65.            $("#searchInfo").html((searchedPartIndex + 1) + " of " + matchingParts.length + ", Line Number: " + selectOrderNumber);
66.        } else {
67.            alert("Could not find part number " + partNumber + " in this list");
68.        }
69.    }
70. 
71.    function selectRow(partNumber) {
72.        searchDataBound = false;
73.        if (partNumber) {
74.            var grid = $("#MyGrid").data("kendoGrid");
75.            var rows = grid.tbody.find(" > tr");
76.            var rowCount = grid.tbody.find(" > tr").length;
77.            if (rowCount > 0) {
78.                for (var x = 0; x < rowCount; x++) {
79.                    var dataItem = grid.dataItem(rows[x]);
80.                    var row = rows[x];
81.                    if (dataItem.PartNumber === partNumber) {
82.                        row.style.backgroundColor = "#b9f6ca";
83.                    }
84.                }
85.            }
86.        }
87.    }
Tags
Grid
Asked by
Marc
Top achievements
Rank 1
Answers by
Marc
Top achievements
Rank 1
Stefan
Telerik team
Viktor Tachev
Telerik team
Share this question
or