change page and select row in Grid programmatically

When the grid is first shown it would be useful to select row which in mentioned in query string. It would be also helpful after edit, because edited row often fles to another page of the grid and it is not possible to view edit result.
I tried to realize this behavior this way, but failed:
            for (int i = 0; i < Grid.PageSettings.PageCount; i++)
           {
               for (int j = 0; j < Grid.PageSettings.PageSize; j++)
              { 
                 List<object> Rows = Grid.CurrentViewData.ToList();
                   if ((Rows[j] as T).GetPropertyValue(Key) == Value) { 
                       Grid.GoToPage(i);
                       Grid.SelectRow(j); 
                        return; 
                    }
                }
            }
Could offer any?

3 Replies

VN Vignesh Natarajan Syncfusion Team May 7, 2020 07:14 AM UTC

Hi Stanislav,  
 
Thanks for contacting Syncfusion support.  
 
Query: “When the grid is first shown it would be useful to select row which in mentioned in query string 
 
From your query we understand that you want to select a particular record from a Grid by navigating to its page. We have done some modification in your code example to achieve your requirement using GotoPage() and SelectRow() method of Grid along with DataBound event of the Grid. 
 
Refer the below code example.  
 
<SfGrid @ref="Grid" DataSource="@Orders" AllowPaging="true"> 
    <GridEvents DataBound="DataHandler" TValue="Order"></GridEvents> 
    <GridColumns> 
. . . . . . . . . 
    </GridColumns> 
</SfGrid> 
 
@code{ 
    SfGrid<Order> Grid { getset; } 
    public bool ContinuePaging = true; 
    public bool InitialRender { getset; } 
    public int Value = 1055; // consider that value your querystring contains 
    public List<Order> Orders { getset; } 
    public async Task DataHandler() 
    { 
        if (InitialRender) // to handled during the initial rendering of Grid 
        { 
            InitialRender = false; 
            for (int i = 1; i <= Grid.PageSettings.PageCount; i++) 
            { 
                List<Order> Rows = await Grid.GetCurrentViewRecords(); // returns the current view data 
                for (int j = 0; j < Grid.PageSettings.PageSize; j++) 
                { 
                    if (Rows[j].OrderID == Value) 
                    { 
                        await Grid.SelectRow(j); 
                        ContinuePaging = false// prevent the default navigation 
                    } 
                } 
                if (ContinuePaging) 
                { 
                    await Grid.GoToPage(i + 1); // if current page does not contain the record navigate to next page.  
                } 
            } 
        } 
    } 
    protected override async Task OnAfterRenderAsync(bool firstRender) 
    { 
        if (firstRender) 
        { 
            InitialRender = true; 
        } 
    } 
} 
 
 
 
For your convenience we attached the sample which can be downloaded from below  
 
 
Refer our UG and API documentation for your reference 
 
 
Kindly get back to us if you have further queries.   
 
Regards, 
Vignesh Natarajan 
 



SG Stanislav Gordenko May 8, 2020 12:33 PM UTC

Your recommendation works well on initial render and after edit when row stays on current page or moves to last page direction. If row moves to fist page direction, it is not work. I have modified your method this way:

public static async Task SelectRow<T>(this SfGrid<T> Grid, string Key, object Value) where T: class
        {
            if (Grid == null) throw new ArgumentNullException(nameof(Grid));
            if (Key == null || Value == null) return;
            List<T> Rows = await Grid.GetCurrentViewRecords().ConfigureAwait(false);
            int Page = Grid.PageSettings.CurrentPage;
            int i = 0;
            while (i <= Grid.PageSettings.PageCount && Rows.Count > 0)
            {
                for (int j = 0; j < Rows.Count; j++)
                {
                    string itemValue;
                    if (typeof(T) == typeof(ExpandoObject))
                    {
                        itemValue = (Rows[j] as IDictionary<string, object>).ContainsKey(Key) ? (Rows[j] as IDictionary<string, object>)[Key]?.ToString() : null;
                    }
                    else
                    {
                        itemValue = (Rows[j] as T).GetPropertyValue(Key)?.ToString();
                    }
                    if (itemValue != null && itemValue == Value.ToString())
                    {
                        await Grid.SelectRow(j).ConfigureAwait(false);
                        return;
                    }
                }
                i++;
                try
                {
                    await Grid.GoToPage(i).ConfigureAwait(true);
                }
                catch
                { 
                    goto CancelSelection;
                }
                Rows = await Grid.GetCurrentViewRecords().ConfigureAwait(false); 
            } 
            CancelSelection: await Grid.SelectRow(-1).ConfigureAwait(false);
            await Grid.GoToPage(Page).ConfigureAwait(false);  
        }

and use it this way:

protected void ActionBegin(ActionEventArgs<Constant> args)
    {
        if (args.RequestType == Syncfusion.Blazor.Grids.Action.Save) SelectedKey = args.Data?.Key;
    }

    protected async Task ActionComplete(ActionEventArgs<Constant> args)
    {
        if (args.RequestType == Syncfusion.Blazor.Grids.Action.Add)
        {
            ToastService.ShowToast(StringLocalizer["New row is added."], ToastLevel.Success);
        }
        else if (args.RequestType == Syncfusion.Blazor.Grids.Action.Save)
        {   
            if (args.Action == DbManager.Add)
            {
                ToastService.ShowToast(StringLocalizer["Row {0} is added.", args.Data?.Key], ToastLevel.Success);
                await Grid.SelectRow(nameof(Constant.Key), args.Data?.Key).ConfigureAwait(false);
            }
            else if (args.Action == DbManager.Edit)
            {
                ToastService.ShowToast(StringLocalizer["Row {0} is updated.", SelectedKey], ToastLevel.Success);
                await Grid.SelectRow(nameof(Constant.Key), SelectedKey).ConfigureAwait(false);
            }
        }
        else if (args.RequestType == Syncfusion.Blazor.Grids.Action.Delete)
        {
            ToastService.ShowToast(StringLocalizer["Row {0} is deleted.", args.Data?.Key], ToastLevel.Warning);
            await Grid.SelectRow(-1).ConfigureAwait(false);
        }
        await InvokeAsync(StateHasChanged);
    }

this method start search from current page, and when it try to go to first page something goes not well. 
Additionally. Page count starts from 1, not from 0, but what is the maximum page number? Grid.PageSettings.PageCount is much higher than real number.



VN Vignesh Natarajan Syncfusion Team May 11, 2020 08:20 AM UTC

Hi Stanislav,  
 
Thanks for the update.  
 
Query: “If row moves to fist page direction, it is not work. 
 
We are able to reproduce the reported behavior at our end with the provided solution. Now we have modified the solution to navigate to required page and select records from any page. Refer the below modified code example.  
 
<SfButton OnClick="DataHandler" Content="Navigate"></SfButton> 
  
<SfGrid @ref="Grid" DataSource="@Orders" AllowPaging="true"> 
    . . . . . .. .  
</SfGrid> 
  
@code{ 
    SfGrid<Order> Grid { getset; } 
    public bool ContinuePaging = true; 
    public bool InitialRender { getset; } 
    public int Value = 1015; // consider that value your querystring contains 
    public List<Order> Orders { getset; } 
    public async Task DataHandler() 
    { 
        ContinuePaging = true; 
        var CurrentPage = Grid.PageSettings.CurrentPage; 
        await Grid.GoToPage(CurrentPage); 
        var PageCount = Grid.PageSettings.PageCount - 1; 
        for (int i = 1; i <= PageCount; i++) 
        { 
            List<Order> Rows = await Grid.GetCurrentViewRecords(); // returns the current view data 
            for (int j = 0; j < Grid.PageSettings.PageSize; j++) 
            { 
                if (j < Rows.Count && Rows[j].OrderID == Value) 
                { 
                    await Grid.SelectRow(j); 
                    ContinuePaging = false// prevent the default navigation 
                    break; 
                } 
            } 
            if (ContinuePaging) 
            { 
                if (i >= PageCount) 
                { 
                    i = 0; 
                } 
                await Grid.GoToPage(i + 1); 
                await Task.Delay(200);  
            } 
        } 
    } 
} 
 
 
Note: we have calculated on number less than the current PageCount. 
 
Refer the modified sample from below  
 
 
Kindly get back to us if you have further queries.   
 
Regards, 
Vignesh Natarajan 


Loader.
Up arrow icon