Grid Refresh State

Hi team,
We would like to know the best approach to perform Grid.Refresh() and keeping the row and row template detail opened as it was before invoking the Refresh() method.
What is happening is that every time we invoke the Refresh() button in order to go to the back-end to retrieve fresh data, the elements that were opened(DetailTemplate)  or selected (Row checkbox) are not holding their previous state.

Any help will be appreciated.
Thanks 

7 Replies

RN Rahul Narayanasamy Syncfusion Team March 27, 2020 11:13 AM UTC

Hi Ernesto, 
 
Greetings from Syncfusion. 
 
Query: Grid Refresh State 
 
We have validated your query and you want to maintain the selected row of the Grid while refreshing the Grid. You can achieve your requirement(maintain the selected row of the Grid) by using EnablePersistance feature of the Grid and PersistSelection property of SelectionSettings. Find the below code snippets and sample for your reference. 
 
. . . 
 
<SfButton OnClick="Refresh" CssClass="e-primary" Content="Refresh"></SfButton> 
 
<SfGrid ID="Grid" @ref="DefaultGrid" AllowSelection="true" EnablePersistence="true" DataSource="@Employees" Height="315px"> 
    <GridSelectionSettings Type="SelectionType.Multiple" PersistSelection="true"></GridSelectionSettings> 
    . . . 
        <GridColumn Type="ColumnType.CheckBox" Width="50"></GridColumn> 
        <GridColumn Field=@nameof(EmployeeData.EmployeeID) HeaderText="EmployeeID" IsPrimaryKey="true" Width="110"></GridColumn> 
        . . . 
    </GridColumns> 
</SfGrid> 
 
@code{ 
    . . . 
    public void Refresh() 
    { 
        this.DefaultGrid.Refresh(); 
    } 
} 
 
 
Also you want to maintain the DetaillTemplate state while refreshing the Grid. We can able to  achieve your requirement using JavaScript function. We use JSInterop support of Microsoft to call a JavaScript function from server and perform the action in JS function.   
 
So kindly confirm whether it is fine for you to achieve you requirement using Microsoft.JsInterop. Based on your confirmation, we will prepare the solution and update you the sample.    
 
Regards, 
Rahul 



EL Ernesto Leyva March 27, 2020 01:04 PM UTC

Hi Rahul,
I'm already using the options "EnablePersistence" and "PersistSelection" and I was able to figure that the selected row persist, however the detail template get closed.
To accomplish that one I would like to have an example using "Microsoft.JsInterop".
Thanks



RN Rahul Narayanasamy Syncfusion Team March 30, 2020 01:04 PM UTC

Hi Ernesto, 

Thanks for the update. 

Query: however the detail template get closed. To accomplish that one I would like to have an example using "Microsoft.JsInterop". 

Based on your requirement, we have prepared a sample. Find the sample in below link. 


In the above sample we will be refreshing the Grid in a Button click event. So before refreshing the Grid in Button click event, we will be fetching the expanded detailrow’s details by calling a JS method(getExpandedRow) and store the details of the row in rowInfo variable. Now the expanded row’s detail is stored in the rowInfo variable before refreshing the Grid. Now after refreshing the Grid, the DataBound event of Grid will be triggered. In this event handler, we suggest you to call the JavaScript method(expandDetailRow). In this method, we will be calling the expand method of Grid’s detailRowModule to expand the detailrows by passing the index value from the previously stored rowInfo variable.  

Please refer the code below,  

  
<Syncfusion.Blazor.Buttons.SfButton @onclick="onclick">Refresh</Syncfusion.Blazor.Buttons.SfButton>  
  
            <SfGrid ID="ParentGrid" @ref="GridInstance" DataSource="@Employees">  
                <GridEvents DataBound="DataBound" TValue="EmployeeData"></GridEvents>  
                <GridTemplates>  
                    <DetailTemplate>  
                        ...  
                   </DetailTemplate>  
                </GridTemplates>  
                ...  
           </SfGrid>  
  
@code{  
    SfGrid<EmployeeData> GridInstance;  
  
    public void DataBound()  
    {  
        JsRuntime.InvokeAsync<object>("expandDetailRow");  
    }  
    public void onclick()  
    {  
        JsRuntime.InvokeAsync<object>("getExpandedRow");  
        GridInstance.Refresh();  
    }  
    ...  
}  
 
[expandscript.js]  
 
var rowInfo = [];  
  
function expandDetailRow() {  
    var gridObj = document.getElementById("ParentGrid").ej2_instances[0];  
    if (rowInfo.length) {  
        for (var j = 0; j < rowInfo.length; j++) {  
            var rowIndex = parseInt(rowInfo[j].getAttribute("aria-rowindex"));          //fetch the row index from aria-rowindex attribute  
            gridObj.detailRowModule.expand(rowIndex);            //use the row index to expand the detailrow  
        }  
    }   
}  
  
function getExpandedRow() {  
    rowInfo = [];  
    var detailrows = document.getElementById("ParentGrid").querySelectorAll(".e-detailrowexpand");    //fetch the expanded row details  
    for (var i = 0; i < detailrows.length; i++) {  
        rowInfo.push(sf.grids.parentsUntil(detailrows[i],"e-row"));                 //store the details in rowInfo variable  
    }  
}  

Please get back to us if you need further assistance.  

Regards, 
Rahul 



BA BAx June 9, 2021 01:32 AM UTC

Hello, 
Can you please confirm the example provided works with the latest version of the component?
When I try in my solution I don't seem to have any sf.grids available.

Thank you,

A.


RN Rahul Narayanasamy Syncfusion Team June 9, 2021 01:02 PM UTC

Hi BAx, 

Greetings from Syncfusion. 
 
Query: need to open the previously opened detail template while refreshing the Grid 

We have validated your query and we have created a sample based on your requirement in latest version. We suggest you to call the DetailExpandCollapseRow method of Grid in the DataBound event handler to persist the expanded rows. In the below code, we have fetched the expanded row details and added to a dictionary in DetailDataBound event. And used Microsoft JSInterop to remove the collapsed rows from the ExpandedRows dictionary value.  
 
Please refer the codes below, 

 
@using Syncfusion.Blazor.Grids 
@using Syncfusion.Blazor.Data 
@inject IJSRuntime Runtime 
@using Syncfusion.Blazor.Buttons 
 
 
<SfButton OnClick="OnClick">Refresh Grid</SfButton> 
 
<SfGrid @ref="Grid" DataSource="@Employees" Height="315px"> 
    <GridEvents DetailDataBound="DetailDataBound" DataBound="DataBound" TValue="EmployeeData"></GridEvents> 
    <GridTemplates> 
        <DetailTemplate> 
            @{ 
                var employee = (context as EmployeeData); 
                <SfGrid DataSource="@Orders" Query="@(new Query().Where("EmployeeID", "equal", employee.EmployeeID))"> 
                    <GridColumns> 
                        . ..  
                    </GridColumns> 
                </SfGrid> 
            } 
        </DetailTemplate> 
    </GridTemplates> 
    <GridColumns> 
        <GridColumn Field=@nameof(EmployeeData.EmployeeID) IsPrimaryKey="true" HeaderText="First Name" Width="110"> </GridColumn> 
        . ..  
    </GridColumns> 
</SfGrid> 
 
@code{ 
    SfGrid<EmployeeData> Grid; 
    . ..  
    public bool firstrender { get; set; } = true; 
    public async Task DataBound() 
    { 
        if (firstrender) 
        { 
            var dotNetReference = DotNetObjectReference.Create(this);          // create dotnet ref 
            await Runtime.InvokeAsync<string>("detail", dotNetReference);     // send the dotnet ref to JS side 
            firstrender = false; 
        } 
 
        foreach (var a in ExpandedRows) 
        { 
            var PKIndex = await Grid.GetRowIndexByPrimaryKey(a.Key); 
            await Grid.DetailExpandCollapseRow((EmployeeData)Grid.CurrentViewData.ElementAt(Convert.ToInt32(PKIndex)));     //Expand the already expnaded detailrows 
        } 
    } 
    IDictionary<int, EmployeeData> ExpandedRows = new Dictionary<int, EmployeeData>(); 
    public void DetailDataBound(DetailDataBoundEventArgs<EmployeeData> args) 
    { 
        if (!ExpandedRows.ContainsKey(args.Data.EmployeeID)) 
        { 
            ExpandedRows.Add(args.Data.EmployeeID, args.Data);  //add the expanded rows to dictionary 
        } 
    } 
 
    [JSInvokable("DetailCollapse")]                            // method called from JS when collapse is done 
    public void DetailRowCollapse(string CollapseIndex) 
    { 
        EmployeeData CollapseRow = (EmployeeData)Grid.CurrentViewData.ElementAt(Convert.ToInt32(CollapseIndex)); 
        ExpandedRows.Remove(CollapseRow.EmployeeID);              //Remove the collapsed row from expanded dictionary 
    } 
 
    public void OnClick() 
    { 
        Grid.Refresh(); 
    } 
} 
 

[detailexpand.js] 
var dotnetInstance; function detail(dotnet) {    dotnetInstance = dotnet; // dotnet instance to invoke C# method from JS } document.addEventListener('click'function (args) {    if (args.target.classList.contains("e-dtdiagonaldown") || args.target.classList.contains("e-detailrowexpand")) {        dotnetInstance.invokeMethodAsync('DetailCollapse', args.target.closest("tr").getAttribute("aria-rowindex")); // call C# method from javascript function    }})
 


Reference

Please let us know if you have any concerns. 

Regards, 
Rahul 



BA BAx June 10, 2021 01:14 AM UTC

No concerns, it works really well.
Thank you


RN Rahul Narayanasamy Syncfusion Team June 10, 2021 05:20 AM UTC

Hi BAx, 

Thanks for the update. 

Please get back to us if you need further assistance. 

Regards, 
Rahul 


Loader.
Up arrow icon