Skip to content

fix: Columns appears conditionally shift data to header in DataGrid #3178

@nvangnoob

Description

@nvangnoob

🐛 Bug Report

Making the columns appear conditionally using Razor logic @if removes the column but causes the data grid to shift data to the header.

💻 Repro or Code Sample

@using Microsoft.FluentUI.AspNetCore.Components

@inject HttpClient Http
@inject NavigationManager NavManager

<p>
    Show:
    <FluentCheckbox @bind-Value="showCity">City</FluentCheckbox>
    <FluentCheckbox @bind-Value="showState">State</FluentCheckbox>
</p>

<div style="height: 434px; overflow:auto;" tabindex="-1">
    <FluentDataGrid ItemsProvider="foodRecallProvider"
                    TGridItem="FoodRecall"
                    GenerateHeader="GenerateHeaderOption.Sticky"
                    ResizableColumns="true"
                    ResizeType="DataGridResizeType.Discrete"
                    HeaderCellAsButtonWithMenu="true"
                    Pagination="@_pagination"
                    ShowHover="true">
        <ChildContent>
            <SelectColumn TGridItem="FoodRecall"
                          SelectMode="DataGridSelectMode.Multiple"
                          SelectFromEntireRow="true"
                          Property="@(e => e.Selected)" />
            <TemplateColumn Width="80px" Title="View" Align="@Align.Start">
                <FluentButton aria-label="View Document" IconEnd="@(new Icons.Regular.Size16.Eye())" />
            </TemplateColumn>
            <PropertyColumn Title="ID" Property="@(c => c!.Event_Id)" />
            @if (showState)
            {
                <PropertyColumn Property="@(c => c!.State)" Style="color: #af5f00 ;" />
            }
            @if (showCity)
            {
                <PropertyColumn Property="@(c => c!.City)" />
            }
            <PropertyColumn Title="Company" Property="@(c => c!.Recalling_Firm)" Tooltip="true" />
            <PropertyColumn Property="@(c => c!.Status)" />
            <TemplateColumn Title="Actions" Align="@Align.End">
                <FluentButton aria-label="Edit item" IconEnd="@(new Icons.Regular.Size16.Edit())" />
                <FluentButton aria-label="Delete item" IconEnd="@(new Icons.Regular.Size16.Delete())" />
            </TemplateColumn>
        </ChildContent>
        <EmptyContent>
            <FluentIcon Value="@(new Icons.Filled.Size24.Document())" Color="@Color.Accent" />&nbsp; No results to display.
        </EmptyContent>
        <LoadingContent>
            <FluentStack Orientation="Orientation.Vertical" HorizontalAlignment="HorizontalAlignment.Center">
                Loading...<br />
                <FluentProgress Width="240px" />
            </FluentStack>
        </LoadingContent>
    </FluentDataGrid>
</div>

<FluentPaginator State="@_pagination">
    <SummaryTemplate>
        <strong>@(_pagination.TotalItemCount ?? 0)</strong> records found.
    </SummaryTemplate>
</FluentPaginator>



@code {
    PaginationState _pagination = new PaginationState { ItemsPerPage = 25 };
    bool showCity = true;
    bool showState = true;

    GridItemsProvider<FoodRecall> foodRecallProvider = default!;
    int? numResults;

    protected override async Task OnInitializedAsync()
    {
        // Define the GridRowsDataProvider. Its job is to convert QuickGrid's GridRowsDataProviderRequest into a query against
        // an arbitrary data soure. In this example, we need to translate query parameters into the particular URL format
        // supported by the external JSON API. It's only possible to perform whatever sorting/filtering/etc is supported
        // by the external API.
        foodRecallProvider = async req =>
        {
            var url = NavManager.GetUriWithQueryParameters("https://api.fda.gov/food/enforcement.json", new Dictionary<string, object?>
                            {
                { "skip", req.StartIndex },
                { "limit", req.Count },
                            });

            var response = await Http.GetFromJsonAsync<FoodRecallQueryResult>(url, req.CancellationToken);

            // Simulate a slow data retrieval process
            if (req.Count is null)
            {
                await Task.Delay(2500);
            }

            return GridItemsProviderResult.From(
                items: response!.Results,
                totalItemCount: response!.Meta.Results.Total);
        };

        // Display the number of results just for information. This is completely separate from the grid.
        numResults = (await Http.GetFromJsonAsync<FoodRecallQueryResult>("https://api.fda.gov/food/enforcement.json"))!.Meta.Results.Total;
    }

    // Represents the data returned by https://open.fda.gov/apis/food/enforcement/
    // This is a subset of the fields available on that API
    public class FoodRecall
    {
        public string Event_Id { get; set; }
        public string Status { get; set; }
        public string City { get; set; }
        public string State { get; set; }
        public string Recalling_Firm { get; set; }
        public bool Selected { get; set; }
    }

    public class FoodRecallQueryResult
    {
        public Metadata Meta { get; set; }
        public FoodRecall[] Results { get; set; }

        public class Metadata
        {
            public ResultsInfo Results { get; set; }
        }

        public class ResultsInfo
        {
            public int Total { get; set; }
        }
    }
}

🤔 Expected Behavior

Data should not shift when column is removed like in the example https://www.fluentui-blazor.net/DataGrid#dynamiccolumns

😯 Current Behavior

The column is removed but the data shifts to the header.

Image

💁 Possible Solution

Column should be removed, and data should not shift.

🔦 Context

Allow users to hide any columns they do not want to see when there are multiples columns.

🌍 Your Environment

  • OS & Device: Windows 11
  • Browser: Edge
  • .NET 8 and Fluent UI Blazor library V4.11.3

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions