Skip to main content
All docs
V25.1
  • DxPivotTable.LayoutAutoSaving Event

    Fires when the Pivot Table’s layout changes.

    Namespace: DevExpress.Blazor.PivotTable

    Assembly: DevExpress.Blazor.PivotTable.v25.1.dll

    NuGet Package: DevExpress.Blazor.PivotTable

    Declaration

    [Parameter]
    public Func<PivotTablePersistentLayoutEventArgs, Task> LayoutAutoSaving { get; set; }

    Parameters

    Type Description
    PivotTablePersistentLayoutEventArgs

    A PivotTablePersistentLayoutEventArgs object that defines data for this event.

    Remarks

    The Blazor Pivot Table allows you to save and restore its layout between application work sessions. The layout information includes settings that users can change: field settings (area, area index, sort order, visibility), filter criteria, expanded/collapsed state of rows and columns.

    Handle the LayoutAutoSaving event to save the Pivot Table’s layout when users change component UI characteristics mentioned above. As an alternative, call the SaveLayout() method to save the layout on demand (for example, on a button click).

    Use the PivotTable event argument and its members to obtain additional information about the Pivot Table. The Layout argument specifies the new Pivot Table layout. To restore the saved layout, pass a value of the Layout event argument to any of the following members:

    You can use the following approach to implement different default layouts for mobile and desktop devices:

    • Save layouts to a database instead of browser storage in the LayoutAutoSaving event handler.
    • In the LayoutAutoLoading event handler, use the DxLayoutBreakpoint component to load the layout based on the screen size.

    Example

    The following code snippet demonstrates how to implement layout persistence for a Pivot Table. When layout changes, the LayoutAutoSaving event handler saves the updated layout to the browser’s local storage. Once the page is reloaded or restored, the LayoutAutoLoading event handler loads the most recently saved layout from the local storage and applies it to the Pivot Table.

    @using System.Text.Json
    @inject NwindDataService NwindDataService
    @inject IJSRuntime JSRuntime
    <DxPivotTable @ref="@PivotTable"
                  Data="@PivotData"
                  VirtualScrollingEnabled="true"
                  LayoutAutoLoading="PivotTable_LayoutAutoLoading"
                  LayoutAutoSaving="PivotTable_LayoutAutoSaving">
        <Fields>
            <DxPivotTableField Field="SalesPerson" Area="PivotTableArea.Row" Caption="Sales Person" Width="270"/>
            <DxPivotTableField Field="ProductName" Area="PivotTableArea.Row" Caption="Product Name"/>
            <DxPivotTableField Field="ProductAmount" Area="PivotTableArea.Data" Caption="Product Amount" CellFormat="{0:c0}"/>
            <DxPivotTableField Field="Discount" Area="PivotTableArea.Data" CellFormat="{0:p0}"/>
            <DxPivotTableField Field="Country" AreaIndex="1"/>
            <DxPivotTableField Field="Region" AreaIndex="0"/>
            <DxPivotTableField Field="City" AreaIndex="-1"/>
            <DxPivotTableField Field="ExtendedPrice" AreaIndex="-1"/>
            <DxPivotTableField Field="OrderDate" GroupInterval="PivotTableGroupInterval.DateYear" Area="PivotTableArea.Column" Caption="Order Year" />
            <DxPivotTableField Field="OrderDate" GroupInterval="PivotTableGroupInterval.DateQuarter" Area="PivotTableArea.Column" Caption="Order Quater">
                <ValueTemplate>
                    <span>@($"Q{context.Text}")</span>
                </ValueTemplate>
            </DxPivotTableField>
        </Fields>
    </DxPivotTable>
    
    @code {
        const string LocalStorageKey = "PivotTable-LayoutPersistence-Data";
        object PivotData { get; set; }
        IPivotTable PivotTable { get; set; }
        bool PreRendered { get; set; }
        protected override void OnAfterRender(bool firstRender) {
            if(firstRender) {
                PreRendered = true;
                StateHasChanged();
            }
        }
        protected override async Task OnInitializedAsync() {
            var invoices = await NwindDataService.GetInvoicesAsync();
            var customers = await NwindDataService.GetCustomersAsync();
            var minDate = invoices.Min(i => i.OrderDate).GetValueOrDefault();
            var maxDate = invoices.Max(i => i.OrderDate).GetValueOrDefault();
            PivotData = invoices.Where(i => {
                var invoiceDate = i.OrderDate.GetValueOrDefault();
                return invoiceDate.Year > minDate.Year && invoiceDate.Year <= maxDate.Year;
            }).Join(customers, i => i.CustomerId, c => c.CustomerId, (i, c) => {
                return new {
                    CompanyName = c.CompanyName,
                    UnitPrice = i.UnitPrice,
                    OrderDate = i.OrderDate,
                    ProductName = i.ProductName,
                    ProductAmount = i.Quantity * i.UnitPrice,
                    Country = c.Country,
                    Region = c.Region,
                    ExtendedPrice = i.ExtendedPrice,
                    City = c.City,
                    Discount = i.Discount,
                    SalesPerson = i.Salesperson,
                };
            });
        }
        async Task PivotTable_LayoutAutoLoading(PivotTablePersistentLayoutEventArgs e) {
            e.Layout = await LoadLayoutFromLocalStorageAsync();
        }
        async Task PivotTable_LayoutAutoSaving(PivotTablePersistentLayoutEventArgs e) {
            await SaveLayoutToLocalStorageAsync(e.Layout);
        }
        // Refer to https://docs.microsoft.com/en-us/aspnet/core/blazor/state-management
        // to learn more about Blazor state management
        // In Blazor Server apps, prefer ASP.NET Core Protected Browser Storage
        async Task<PivotTablePersistentLayout> LoadLayoutFromLocalStorageAsync() {
            try {
                var json = await JSRuntime.InvokeAsync<string>("localStorage.getItem", LocalStorageKey);
                return JsonSerializer.Deserialize<PivotTablePersistentLayout>(json);
            } catch {
                // Mute exceptions for the server prerender stage
                return null;
            }
        }
        async Task SaveLayoutToLocalStorageAsync(PivotTablePersistentLayout layout) {
            try {
                var json = JsonSerializer.Serialize(layout);
                await JSRuntime.InvokeVoidAsync("localStorage.setItem", LocalStorageKey, json);
            } catch {
                // Mute exceptions for the server prerender stage
            }
        }
        async Task RemoveLayoutFromLocalStorageAsync() {
            try {
                await JSRuntime.InvokeVoidAsync("localStorage.removeItem", LocalStorageKey);
            } catch {
                // Mute exceptions for the server prerender stage
            }
        }
        async Task ReloadPageButton_ClickAsync() {
            await JSRuntime.InvokeVoidAsync("location.reload");
        }
        async Task ResetLayoutButton_ClickAsync() {
            await RemoveLayoutFromLocalStorageAsync();
            await JSRuntime.InvokeVoidAsync("location.reload");
        }
        void FieldListButton_Click() {
            PivotTable.ShowFieldList();
        }
    }
    

    DevExpress Blazor Pivot Table - Save and Restore Layout

    Run Demo: Save and Restore the Layout

    See Also