Lose focus on control when grid rebind

1 Answer 416 Views
Grid
Yaël
Top achievements
Rank 1
Yaël asked on 24 Sep 2021, 02:47 PM

Hi,

I have a grid with an header context menu and control for filtering.
I'm refreshing the grid using a timer.

When the grid rebind, we lose the focus on a control. So when you want to filter by text or with a dropdown, you lose the focus. It's the same when the header context menu is open, after rebind it disappears.

Do you have a solution how to don't lose the focus or not rebind the grid when a control is focused ?

Thanks

1 Answer, 1 is accepted

Sort by
0
Attila Antal
Telerik team
answered on 29 Sep 2021, 09:21 AM

Hello Yaƫl,

Preventing a control from losing its focus upon PosBack is impossible. Even if AJAX is enabled, the partial PostBack request may not refresh the entire page, it will still refresh the element that was Ajaxified. This is a general behavior of ASP NET Web-based apps and Telerik Components are no exception for that.

What you can do, is to re-set the Focus after the PostBack is finished. In this case, re-opening the HeaderContextMenu.

Here is an example of Re-Opening the same HeaderContextMenu after applying the Filter.

1. Attach the ItemCommand event to the Grid.

2. In this event handler, you can write a condition that will only apply when filtering by the HeaderContextMenu.

protected void RadGrid1_ItemCommand(object sender, GridCommandEventArgs e)
{
    if (e.CommandName == RadGrid.HeaderContextMenuFilterCommandName)
    {
        var grid = (RadGrid)sender;

        var filterArgs = e.CommandArgument as Triplet;
        var filteredColumn = filterArgs.First.ToString();

        // prepare the Script with two parameters
        string scriptString = "Sys.Application.add_load(applicationLoadHandler); function applicationLoadHandler() {{ reOpenContextMenu('{0}', '{1}'); /* Sys.Application.remove_load(applicationLoadHandler);*/ }}";

        // pass the Grid's ClientID and ColumnUniqueName as parameters
        string formattedScript = string.Format(scriptString, grid.ClientID, filteredColumn);

        // Register a Startup script that will execute soon after the PostBack is over
        ScriptManager.RegisterStartupScript(Page, Page.GetType(), "ResetFocus", formattedScript, true);
    }
}

3. In the JavaScript function that will be executed upon loading the page, you can use the Grid's Client-Side APIs and re-open the ContextMenu for that specific column respectively.

<script type="text/javascript">
    function reOpenContextMenu(gridId, columnUniqueName) {
        var grid = $find(gridId); // find the Grid by ID
        var masterTable = grid.get_masterTableView(); // get reference to MasterTable
        var filteredColumn = masterTable.getColumnByUniqueName(columnUniqueName); // get reference to the Column by UniqueName
        filteredColumn.showHeaderMenu(); // show the HeaderContextMenu
    }
</script>

 

There is a conflict though. You mentioned that you have a Timer that refreshes the Grid, meaning that while users are trying to filter, at any moment this Timer might trigger the PostBack, and so, the Filter Menu will close. To avoid that, I suggest that you implement a Logic that will stop the timer for as long as the user is Using the HeaderContextMenu.

You can use the OnHeaderMenuShowing client-side event that will fire when the user opens the menu. Use this event handler to stop the timer. 

<script type="text/javascript">
    // When the Menu Opens
    function HeaderMenuShowing(sender, args) {
        // Attach the Menu hiding event
        sender.get_headerMenu().add_hiding(HeaderMenuHiding);

        // Write a code that will stop the timer here
    }

    // When the Menu Closes (needed if the User decides to close the menu without filtering)
    function HeaderMenuHiding(sender, args) {
        // Write a code that will restart/resume the timer here
    }
</script>

 

Let's assume the user has opened the Menu, the timer gets paused. Then the user makes a few choices and applies the filter. This will then cause the Grid to fire the HeaderContextMenuFilterCommand as I showed above. Use that opportunity to unpause/restart the Timer.

protected void RadGrid1_ItemCommand(object sender, GridCommandEventArgs e)
{
    if (e.CommandName == RadGrid.HeaderContextMenuFilterCommandName)
    {
        // Check if the Timer has been Paused, if so, resume it
    }
}

 

In case the user does not apply any filter and simply closes the FilterMenu, the Timer will be resumed as well since you will have a logic in the "HeaderMenuHiding" event handler to do so.

 

I'm afraid we do not have a solution to offer as this is not supported out of the box, however, I have shared a guide that you can follow and Implement the desired functionality.

 

Regards,
Attila Antal
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.

Tags
Grid
Asked by
Yaël
Top achievements
Rank 1
Answers by
Attila Antal
Telerik team
Share this question
or