Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Popup errormessages hidden behind Input Controls in DataGrid InLine Editing when DataGridEditMode is Multiple #1917

Open
MartinStanz opened this issue Jan 21, 2025 · 0 comments

Comments

@MartinStanz
Copy link

Describe the bug
Popup errormessages from Validators are hidden behind the Dropdowns and DatePickers inputs (from the entries below) when using DataGrid InLine Editing in combiantion with DataGridEditMode.Multiple

To Reproduce
Steps to reproduce the behavior:

  1. Go to your own DataGrid InLine Editing Example: https://blazor.radzen.com/datagrid-inline-edit?theme=humanistic
  2. Click on "Edit Source" Tab and add a RadzenRequiredValidator to any RadzenDropDown and/or RadzenDatePicker (see full code at the end below)
    e.g. <RadzenDropDown @bind-Value="order.CustomerID" Data="@customers" TextProperty="@nameof(Customer.CompanyName)" ValueProperty="@nameof(Customer.CustomerID)" Style="width:100%; display: block;" InputAttributes="@(new Dictionary<string,object>(){ { "aria-label", "Select customer" }})" Name="CustomerDropdown" /> <RadzenRequiredValidator Text="CustomerDropdown is required" Component="CustomerDropdown" Popup="true" />
  3. Click on "Run"
  4. Go back to "Example" Tab
  5. Click "Multiple" right next to Edit Mode
  6. Click "Add new Order" 2 times
  7. Click the Green Check mark button (in the EditControlColumn) on the 2 newly created Rows (without entering any data)
  8. The Error Popups on the Dropdown and DatePicker are hidden by the Dropdown and DatePicker below

Expected behavior
The Popup error messages should not be hidden behind other Input Controls, they should be in front or even occupy their own space.

Screenshots
Image

Desktop (please complete the following information):

  • OS: Windows 11
  • Browser Google Chrome
  • Version 132.0.6834.84

Additional context
As seen in the Screenshot, this does not seem to affect the text inputs.
When there are no pre-existing entries, the error messages are hidden aswell and need to scroll down for (which may be an issue for itself?):
Image
Image

Full Code for step 2:

@using RadzenBlazorDemos.Data
@using RadzenBlazorDemos.Models.Northwind
@using Microsoft.EntityFrameworkCore

@inherits DbContextPage

<style>
    .rz-grid-table {
    width: unset;
    }
</style>

<RadzenCard Variant="Variant.Outlined" class="rz-my-4">
    <RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" Gap="0.5rem">
        <div>Edit Mode:</div>
        <RadzenSelectBar @bind-Value="@editMode" TextProperty="Text" ValueProperty="Value"
        Data="@(Enum.GetValues(typeof(DataGridEditMode)).Cast<DataGridEditMode>().Select(t => new { Text = $"{t}", Value = t }))" Size="ButtonSize.Small"
        Disabled="@(editMode == DataGridEditMode.Multiple && ordersToInsert.Count() > 1)" />
    </RadzenStack>
</RadzenCard>

<RadzenDataGrid @ref="ordersGrid" AllowAlternatingRows="false" AllowFiltering="true" AllowPaging="true" PageSize="5" AllowSorting="true" EditMode="@editMode"
Data="@orders" TItem="Order" RowUpdate="@OnUpdateRow" RowCreate="@OnCreateRow" Sort="@Reset" Page="@Reset" Filter="@Reset" ColumnWidth="200px">
    <HeaderTemplate>
        <RadzenButton ButtonStyle="ButtonStyle.Success" Icon="add_circle" Text="Add New Order" Click="@InsertRow" Disabled="@(editMode == DataGridEditMode.Single && ordersToInsert.Count() > 0)" />
    </HeaderTemplate>
    <Columns>
        <RadzenDataGridColumn Property="OrderID" Title="Order ID" Width="120px" Frozen="true" />
        <RadzenDataGridColumn Property="Customer.CompanyName" Title="Customer" Width="280px">
            <EditTemplate Context="order">
                <RadzenDropDown @bind-Value="order.CustomerID" Data="@customers" TextProperty="@nameof(Customer.CompanyName)" ValueProperty="@nameof(Customer.CustomerID)" Style="width:100%; display: block;"
                InputAttributes="@(new Dictionary<string,object>(){ { "aria-label", "Select customer" }})" Name="CustomerDropdown" />
                <RadzenRequiredValidator Text="CustomerDropdown is required" Component="CustomerDropdown" Popup="true" />
            </EditTemplate>
        </RadzenDataGridColumn>
        <RadzenDataGridColumn Property="Employee.LastName" Title="Employee" Width="220px">
            <Template Context="order">
                <RadzenImage Path="@order.Employee?.Photo" Style="width: 32px; height: 32px;" class="rz-border-radius-4 rz-me-2" AlternateText="@(order.Employee?.FirstName + " " + order.Employee?.LastName)" />
                @order.Employee?.FirstName @order.Employee?.LastName
            </Template>
            <EditTemplate Context="order">
                <RadzenDropDown @bind-Value="order.EmployeeID" Data="@employees" ValueProperty="EmployeeID" Style="width:100%; display: block;"
                InputAttributes="@(new Dictionary<string,object>(){ { "aria-label", "Select employee" }})">
                    <Template>
                        <RadzenImage Path="@context.Photo" Style="width: 20px; height: 20px;" class="rz-border-radius-4 rz-me-2" />
                        @context.FirstName @context.LastName
                    </Template>
                </RadzenDropDown>
            </EditTemplate>
        </RadzenDataGridColumn>
        <RadzenDataGridColumn Property="@nameof(Order.OrderDate)" Title="Order Date" Width="200px">
            <Template Context="order">
                @String.Format("{0:d}", order.OrderDate)
            </Template>
            <EditTemplate Context="order">
                <RadzenDatePicker @bind-Value="order.OrderDate" Style="width:100%" InputAttributes="@(new Dictionary<string,object>(){ { "aria-label", "Select order date" }})" Name="OrderDatePicker"/>
                    <RadzenRequiredValidator Text="OrderDatePicker is required" Component="OrderDatePicker" Popup="true" />
            </EditTemplate>
        </RadzenDataGridColumn>
        <RadzenDataGridColumn Property="@nameof(Order.Freight)" Title="Freight">
            <Template Context="order">
                @String.Format(new System.Globalization.CultureInfo("en-US"), "{0:C}", order.Freight)
            </Template>
            <EditTemplate Context="order">
                <RadzenNumeric @bind-Value="order.Freight" Style="width:100%" InputAttributes="@(new Dictionary<string,object>(){ { "aria-label", "Select freight" }})" />
            </EditTemplate>
        </RadzenDataGridColumn>
        <RadzenDataGridColumn Property="@nameof(Order.ShipName)" Title="Ship Name">
            <EditTemplate Context="order">
                <RadzenTextBox @bind-Value="order.ShipName" Style="width:200px; display: block" Name="ShipName" aria-label="Enter ship name" />
                <RadzenRequiredValidator Text="ShipName is required" Component="ShipName" Popup="true" />
            </EditTemplate>
        </RadzenDataGridColumn>
        <RadzenDataGridColumn Property="@nameof(Order.ShipCountry)" Title="ShipCountry">
            <EditTemplate Context="order">
                <RadzenTextBox @bind-Value="order.ShipCountry" Style="width:200px; display: block" Name="ShipCountry" aria-label="Enter ship country" />
                <RadzenRequiredValidator Text="ShipCountry is required" Component="ShipCountry" Popup="true" />
            </EditTemplate>
        </RadzenDataGridColumn>
        <RadzenDataGridColumn Property="@nameof(Order.ShipCity)" Title="ShipCity">
            <EditTemplate Context="order">
                <RadzenTextBox @bind-Value="order.ShipCity" Style="width:200px; display: block" Name="ShipCity" aria-label="Enter ship city" />
                <RadzenRequiredValidator Text="ShipCity is required" Component="ShipCity" Popup="true" />
            </EditTemplate>
        </RadzenDataGridColumn>
        <RadzenDataGridColumn Context="order" Filterable="false" Sortable="false" TextAlign="TextAlign.Right" Frozen="true" FrozenPosition="FrozenColumnPosition.Right">
            <Template Context="order">
                <RadzenButton Icon="add_circle" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Size="ButtonSize.Medium" Shade="Shade.Lighter" Click="@(() => InsertAfterRow(order))" title="Add new row after this row" Disabled="@(editMode == DataGridEditMode.Single && ordersToInsert.Count() > 0)" />
                <RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="rz-my-1 rz-ms-1" Click="@(args => EditRow(order))" @onclick:stopPropagation="true" />
                <RadzenButton Icon="delete" ButtonStyle="ButtonStyle.Danger" Variant="Variant.Flat" Size="ButtonSize.Medium" Shade="Shade.Lighter" class="rz-my-1 rz-ms-1" Click="@(args => DeleteRow(order))" @onclick:stopPropagation="true" />
            </Template>
            <EditTemplate Context="order">
                <RadzenButton Icon="check" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Size="ButtonSize.Medium" Click="@((args) => SaveRow(order))" aria-label="Save"/>
                <RadzenButton Icon="close" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Medium" class="rz-my-1 rz-ms-1" Click="@((args) => CancelEdit(order))" aria-label="Cancel"/>
                <RadzenButton Icon="delete" ButtonStyle="ButtonStyle.Danger" Variant="Variant.Flat" Size="ButtonSize.Medium" Shade="Shade.Lighter" class="rz-my-1 rz-ms-1" Click="@(args => DeleteRow(order))" aria-label="Delete" />
            </EditTemplate>
        </RadzenDataGridColumn>
    </Columns>
</RadzenDataGrid>

@code {
    RadzenDataGrid<Order> ordersGrid;
    IEnumerable<Order> orders;
    IEnumerable<Customer> customers;
    IEnumerable<Employee> employees;

    DataGridEditMode editMode = DataGridEditMode.Single;

    List<Order> ordersToInsert = new List<Order>();
    List<Order> ordersToUpdate = new List<Order>();

    void Reset()
    {
        ordersToInsert.Clear();
        ordersToUpdate.Clear();
    }

    void Reset(Order order)
    {
        ordersToInsert.Remove(order);
        ordersToUpdate.Remove(order);
    }

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();

        customers = dbContext.Customers;
        employees = dbContext.Employees;

        orders = dbContext.Orders.Include("Customer").Include("Employee");
    }

    async Task EditRow(Order order)
    {
        if (!ordersGrid.IsValid) return;

        if (editMode == DataGridEditMode.Single)
        {
            Reset();
        }

        ordersToUpdate.Add(order);
        await ordersGrid.EditRow(order);
    }

    void OnUpdateRow(Order order)
    {
        Reset(order);

        dbContext.Update(order);

        dbContext.SaveChanges();
    }

    async Task SaveRow(Order order)
    {
        await ordersGrid.UpdateRow(order);
    }

    void CancelEdit(Order order)
    {
        Reset(order);

        ordersGrid.CancelEditRow(order);

        var orderEntry = dbContext.Entry(order);
        if (orderEntry.State == EntityState.Modified)
        {
            orderEntry.CurrentValues.SetValues(orderEntry.OriginalValues);
            orderEntry.State = EntityState.Unchanged;
        }
    }

    async Task DeleteRow(Order order)
    {
        Reset(order);

        if (orders.Contains(order))
        {
            dbContext.Remove<Order>(order);

            dbContext.SaveChanges();

            await ordersGrid.Reload();
        }
        else
        {
            ordersGrid.CancelEditRow(order);
            await ordersGrid.Reload();
        }
    }

    async Task InsertRow()
    {
        if (!ordersGrid.IsValid) return;

        if (editMode == DataGridEditMode.Single)
        {
            Reset();
        }

        var order = new Order();
        ordersToInsert.Add(order);
        await ordersGrid.InsertRow(order);
    }

    async Task InsertAfterRow(Order row)
    {
        if (!ordersGrid.IsValid) return;

        if (editMode == DataGridEditMode.Single)
        {
            Reset();
        }

        var order = new Order();
        ordersToInsert.Add(order);
        await ordersGrid.InsertAfterRow(order, row);
    }

    void OnCreateRow(Order order)
    {
        dbContext.Add(order);

        dbContext.SaveChanges();

        ordersToInsert.Remove(order);
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant