Completed
Last Updated: 15 Apr 2025 13:20 by ADMIN
Release 2025 Q2 (May)
Aaron
Created on: 15 Apr 2025 13:03
Category: Popover
Type: Bug Report
2
Dynamic Popover Anchoring Breaks on Grid Operations (Sorting, Paging)
Since version 7.0.0, if you show a Popover for each Grid row, upon sorting/paging, the Popover displays with the incorrect association.
1 comment
ADMIN
Hristian Stefanov
Posted on: 15 Apr 2025 13:20

Hello,

Closing this as "Completed," as each TelerikPopover instance should have a unique "@key" set. This allows the framework to correctly track and re-render the component in sync with data changes, ensuring the Popover remains anchored to the correct element.

@using System.Threading

<TelerikGrid Data="@GridData" FilterMode="@GridFilterMode.FilterMenu" Sortable="true">
    <GridColumns>
        <GridColumn Field="Name" Title="Product Name">
            <Template>
                @{
                    var product = context as Product;
                }
                <TelerikPopover @ref="product.ProductPopover"
                                @key="@product.Id"
                                AnchorSelector="@($".popover-target-{product.Id}")"
                                AnimationType="AnimationType.Fade">
                    <PopoverContent>
                        @product.Name
                    </PopoverContent>
                </TelerikPopover>
                <span class="@($"popover-target-{product.Id}") popover-target"
                      style="cursor: help"
                      @onmouseover="@(() => StartShowPopover(product))"
                      @onmouseleave="@(() => CancelShowPopover(product))">
                    @product.Name
                </span>
            </Template>
        </GridColumn>
    </GridColumns>
</TelerikGrid>

@code {
    private List<Product> GridData { get; set; }

    protected override void OnInitialized()
    {
        GridData = new List<Product>();

        for (int i = 1; i <= 30; i++)
        {
            GridData.Add(new Product
                {
                    Id = i,
                    Name = "Product name " + i,
                    ProductPopover = new TelerikPopover()
                });
        }

        base.OnInitialized();
    }

    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public TelerikPopover ProductPopover { get; set; }
        public CancellationTokenSource CancellationTokenSource { get; set; }
    }

    private async Task StartShowPopover(Product product)
    {
        // Cancel any ongoing show operation for this product
        CancelShowPopover(product);

        // Create a new cancellation token source
        product.CancellationTokenSource = new CancellationTokenSource();
        try
        {
            // Wait for the delay with cancellation support
            await Task.Delay(1000, product.CancellationTokenSource.Token);
            product.ProductPopover.Show();
        }
        catch (TaskCanceledException)
        {
            // Handle the cancellation (no action needed here)
        }
    }

    private void CancelShowPopover(Product product)
    {
        // Cancel the token if it's active
        product.CancellationTokenSource?.Cancel();
        product.CancellationTokenSource = null;
        product.ProductPopover.Hide();
    }
}

Regards,
Hristian Stefanov
Progress Telerik

Enjoyed our products? Share your experience on G2 and receive a $25 Amazon gift card for a limited time!