Adding a Row Number to Telerik ASP.NET Core Scrolling Grid

I've been playing around with the Telerik UI for ASP.NET Core Grid component from Progress Software. Since I have experience using their UI components for ASP.NET AJAX, I thought this would be a good choice as I'm transitioning web apps to ASP.NET Core. In the latest release (Q3 2019), the Grid has added an "endless scrolling" feature. This feature allows a web developer to present a grid that functions in the web similar to what would happen in a desktop app. And, it certainly does that, but it raised a question

How do I add a Row Number?

After searching around the Telerik's website and the web in general, I didn't find an implementation I liked so I contacted Telerik Technical Support (which, in my experience, is excellent). Their response got me on the right track but didn't resolve it. Many people might find this surprising; however, as I mentioned earlier, the "endless scrolling" feature is new. Here's how I solved it.

The first thing I decided to do was add a row number to my stored procedure in T-SQL. Here are the changes to the T-SQL stored procedure and a screen shot of the execution output.

Here is the output of the Grid on a web page to illustrate the incorrect and correct row numbering. As you can see in the Row Wrong column, the row number becomes incorrect once we scroll past the first page.

So, let's take a look at the code and figure out what's right and wrong in this specific scenario. Here is HtmlHelper definition of the Grid.

    .Columns(columns =>
	  columns.Template("#=myRowNumWrong(data)#").Title("Row Wrong").Width(75);
	  columns.Template("#=myRowNum(data)#").Title("Row Correct").Width(75);
	  columns.Bound(p => p.RowNum).Title("Row T-SQL").Width(75);
	.HtmlAttributes(new { style = "height: 100%;" })
	.Scrollable(scrollable => scrollable.Endless(true))
	.Pageable(p => p.Numeric(false).PreviousNext(false))
	.ToolBar(t => t.Search())
	.Search(s => { s.Field(c => c.Consumer); s.Field(c => c.ConsumerService); s.Field(c => c.AlertStatus); })
	.Resizable(resize => resize.Columns(true))
	.DataSource(dataSource =>			   
Note:  I have removed the DataSource definition. It is not needed to get the concept.

Here is the Javascript definition for the function "myRowNumWrong".

    var myRowNumWrong = function(e) {
        var grid = $("#gridAlertAvailableUnits").data("kendoGrid");
        var ds = grid.dataSource;
        var pageSize = ds.pageSize();
        var pageN =;
        var rowN = (pageSize * (pageN - 1)) + ds.indexOf(e) + 1;

        console.log("Page Size: " + pageSize.toString() + "  Page: " + pageN.toString() + "  ds.indexOf(e): " + ds.indexOf(e).toString() + "  Row Wrong: " + rowN.toString());

        return rowN;
The code above was supplied by Telerik technical support and if you review the calculation of the Row Number this makes perfect sense. Get the Page Size; multiply it by the Page Number minus 1; and, then, add the Indexed Row of the Dataset plus 1. Unfortunately, this gives incorrect values for pages past page 1.

And, here is the Javascript definition for the function "myRowNum" which provides the correct row number.

    var myRowNum = function (e) {
        var grid = $("#gridAlertAvailableUnits").data("kendoGrid");
        var ds = grid.dataSource;
        var rowNum = ds.indexOf(e) + 1;

        console.log("Row Correct:" + rowNum.toString());

        return rowNum;

The following screen shot shows the console log when we move from Page 1 to Page 2 during the endless scrolling. By logging the different values in myRowNumWrong, we're able to quickly identify that ds.indexOf(e) is providing the row number minus 1 directly. I'm not sure if this is a result of the new endless scrolling feature or due to the way I've implemented the call to the Web API. Either way, if you run into an issue with using a Javascript function to supply the row number for a Telerik Kendo Grid then you should take a look at the number that ds.indexOf(e) is providing (where ds represents the Telerik Kendo Grid data set).

The above illustrates 3 ways to implement a row number with the Telerik UI for ASP.NET Core Grid (i.e. Kendo Grid). Although, in this case the myRowNumWrong Javascript function provides an incorrect value when the grid is paged, I don't expect that to be the case in all situations. This is why I laid out both Javascript functions. I expect that the Row Number may depend upon your specific scenario for the Kendo grid.