Preserving state of the data grid through navigations

In my UI I have several data grids that contain a lot of data, guaranteeing that a user will use filters, paging and sorting to find their interesting row.
They can then navigate to a detail page, which is a separate Blazor page and URL.
Pressing back on the browser, or a page button which calls history.back(); navigates back to the list/grid page.
However at the moment the state of filtering/sorting/paging is lost, which is quite annoying.
Is there a built in or programmatic way so that when pressing Back the grid state will be as the user left it?

1 Like

Hi!

I've just figured out how to do it (maybe not the cleanest or most straight-forward implementation, but it works):

@page "/Entity"

@inject DigitalGateway.Services.ICalendarService CalendarService;
@inject DigitalGateway.Services.IAzureService AzureService;
@inject NavigationManager NavigationManager;
@inject ProtectedSessionStorage storage;
@using System.Linq.Dynamic.Core;
@using Serilog;
@using System.Text.Json;

<h1>Entities</h1>

<RadzenDataGrid @ref="gridEntities" AllowFiltering="true" AllowColumnResize="true" FilterMode="FilterMode.Simple" PageSizeOptions="@pageSizeOptions" PagerPosition="PagerPosition.TopAndBottom" AllowPaging="true" AllowSorting="true"
				Data="@_entities" LoadData="@LoadData" Count="@count" TItem="Entities.Entity" LogicalFilterOperator="LogicalFilterOperator.And" EditMode="DataGridEditMode.Single" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive">
	<Columns>
		<RadzenDataGridColumn TItem="Entities.Entity" Property="ExtractConfig.ExtractName" Title="Extract Name" TextAlign="TextAlign.Left" FilterProperty="ExtractConfig.ExtractName" />
		<RadzenDataGridColumn TItem="Entities.Entity" Property="EntityName" Title="Entity Name" />
		<RadzenDataGridColumn TItem="Entities.Entity" Property="DGEntityId" Title="DG Entity ID" />
		<RadzenDataGridColumn TItem="Entities.Entity" Property="ExcludedFromExtract" Title="Excluded from Extract" TextAlign="TextAlign.Center">
			<Template Context="entity">
				<RadzenCheckBox id="ExcludedFromExtract" TValue="bool" Value="@entity.ExcludedFromExtract" Change=@(args => CheckChanged(args,entity.Id)) />
			</Template>
		</RadzenDataGridColumn>
		<RadzenDataGridColumn TItem="Entities.Entity" Property="AssignedToGroup" Title="Assigned To Group" />
		<RadzenDataGridColumn Width="200px" TItem="Entities.Entity" Property="Id">
			<Template Context="entity">
				<RadzenButton ButtonStyle="ButtonStyle.Light" Click=@(() => EditEntity(entity.Id.ToString())) Text="Edit" />
			</Template>
		</RadzenDataGridColumn>
	</Columns>
</RadzenDataGrid>
<br />


@code {
	private IEnumerable<Entities.Entity> _entities;
	IEnumerable<int> pageSizeOptions = new int[] { 10, 20, 50, 100 };
	RadzenDataGrid<Entities.Entity> gridEntities;
	string sessionquery;
	int count = 0;


	protected override async Task OnAfterRenderAsync(bool firstRender)
	{
		if (firstRender)
		{
			await GetSessionValues();
			StateHasChanged();
		}
		await base.OnAfterRenderAsync(firstRender);
	}

	private void EditEntity(string entityId)
	{
		NavigationManager.NavigateTo($"EntityEdit/{entityId}");
	}

	private async Task GetSessionValues()
	{
		var result = await storage.GetAsync<string>("gridEntity");
		sessionquery = result.Success ? result.Value : "";
		if (!string.IsNullOrEmpty(result.Value))
		{

			var elems = JsonSerializer.Deserialize<IEnumerable<Tuple<string, string>>>(result.Value);
			foreach (var elem in elems)
			{
				var column = this.gridEntities.ColumnsCollection.FirstOrDefault(x => x.Property.Equals(elem.Item1));
				if (column != null)
				{
					column.FilterValue = elem.Item2;
				}
			}
			this.gridEntities.Reload();


		}
	}

	async Task LoadData(LoadDataArgs args)
	{

		var query = CalendarService.GetEntitiesAsQueryable();

		if (!string.IsNullOrEmpty(args.Filter))
		{
			query = query.Where(args.Filter);
		}

		var filterValues = args.Filters.Where(x => x.FilterValue != null).Select(x => new { Property = x.Property, FilterValue = x.FilterValue }).AsEnumerable().Select(c => new Tuple<string, string>(c.Property, c.FilterValue.ToString())).ToList();

		if (filterValues.Any())
			await storage.SetAsync("gridEntity", JsonSerializer.Serialize(filterValues));
		count = query.Count();
		_entities = query.Skip(args.Skip.Value).Take(args.Top.Value).ToList();
	}

	private async Task CheckChanged(bool? selected, int id)
	{

		CalendarService.UpdateEntitySetup(id, selected.Value);
		//await gridEntities.Reload();
		_entities = await Task.Run(() => CalendarService.GetEntities()).ConfigureAwait(true);
	}

}


2 Likes

... this is what I need. Thanks :sunflower:.

Now I want to clean the filter.

My Question is in another Post. Sorry...
Please see here:
Clearing Filter Post

And one more Question:
Clearing the filter on INT Columns
I set the filter (1) column.FilterValue = elem.Item2;
My Gird is filtered. Now the User gos into the filtercell and deleted the number and pressed enter or leave the filtercell.

The grid set the number from the codeside setting filter (1) automatically and start a new search.
The user has no chance to reset or clean this filter :frowning: