New to Telerik UI for Blazor? Download free 30-day trial

Save and Load the Splitter State

Environment

Product Splitter for Blazor

Description

I want to save the Splitter state when it is expanded or collapsed, and then automatically load it when the page is reloaded.

Solution

Implement this scenario in two steps:

Save the Splitter state

Handle the Splitter events to save its state in the LocalStorage when the user changes the component layout:

Load the Splitter state

Set the saved state from the browser local storage. It is important to perform this action in OnAfterRender(Async), as the component references are typically unavailable earlier. If you try setting the state in OnInitialized(Async), the Splitter reference may still be null.

The example below demonstrates the described approach.

@inject LocalStorage LocalStorage

<div style="width: 500px; height: 200px;">
    <TelerikSplitter @ref="@Splitter"
                     Width="100%"
                     Height="100%"
                     OnCollapse="@SaveStateToJson"
                     OnExpand="@SaveStateToJson"
                     OnResize="@SaveStateToJson">
        <SplitterPanes>
            <SplitterPane Size="200px" Collapsible="true">
                <div>pane 0</div>
            </SplitterPane>

            <SplitterPane Size="250px" Collapsible="true">
                <div>pane 1</div>
            </SplitterPane>

            <SplitterPane Collapsible="true">
                <div>pane 2</div>
            </SplitterPane>
        </SplitterPanes>
    </TelerikSplitter>
</div>

@code {
    const string SplitterStateKey = "SplitterStorageStateKey";
    TelerikSplitter Splitter { get; set; }

    async Task SaveStateToJson()
    {
        var state = Splitter.GetState();
        await LocalStorage.SetItem(SplitterStateKey, state);
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            var state = await LocalStorage.GetItem<SplitterState>(SplitterStateKey);
            if (state != null)
            {
                Splitter.SetState(state);
            }
        }
    }
}
using Microsoft.JSInterop;
using System.Text.Json;
using System.Threading.Tasks;

public class LocalStorage
{
    protected IJSRuntime JSRuntimeInstance { get; set; }

    public LocalStorage(IJSRuntime jsRuntime)
    {
        JSRuntimeInstance = jsRuntime;
    }

    public ValueTask SetItem(string key, object data)
    {
        return JSRuntimeInstance.InvokeVoidAsync(
            "localStorage.setItem",
            new object[] {
                key,
                JsonSerializer.Serialize(data)
            });
    }

    public async Task<T> GetItem<T>(string key)
    {
        var data = await JSRuntimeInstance.InvokeAsync<string>("localStorage.getItem", key);
        if (!string.IsNullOrEmpty(data))
        {
            return JsonSerializer.Deserialize<T>(data);
        }

        return default;
    }

    public ValueTask RemoveItem(string key)
    {
        return JSRuntimeInstance.InvokeVoidAsync("localStorage.removeItem", key);
    }
}
In this article