Tab Content Overlay Issue in Dialog #1812

Closed
opened 2026-01-29 17:58:53 +00:00 by claunia · 12 comments
Owner

Originally created by @nhtdalat on GitHub (Jul 16, 2025).

Issue Description:
When switching tabs within the "Customer.Edit.Title" dialog, the content of the newly selected tab ("CUSTOMER.SOCIALLINKS") appears as an overlay on top of the previously active tab's content ("CUSTOMER.ADDRESSES") instead of replacing it. This results in an unreadable and unusable interface for managing social links.

Steps to Reproduce:

Open the "Customer.Edit.Title" dialog.

Observe that the "CUSTOMER.ADDRESSES" tab is active by default, displaying its content.

Click on the "CUSTOMER.SOCIALLINKS" tab.

Actual Result: The content intended for the "CUSTOMER.SOCIALLINKS" tab (e.g., Instagram dropdown, URL input, "SOCIALLINK.ADD" button) is rendered on top of, or interleaved with, the "CUSTOMER.ADDRESSES" tab's content, causing an overlay and visual corruption.

**

Image Image

**

Upon clicking the "CUSTOMER.SOCIALLINKS" tab, the dialog's content area should completely and cleanly transition to display only the fields and controls relevant to the "CUSTOMER.SOCIALLINKS" tab. The content of the "CUSTOMER.ADDRESSES" tab should be fully hidden or unloaded, ensuring a clear and functional interface for inputting social link data.

Originally created by @nhtdalat on GitHub (Jul 16, 2025). **Issue Description:** When switching tabs within the "Customer.Edit.Title" dialog, the content of the newly selected tab ("CUSTOMER.SOCIALLINKS") appears as an overlay on top of the previously active tab's content ("CUSTOMER.ADDRESSES") instead of replacing it. This results in an unreadable and unusable interface for managing social links. **Steps to Reproduce:** Open the "Customer.Edit.Title" dialog. Observe that the "CUSTOMER.ADDRESSES" tab is active by default, displaying its content. Click on the "CUSTOMER.SOCIALLINKS" tab. Actual Result: The content intended for the "CUSTOMER.SOCIALLINKS" tab (e.g., Instagram dropdown, URL input, "SOCIALLINK.ADD" button) is rendered on top of, or interleaved with, the "CUSTOMER.ADDRESSES" tab's content, causing an overlay and visual corruption. ** <img width="882" height="841" alt="Image" src="https://github.com/user-attachments/assets/ffc89b72-6b55-4f38-8dd4-abcd5e8fa862" /> <img width="856" height="823" alt="Image" src="https://github.com/user-attachments/assets/dd14749f-bc7e-4ef2-b549-aa6f8d26a472" /> ** Upon clicking the "CUSTOMER.SOCIALLINKS" tab, the dialog's content area should completely and cleanly transition to display only the fields and controls relevant to the "CUSTOMER.SOCIALLINKS" tab. The content of the "CUSTOMER.ADDRESSES" tab should be fully hidden or unloaded, ensuring a clear and functional interface for inputting social link data.
Author
Owner

@enchev commented on GitHub (Jul 16, 2025):

Please provide runnable code demonstrating the problem. You can use our demos, they are editable.

@enchev commented on GitHub (Jul 16, 2025): Please provide runnable code demonstrating the problem. You can use our demos, they are editable.
Author
Owner

@nhtdalat commented on GitHub (Jul 16, 2025):

@using Radzen
@using Radzen.Blazor
@using System.Collections.Generic
@using System.Linq

@inject DialogService DialogService // Keep DialogService for closing the dialog

Customer Editor (Demo)

            <RadzenRow AlignItems="AlignItems.Center">
                <RadzenColumn Size="4">
                    <RadzenLabel Text="Phone Number" />
                </RadzenColumn>
                <RadzenColumn Size="8">
                    <RadzenTextBox @bind-Value="customerModel.PhoneNumber" Name="PhoneNumber" Style="width: 100%;"></RadzenTextBox>
                    <RadzenRequiredValidator Component="PhoneNumber" Text="Phone number is required" />
                </RadzenColumn>
            </RadzenRow>

            <RadzenRow AlignItems="AlignItems.Center">
                <RadzenColumn Size="4">
                    <RadzenLabel Text="Email" />
                </RadzenColumn>
                <RadzenColumn Size="8">
                    <RadzenTextBox @bind-Value="customerModel.Email" Name="Email" Style="width: 100%;" />
                    <RadzenEmailValidator Component="Email" Text="Invalid email" />
                </RadzenColumn>
            </RadzenRow>
        </RadzenStack>
    </RadzenFieldset>

    <RadzenTabs RenderMode="TabRenderMode.Client"> @* This is the component causing issues *@
        <Tabs>
            <RadzenTabsItem Text="CUSTOMER.ADDRESSES">
                <RadzenStack>
                    @foreach (var address in addresses)
                    {
                        <RadzenCard>
                            <RadzenRow>
                                <RadzenColumn Size="12" class="rz-text-align-center rz-text-align-md-right">
                                    <RadzenButton Icon="delete" ButtonStyle="ButtonStyle.Danger" Size="ButtonSize.Small" Click="@(() => RemoveAddress(address))" />
                                </RadzenColumn>
                            </RadzenRow>
                            <RadzenRow Gap="0.5rem">
                                <RadzenColumn Size="12">
                                    <RadzenStack>
                                        <RadzenFormField Text="Address Type" Variant="Variant.Text">
                                            <RadzenDropDown @bind-Value="address.Type" Data="@addressTypes" AllowClear="false" Style="width:150px;" />
                                        </RadzenFormField>
                                        <RadzenFormField Text="Recipient Name" Variant="Variant.Text">
                                            <RadzenTextBox @bind-Value="address.Name" Style="width: 100%;" />
                                        </RadzenFormField>
                                        <RadzenFormField Text="Street Address" Variant="Variant.Text">
                                            <RadzenTextBox @bind-Value="address.Address" Style="width: 100%;" />
                                        </RadzenFormField>
                                        <RadzenFormField Text="Phone Number" Variant="Variant.Text">
                                            <RadzenTextBox @bind-Value="address.PhoneNumber" Style="width: 100%;" />
                                        </RadzenFormField>
                                    </RadzenStack>
                                </RadzenColumn>
                            </RadzenRow>
                        </RadzenCard>
                    }
                    <RadzenButton Icon="add_location" Text="Add Address" ButtonStyle="ButtonStyle.Secondary" Click="AddAddress" Style="width:100%" />
                </RadzenStack>
            </RadzenTabsItem>
            <RadzenTabsItem Text="CUSTOMER.SOCIALLINKS">
                <RadzenStack>
                    @foreach (var link in socialLinks)
                    {
                        <RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center">
                            <RadzenDropDown @bind-Value="link.Platform"
                                            Data="@socialPlatforms"
                                            AllowClear="false"
                                            Style="width: 150px; flex-shrink: 0;" />

                            <RadzenTextBox @bind-Value="link.Url"
                                           Placeholder="e.g., https://www.instagram.com/yourprofile"
                                           Style="width: 100%;" />

                            <RadzenButton Icon="delete"
                                          ButtonStyle="ButtonStyle.Danger"
                                          Click="@(() => RemoveSocialLink(link))"
                                          @onclick:stopPropagation="true" />
                        </RadzenStack>
                    }
                    <RadzenButton Icon="link" Text="Add Social Link" ButtonStyle="ButtonStyle.Secondary" Click="AddSocialLink" Style="width:100%" />
                </RadzenStack>
            </RadzenTabsItem>
        </Tabs>
    </RadzenTabs>

    <RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.End">
        <RadzenButton ButtonType="ButtonType.Button" Text="Cancel" ButtonStyle="ButtonStyle.Light" Click="@(() => DialogService.Close(false))" />
        <RadzenButton ButtonType="ButtonType.Submit" Text="Save" Icon="save" ButtonStyle="ButtonStyle.Primary" IsBusy="@isSaving" />
    </RadzenStack>
</RadzenStack>

@code {
// Simplified models for demonstration
public class CustomerInput
{
public string Name { get; set; }
public string PhoneNumber { get; set; }
public string Email { get; set; }
// These are not actually used in this simplified demo, but keep them for context
public string Address { get; set; }
public string SocialLink { get; set; }
}

public class AddressInfo
{
    public string Type { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string PhoneNumber { get; set; }
}

public class SocialLinkInfo
{
    public string Platform { get; set; }
    public string Url { get; set; }
}

// --- Component Logic ---
[Parameter]
public object CustomerToEdit { get; set; } // Use object if actual Customer type is complex/irrelevant for bug

private CustomerInput customerModel = new();
private List<AddressInfo> addresses = new();
private List<SocialLinkInfo> socialLinks = new();

private bool isEditMode = false;
private bool isSaving = false;

private readonly List<string> addressTypes = new() { "Home", "Work", "Other" };
private readonly List<string> socialPlatforms = new() { "Instagram", "Facebook", "Tiktok", "Website" };

protected override void OnInitialized()
{
    // Simulate loading data if in edit mode
    if (CustomerToEdit != null)
    {
        isEditMode = true;
        customerModel = new CustomerInput
        {
            Name = "John Doe",
            PhoneNumber = "123-456-7890",
            Email = "john.doe@example.com"
        };

        // Simulate existing addresses
        addresses.Add(new AddressInfo { Type = "Home", Name = "John Doe", Address = "123 Main St", PhoneNumber = "123-456-7890" });
        addresses.Add(new AddressInfo { Type = "Work", Name = "John Doe", Address = "456 Office Rd", PhoneNumber = "098-765-4321" });

        // Simulate existing social links
        socialLinks.Add(new SocialLinkInfo { Platform = "Instagram", Url = "https://instagram.com/johndoe" });
    }
    else
    {
        customerModel = new CustomerInput();
        addresses = new List<AddressInfo>();
        socialLinks = new List<SocialLinkInfo>();
    }
}

private async Task OnSubmit(CustomerInput args)
{
    if (isSaving) return;
    isSaving = true;

    Console.WriteLine("Saving customer data...");
    // Simulate an API call
    await Task.Delay(500);

    // In a real app, you'd send args to your service.
    // For this demo, we just close.
    DialogService.Close(true);
    isSaving = false;
}

private void AddAddress()
{
    addresses.Add(new AddressInfo { Type = addressTypes.First(), PhoneNumber = customerModel.PhoneNumber });
    StateHasChanged(); // Essential for Blazor to re-render the list
}
private void RemoveAddress(AddressInfo address)
{
    addresses.Remove(address);
    StateHasChanged(); // Essential for Blazor to re-render the list
}

private void AddSocialLink()
{
    socialLinks.Add(new SocialLinkInfo { Platform = socialPlatforms.First() });
    StateHasChanged(); // Essential for Blazor to re-render the list
}
private void RemoveSocialLink(SocialLinkInfo link)
{
    socialLinks.Remove(link);
    StateHasChanged(); // Essential for Blazor to re-render the list
}

}

@nhtdalat commented on GitHub (Jul 16, 2025): > @using Radzen > @using Radzen.Blazor > @using System.Collections.Generic > @using System.Linq > > @inject DialogService DialogService // Keep DialogService for closing the dialog > > <h3>Customer Editor (Demo)</h3> > > <RadzenTemplateForm TItem="CustomerInput" Data="@customerModel" Submit="@OnSubmit"> > <RadzenStack> > <RadzenFieldset Text="Customer Details"> > <RadzenStack Gap="1rem"> > <RadzenRow AlignItems="AlignItems.Center"> > <RadzenColumn Size="4"> > <RadzenLabel Text="Name" /> > </RadzenColumn> > <RadzenColumn Size="8"> > <RadzenTextBox @bind-Value="customerModel.Name" Name="Name" Style="width: 100%;" /> > <RadzenRequiredValidator Component="Name" Text="Name is required" /> > </RadzenColumn> > </RadzenRow> > > <RadzenRow AlignItems="AlignItems.Center"> > <RadzenColumn Size="4"> > <RadzenLabel Text="Phone Number" /> > </RadzenColumn> > <RadzenColumn Size="8"> > <RadzenTextBox @bind-Value="customerModel.PhoneNumber" Name="PhoneNumber" Style="width: 100%;"></RadzenTextBox> > <RadzenRequiredValidator Component="PhoneNumber" Text="Phone number is required" /> > </RadzenColumn> > </RadzenRow> > > <RadzenRow AlignItems="AlignItems.Center"> > <RadzenColumn Size="4"> > <RadzenLabel Text="Email" /> > </RadzenColumn> > <RadzenColumn Size="8"> > <RadzenTextBox @bind-Value="customerModel.Email" Name="Email" Style="width: 100%;" /> > <RadzenEmailValidator Component="Email" Text="Invalid email" /> > </RadzenColumn> > </RadzenRow> > </RadzenStack> > </RadzenFieldset> > > <RadzenTabs RenderMode="TabRenderMode.Client"> @* This is the component causing issues *@ > <Tabs> > <RadzenTabsItem Text="CUSTOMER.ADDRESSES"> > <RadzenStack> > @foreach (var address in addresses) > { > <RadzenCard> > <RadzenRow> > <RadzenColumn Size="12" class="rz-text-align-center rz-text-align-md-right"> > <RadzenButton Icon="delete" ButtonStyle="ButtonStyle.Danger" Size="ButtonSize.Small" Click="@(() => RemoveAddress(address))" /> > </RadzenColumn> > </RadzenRow> > <RadzenRow Gap="0.5rem"> > <RadzenColumn Size="12"> > <RadzenStack> > <RadzenFormField Text="Address Type" Variant="Variant.Text"> > <RadzenDropDown @bind-Value="address.Type" Data="@addressTypes" AllowClear="false" Style="width:150px;" /> > </RadzenFormField> > <RadzenFormField Text="Recipient Name" Variant="Variant.Text"> > <RadzenTextBox @bind-Value="address.Name" Style="width: 100%;" /> > </RadzenFormField> > <RadzenFormField Text="Street Address" Variant="Variant.Text"> > <RadzenTextBox @bind-Value="address.Address" Style="width: 100%;" /> > </RadzenFormField> > <RadzenFormField Text="Phone Number" Variant="Variant.Text"> > <RadzenTextBox @bind-Value="address.PhoneNumber" Style="width: 100%;" /> > </RadzenFormField> > </RadzenStack> > </RadzenColumn> > </RadzenRow> > </RadzenCard> > } > <RadzenButton Icon="add_location" Text="Add Address" ButtonStyle="ButtonStyle.Secondary" Click="AddAddress" Style="width:100%" /> > </RadzenStack> > </RadzenTabsItem> > <RadzenTabsItem Text="CUSTOMER.SOCIALLINKS"> > <RadzenStack> > @foreach (var link in socialLinks) > { > <RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center"> > <RadzenDropDown @bind-Value="link.Platform" > Data="@socialPlatforms" > AllowClear="false" > Style="width: 150px; flex-shrink: 0;" /> > > <RadzenTextBox @bind-Value="link.Url" > Placeholder="e.g., https://www.instagram.com/yourprofile" > Style="width: 100%;" /> > > <RadzenButton Icon="delete" > ButtonStyle="ButtonStyle.Danger" > Click="@(() => RemoveSocialLink(link))" > @onclick:stopPropagation="true" /> > </RadzenStack> > } > <RadzenButton Icon="link" Text="Add Social Link" ButtonStyle="ButtonStyle.Secondary" Click="AddSocialLink" Style="width:100%" /> > </RadzenStack> > </RadzenTabsItem> > </Tabs> > </RadzenTabs> > > <RadzenStack Orientation="Orientation.Horizontal" JustifyContent="JustifyContent.End"> > <RadzenButton ButtonType="ButtonType.Button" Text="Cancel" ButtonStyle="ButtonStyle.Light" Click="@(() => DialogService.Close(false))" /> > <RadzenButton ButtonType="ButtonType.Submit" Text="Save" Icon="save" ButtonStyle="ButtonStyle.Primary" IsBusy="@isSaving" /> > </RadzenStack> > </RadzenStack> > </RadzenTemplateForm> > @code { > // Simplified models for demonstration > public class CustomerInput > { > public string Name { get; set; } > public string PhoneNumber { get; set; } > public string Email { get; set; } > // These are not actually used in this simplified demo, but keep them for context > public string Address { get; set; } > public string SocialLink { get; set; } > } > > public class AddressInfo > { > public string Type { get; set; } > public string Name { get; set; } > public string Address { get; set; } > public string PhoneNumber { get; set; } > } > > public class SocialLinkInfo > { > public string Platform { get; set; } > public string Url { get; set; } > } > > // --- Component Logic --- > [Parameter] > public object CustomerToEdit { get; set; } // Use object if actual Customer type is complex/irrelevant for bug > > private CustomerInput customerModel = new(); > private List<AddressInfo> addresses = new(); > private List<SocialLinkInfo> socialLinks = new(); > > private bool isEditMode = false; > private bool isSaving = false; > > private readonly List<string> addressTypes = new() { "Home", "Work", "Other" }; > private readonly List<string> socialPlatforms = new() { "Instagram", "Facebook", "Tiktok", "Website" }; > > protected override void OnInitialized() > { > // Simulate loading data if in edit mode > if (CustomerToEdit != null) > { > isEditMode = true; > customerModel = new CustomerInput > { > Name = "John Doe", > PhoneNumber = "123-456-7890", > Email = "john.doe@example.com" > }; > > // Simulate existing addresses > addresses.Add(new AddressInfo { Type = "Home", Name = "John Doe", Address = "123 Main St", PhoneNumber = "123-456-7890" }); > addresses.Add(new AddressInfo { Type = "Work", Name = "John Doe", Address = "456 Office Rd", PhoneNumber = "098-765-4321" }); > > // Simulate existing social links > socialLinks.Add(new SocialLinkInfo { Platform = "Instagram", Url = "https://instagram.com/johndoe" }); > } > else > { > customerModel = new CustomerInput(); > addresses = new List<AddressInfo>(); > socialLinks = new List<SocialLinkInfo>(); > } > } > > private async Task OnSubmit(CustomerInput args) > { > if (isSaving) return; > isSaving = true; > > Console.WriteLine("Saving customer data..."); > // Simulate an API call > await Task.Delay(500); > > // In a real app, you'd send args to your service. > // For this demo, we just close. > DialogService.Close(true); > isSaving = false; > } > > private void AddAddress() > { > addresses.Add(new AddressInfo { Type = addressTypes.First(), PhoneNumber = customerModel.PhoneNumber }); > StateHasChanged(); // Essential for Blazor to re-render the list > } > private void RemoveAddress(AddressInfo address) > { > addresses.Remove(address); > StateHasChanged(); // Essential for Blazor to re-render the list > } > > private void AddSocialLink() > { > socialLinks.Add(new SocialLinkInfo { Platform = socialPlatforms.First() }); > StateHasChanged(); // Essential for Blazor to re-render the list > } > private void RemoveSocialLink(SocialLinkInfo link) > { > socialLinks.Remove(link); > StateHasChanged(); // Essential for Blazor to re-render the list > } > }
Author
Owner

@nhtdalat commented on GitHub (Jul 16, 2025):

@enchev here is my code

@nhtdalat commented on GitHub (Jul 16, 2025): @enchev here is my code
Author
Owner

@enchev commented on GitHub (Jul 16, 2025):

We cannot compile this code

@enchev commented on GitHub (Jul 16, 2025): We cannot compile this code
Author
Owner

@nhtdalat commented on GitHub (Jul 16, 2025):

sorry, I have updated the code with minimal dependencies.

@nhtdalat commented on GitHub (Jul 16, 2025): sorry, I have updated the code with minimal dependencies.
Author
Owner

@nhtdalat commented on GitHub (Jul 16, 2025):

and this code to call that code in the dialog

@page "/"
@inject DialogService DialogService

@code {
async Task OpenCustomerForm()
{
// Pass null for "add" mode, or a dummy object for "edit" mode
await DialogService.OpenAsync("Customer Form",
new Dictionary<string, object>() { { "CustomerToEdit", new { Name = "Test Customer" } } }, // Pass a dummy object to simulate edit mode
new DialogOptions() { Width = "840px", Resizable = true, Draggable = true });
}
}

@nhtdalat commented on GitHub (Jul 16, 2025): and this code to call that code in the dialog > @page "/" > @inject DialogService DialogService > > <RadzenButton Text="Open Customer Form (Tab Bug Demo)" Click="OpenCustomerForm" /> > > @code { > async Task OpenCustomerForm() > { > // Pass null for "add" mode, or a dummy object for "edit" mode > await DialogService.OpenAsync<RadzenTabBugDemo>("Customer Form", > new Dictionary<string, object>() { { "CustomerToEdit", new { Name = "Test Customer" } } }, // Pass a dummy object to simulate edit mode > new DialogOptions() { Width = "840px", Resizable = true, Draggable = true }); > } > }
Author
Owner

@enchev commented on GitHub (Jul 16, 2025):

Please format both code blocks for easy copy

@enchev commented on GitHub (Jul 16, 2025): Please format both code blocks for easy copy
Author
Owner

@nhtdalat commented on GitHub (Jul 16, 2025):

Thanks for your patience. I've uploaded the files for easier access and compilation. You can find them here:
Index.razor.txt
CustomerForm.razor.txt

@nhtdalat commented on GitHub (Jul 16, 2025): Thanks for your patience. I've uploaded the files for easier access and compilation. You can find them here: [Index.razor.txt](https://github.com/user-attachments/files/21257886/Index.razor.txt) [CustomerForm.razor.txt](https://github.com/user-attachments/files/21257887/CustomerForm.razor.txt)
Author
Owner

@enchev commented on GitHub (Jul 16, 2025):

Here is what I see in our demos

https://github.com/user-attachments/assets/28300056-00e7-46e2-8e58-3e90128b19eb

@enchev commented on GitHub (Jul 16, 2025): Here is what I see in our demos https://github.com/user-attachments/assets/28300056-00e7-46e2-8e58-3e90128b19eb
Author
Owner

@nhtdalat commented on GitHub (Jul 16, 2025):

Hello,
this is in my side

@nhtdalat commented on GitHub (Jul 16, 2025): Hello, this is in my side
Author
Owner

@nhtdalat commented on GitHub (Jul 16, 2025):

I try to keep"State Persistence" by creating private int selectedTabIndex, but if I set it = 0, still get the problem.

@nhtdalat commented on GitHub (Jul 16, 2025): I try to keep"State Persistence" by creating private int selectedTabIndex, but if I set it = 0, still get the problem.
Author
Owner

@nhtdalat commented on GitHub (Jul 16, 2025):

I found the solution.
By setting style="min-height: 400px;", the dialog's dimensions are now stable, it does not trigger the problematic resize-and-rerender cycle, so I solved the problem.
<RadzenTabsItem Text="@L["Customer.Addresses"]">
<RadzenStack Style="min-height:400px">

@nhtdalat commented on GitHub (Jul 16, 2025): I found the solution. By setting style="min-height: 400px;", the dialog's dimensions are now stable, it does not trigger the problematic resize-and-rerender cycle, so I solved the problem. <RadzenTabsItem Text="@L["Customer.Addresses"]"> <RadzenStack **Style="min-height:400px"**>
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/radzen-blazor#1812