MudBlazor / MudBlazor

Blazor Component Library based on Material design with an emphasis on ease of use. Mainly written in C# with Javascript kept to a bare minimum it empowers .NET developers to easily debug it if needed.
http://mudblazor.com
MIT License
8.17k stars 1.29k forks source link

MudDataGrid how do you fill container height so the vertical scroll is on grid data and not the page? #6477

Open PaulTodd opened 1 year ago

PaulTodd commented 1 year ago

Feature request type

Enhance component

Component name

MudDataGrid

Is your feature request related to a problem?

I would like to know if there is a way for the DataGrid to fill the height of the container it is in. I don't want to specify a static height like 600px and when I put 100%, the DataGrid shows every row with the scroll happening on the page level. I would like to use the grid in a MudPaper that is 100% height and have the vertical scroll bar appear on the table body if there are too many items to show.

Describe the solution you'd like

I would like the header and footer of the grid to snap to the container and the vertical scroll to be on the grid content.

Have you seen this feature anywhere else?

No response

Describe alternatives you've considered

No response

Pull Request

Code of Conduct

rzgthb commented 1 year ago

Hello @PaulTodd,

this happens because the "Height" attribute is applied to one of the inner divs of the DataGrid containing the table. Since the outer div containing the DataGrid does not have a height applied, the percentage has no effect. You can use the DataGrid atttribute to set the outer div's height in addition to the "Height"-attribute:

Style="height: 100%"

When you are using additional content in the table like ToolBarContent, now there is an additional issue: Since the additional content is not part of the table div, now the DataGrid's height is the height of the additional content + the height of the table (100% of the parent), resulting in two scrollbars.

For my use case, i solved this by omitting the "Height" attribute and setting the "Style" attribute of the DataGrid as follows:

Style="display: flex; flex-direction: column; height: 100%;"

Regards

PaulTodd commented 1 year ago

Thans for the help. I switched to the Class property: Class="d-flex flex-column mud-height-full pa-1">

gcooke commented 1 year ago

@PaulTodd I've been struggling with this for a while and neither the class or style approaches above have worked for me. I am using the MudDataGridPager which is not sitting at the bottom of the page.

Is your workaround working?

PaulTodd commented 1 year ago

I have not tried to use the pager. I figure users will filter results some and then just scroll down. I wish there were easier ways to make things stick in the browser view and anchor like in WinForms. Some screens I think are just more intuitive without scrolling the entire browser page.

A9G-Data-Droid commented 1 year ago

These solutions are not working for me either. I tried on just a MudDataGrid then I put it inside a MudPaper and tried layering the techniques in every which way. When I inspect, I can see the rows overflowing the bounds of their parent boxes. So I added overflow: scroll; to both the grid and the paper. No effect. This appears to be outside of my control.

Hiden46 commented 1 year ago

I have the same problem too, I can't make the table reflect the maximum height of the page.

A9G-Data-Droid commented 1 year ago

After struggling with manually applied style, as discussed earlier here, I found some MudDataGrid options that help.

<MudDataGrid 
    FixedHeader="true"                    @* Keep header while content scrolls *@
    Height="calc(100vh - 13rem);"         @* THIS IS THE KEY *@
>

Height="calc(100vh - 13rem);" This is what creates the desired behavior and could close this issue. I'm taking the view height minus the size of my header and page title. It's negative so if you want the table to be taller, reduce the 13rem to match your page.

EDIT: This should be noted somewhere in the documentation because this layout is the sane default I would use all the time. Seems like a common thing that new users will need to know.

esond commented 10 months ago

<MudDataGrid 
    FixedHeader="true"                    @* Keep header while content scrolls *@
    Height="calc(100vh - 13rem);"         @* THIS IS THE KEY *@
>

@A9G-Data-Droid This is the ticket. This works excellently with virtualization as well. Thank you very much!

kelltom commented 9 months ago

Unfortunately this isn't really a great solution when it comes to responsiveness with mobile. You'll still end up with inconsistent overflow.

svenskaskolan commented 7 months ago

Thanks for the solution idea, but as kelltom mentioned its never a good idea to hardcode such values. I guess you could have some script that calculates the header size in the dom, but that would also be a bit messy and would need to refresh the value if the page was resized etc.

A9G-Data-Droid commented 7 months ago

Those are the two settings you need. Declaring a height is what gets the behavior OP asked for. What you set your height to is an exercise for the reader. If you come up with a way to do it dynamically that works in all scenarios then issue a PR to add that feature to the data grid. There is plenty of interest in that feature.

brandonseydel commented 7 months ago

have a container div with flex

make the data grid flex flex-column with flex-fill 1 and min-height:0px; add full-height class for styling below and margin to keep off bottom

style the inner contents something like

.mud-table.full-height > .mud-table-container {
    min-height: 0px;
    flex-grow: 1;
}
   .mud-table.full-height >  .mud-table-pagination{
    overflow: visible;
}

works for all bps :)

RDUser-dev commented 6 months ago

I also had the same problem and as suggested by @brandonseydel the only solution that worked correctly for me was to use flexboxes https://try.mudblazor.com/snippet/wuGSYoHORmcQAlHF

foxy0669 commented 3 weeks ago

I've wasted hours on this. All parents of the grid were the correct height, but as soon as data was loaded the height was ignored. I only found having a fixed number of pixels worked. This is the solution I've just come up with

App.razor

        window.getElementHeight = (elementId) => {
            const element = document.getElementById(elementId);
            return element ? element.offsetHeight : 0;
        };

MyPage.razor

<div class="d-flex flex-column" style="height: calc(100vh - 64px)">
    <div class="flex-grow-0">
    <!-- header -->
    </div>

    <div id="gridParentDiv" class="flex-grow-1">
        <MudGrid Spacing="0" Style="height: 100%;">
            <MudItem xs="12" Class="mx-4 mt-2" Style="height: 100%">
                @if (transactions != null && transactions.Count > 0)
                {
                    <MudDataGrid T="TransactionModelWithInputs" MultiSelection="true" Items="@trans" Dense="true" SelectedItemsChanged="@SelectedItemsChanged"
                                 Class="px-4 pt-2" Height="@(gridHeight.ToString()+"px")" SelectOnRowClick=false Virtualize=true FixedHeader=true>
                        <Columns>
                        .
                        </Columns>
                    </MudDataGrid>
                }
            </MudItem>
        </MudGrid>
    </div>
    private async Task SetGridHeight()
    {
        gridHeight = await JSRuntime.InvokeAsync<int>("getElementHeight", "gridParentDiv");
        StateHasChanged();
    }

Just call the SetGridHeight in an appropriate place. I initially call it in OnAfterRenderAsync but then I had hide a div once I load data after user input which makes the grid higher so I call it again and it resizes.