Asp.Net Core, Grid, HtmlHelper, scroll grid column into view using the title or index of the column as a reference

1 Answer 102 Views
Grid
Trent
Top achievements
Rank 1
Trent asked on 02 Dec 2023, 12:53 AM | edited on 04 Dec 2023, 01:23 AM

My customer has an obnoxiously wide grid (~200 columns) which introduces the need to allow them to pick a Grid Column Title from a droplist (of all column titles) so that we can auto scroll the select grid into view.  I have tried to follow several other examples like this

https://docs.telerik.com/kendo-ui/knowledge-base/grid-scroll-to-last-column

but the offset() and .let seem to now work for core.

This is the closest that I have found but I cannot get it to work, either

Thanks!

Sample Code

<button onclick="jumpToColumn();">Jump</button>
<input type="text" id="jumpToColumnName" name="jumpToColumnName">
<br>
<br>


@(Html.Kendo().Grid<OrderViewModel>
                                ().Name("grid")
                                .Groupable()
                                .Sortable()
                                .Editable()
                                .Scrollable()
                                .ToolBar(x => x.Create())
                                .Columns(columns =>
                                {
                                    columns.Bound(column => column.Freight);
                                    columns.Bound(column => column.ShipName);
                                    columns.Bound(column => column.ShipCity);
                                    columns.Template("1").Title("Sh1").Width(200);
                                    columns.Template("2").Title("Sh2").Width(200);
                                    columns.Template("3").Title("Sh3").Width(200);
                                    columns.Template("4").Title("Sh4").Width(200);
                                    columns.Template("5").Title("Sh5").Width(200);
                                    columns.Template("6").Title("Sh6").Width(200);
                                    columns.Template("7").Title("Sh7").Width(200);
                                    columns.Template("8").Title("Sh8").Width(200);
                                    columns.Template("9").Title("Sh9").Width(200);
                                    columns.Template("10").Title("Sh10").Width(200);
                                    columns.Template("11").Title("Sh11").Width(200);
                                    columns.Template("12").Title("Sh12").Width(200);
                                    columns.Template("13").Title("Sh13").Width(200);
                                    columns.Template("14").Title("Sh14").Width(200);
                                    columns.Template("15").Title("Sh15").Width(200);
                                    columns.Template("16").Title("Sh16").Width(200);
                                    columns.Template("17").Title("Sh17").Width(200);
                                    columns.Template("18").Title("Sh18").Width(200);
                                    columns.Template("19").Title("Sh19").Width(200);
                                    columns.Template("20").Title("Sh20").Width(200);
                                    columns.Template("21").Title("Sh21").Width(200);
                                    columns.Template("22").Title("Sh22").Width(200);
                                    columns.Template("23").Title("Sh23").Width(200);

                                    columns.Command(column =>
                                    {
                                        column.Edit();
                                        column.Destroy();
                                    }).Width(230);
                                })
                                .DataSource(ds => ds.Ajax()
                                .Read(r => r.Url("/Index?handler=Read").Data("forgeryToken"))
                                .Update(u => u.Url("/Index?handler=Update").Data("forgeryToken"))
                                .Create(c => c.Url("/Index?handler=Create").Data("forgeryToken"))
                                .Destroy(d => d.Url("/Index?handler=Destroy").Data("forgeryToken"))
                                .Model(m => m.Id(id => id.OrderID))
                                .PageSize(10)
                                )
                                .Pageable()
                                .Selectable()
)

<script type="text/javascript">

    function jumpToColumn() {
        let columnTitle = 'sh11';   //$("#jumpToColumnName").val();

        var grid = $("#grid").data().kendoGrid;
        let headerColumnTitleSelector = "th[data-field='" + columnTitle + "']";            //"th[data-title='" + columnTitle + "']";
        let column = $(headerColumnTitleSelector);
        let columnOffset = column.offset();                 // returns undefined
        let lastColumnOffset = columnOffset.left;       // exception because of the previous line

       // This scrolls the scrollbar but does NOT scroll the content

        grid.content.scrollLeft(lastColumnOffset);

    }

 

</script>

1 Answer, 1 is accepted

Sort by
0
Mihaela
Telerik team
answered on 06 Dec 2023, 03:39 PM

Hello Trent,

Thank you for sharing the code snippets.

I examined them, and I would suggest the following approach:

<script type="text/javascript">
    function jumpToColumn() {
        let columnTitle = 'Sh11'; //Ensure that the Title() of the target column is added correctly
        var grid = $("#grid").data().kendoGrid;
        var scrollContentOffset = $("#grid").find(".k-grid-content").offset().left;
        var targetContentOffset = $("th[data-title='" + columnTitle + "']").offset().left; // Get the offset to column with title "Sh11"
        var distance = targetContentOffset - scrollContentOffset; //Calculate the scroll distance

        $("#grid").find(".k-grid-content").animate({ //Scroll to column with title "Sh11"
            scrollLeft: distance
        }, 400);
    }
</script>

Here is a REPL sample for your reference:

https://netcorerepl.telerik.com/mdlGOAbT38iQwVQv40

I hope that helps.

 

Regards,
Mihaela
Progress Telerik

Stay tuned by visiting our public roadmap and feedback portal pages. If you're new to the Telerik family, be sure to check out our getting started resources, as well as the only REPL playground for creating, saving, running, and sharing server-side code.
Trent
Top achievements
Rank 1
commented on 07 Dec 2023, 11:49 PM

You, my friend, are truly Awesome!!  That worked perfectly. Thank you.
Trent
Top achievements
Rank 1
commented on 08 Dec 2023, 01:53 AM

I'll figure this out so don't worry about looking at it but...

One interesting aspect of this offset scroll functionality (and this may or may not be a defect)

  1. Change the columnTitle to what I have below. 
  2. Enter a column Name in the TextBox
  3. Click <Jump>
  4. The scrollbar jumps to the correct column.
  5. Click <Jump> again with the same value (or a new value)
  6. The content scrolls all the way back to the left (sometimes to Column 2)
  7.  Click <Jump> again and then scrollbar scrolls to the correct column

First call with "Sh7" selected

scrollContentOffset:     285.1171875
targetContentOffset:   1285.1171875
distance:                        1000

localhost/:1 Uncaught (in promise) Error: A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received

Second call with "Sh7" Selected

scrollContentOffset:     285.1171875
targetContentOffset:   485.1171875
distance:                        200

 

    function jumpToColumn() {
        let columnTitle = $("#jumpToColumnName").val(); // <=====
        var grid = $("#grid").data().kendoGrid;
        var scrollContentOffset = $("#grid").find(".k-grid-content").offset().left;
        var targetContentOffset = $("th[data-title='" + columnTitle + "']").offset().left;
        var distance = targetContentOffset - scrollContentOffset; //Calculate the scroll distance
        $("#grid").find(".k-grid-content").animate({ //Scroll to column with title "Sh11"
            scrollLeft: distance
        }, 400);
    }
Trent
Top achievements
Rank 1
commented on 08 Dec 2023, 03:26 AM | edited

Nothing elegant, and there is probably a lot of better ways to code this, but it works every time.

 

    function getJumpToPosition(columnTitle) {
        let grid = $("#gridHtmlHelper").data("kendoGrid");
        let columns = grid.columns;
        let cells = grid.thead[0].rows[0].cells;

        if (columns === 'undefined' || columns.length < 0)
            return 0;

        for (var columnIndex = 0; columnIndex < columns.length; columnIndex++)
        {
            if (columns[columnIndex].hidden !== true && (columns[columnIndex].title === columnTitle || columns[columnIndex].columnField === columnTitle))
                return cells[columnIndex].offsetLeft;
        }
    }

    function jumpToColumn(columnTitle) {
        if (columnTitle === 'undefined')
            return;

        let grid = $("#gridHtmlHelper").data().kendoGrid;
        if (grid === 'undefined')
            return;

        let calculatedOffsetPosition = getJumpToPosition(columnTitle);

        // Scroll to column with title "Sh11"
        $("#gridHtmlHelper").find(".k-grid-content").animate(
            {
                scrollLeft: calculatedOffsetPosition
            }, 400);
    }
Mihaela
Telerik team
commented on 11 Dec 2023, 05:18 PM

Hey Trent.

Thank you for sharing your solution that handles all cases. It is greatly appreciated!

Tags
Grid
Asked by
Trent
Top achievements
Rank 1
Answers by
Mihaela
Telerik team
Share this question
or