Unplanned
Last Updated: 04 Sep 2023 08:44 by ADMIN
Meindert
Created on: 08 Feb 2023 13:23
Category: Grid
Type: Bug Report
9
Triggering Incell or Inline Edit which causes the grid to scroll cancels the edit

When the Virtualization feature is enabled, triggering Incell edit causes the Grid to scroll. When we scroll the edit is canceled. This happens when the row is partially visible.
https://www.screencast.com/t/zCJ9z9P83c

A more specific case is when you try to edit the last row. In case the editor height is bigger than the row height the Grid tries to scroll but there is no more data. The editor is closed and the item cannot be edited.
https://www.screencast.com/t/331cT4xxt

Reproduction: https://blazorrepl.telerik.com/QxEcECvx22pq4BBG59

 

1 comment
ADMIN
Dimo
Posted on: 04 Sep 2023 08:44

Hello everyone,

Until we fix this issue, here is a possible workaround for in-cell editing. Another option is to switch the Grid to popup edit mode.

  1. Use the Grid OnStateChanged event to track the Grid scroll position via the Skip property of the GridState.
  2. Measure or hard-code how many visible rows the Grid can display. This will depend on the theme, the Grid Height and the RowHeight.
  3. Use the Grid OnEdit event to check if the edited row is outside the viewable area (for example, item index > Skip + visible rows).
  4. If this is the case, then increment the Skip property in the Grid state and initiate editing of the same Grid item programmatically.
<TelerikGrid @ref="@GridRef"
             Data="@GridData"
             EditMode="@GridEditMode.Incell"
             Navigable="true"
             ScrollMode="@GridScrollMode.Virtual"
             RowHeight="42"
             Height="400px"
             OnUpdate="@OnGridUpdate"
             OnCreate="@OnGridCreate"
             OnStateChanged="@( (GridStateEventArgs<Product> args) => GridSkip = args.GridState.Skip )"
             OnEdit="@OnGridEdit">
    <GridToolBarTemplate>
        <GridCommandButton Command="Add" Icon="@FontIcon.Plus">Add Item</GridCommandButton>
    </GridToolBarTemplate>
    <GridColumns>
        <GridColumn Field="@nameof(Product.Name)" Title="Product Name" />
        <GridColumn Field="@nameof(Product.Price)" Title="Unit Price" />
        <GridColumn Field="@nameof(Product.Stock)" Title="Units In Stock" />
        <GridColumn Field="@nameof(Product.ReleaseDate)" Title="Release Date" />
        <GridColumn Field="@nameof(Product.Discontinued)" Title="Discontinued" />
    </GridColumns>
</TelerikGrid>

@code {
    TelerikGrid<Product> GridRef { get; set; }

    List<Product> GridData { get; set; }

    int? GridSkip { get; set; } = 0;

    int VisibleRowsInGrid = 6;

    private async Task OnGridEdit(GridCommandEventArgs args)
    {
        var originalEditItem = (Product)args.Item;
        var itemIndex = GridData.FindIndex(x => x.Id == originalEditItem.Id);
        if (itemIndex >= GridSkip + VisibleRowsInGrid)
        {
            var gridState = GridRef.GetState();
            gridState.Skip += 1;
            gridState.OriginalEditItem = originalEditItem;
            gridState.EditItem = originalEditItem.Clone();

            await GridRef.SetStateAsync(gridState);
        }
    }

    private void OnGridUpdate(GridCommandEventArgs args)
    {
        var argsItem = args.Item as Product;
        var index = GridData.FindIndex(i => i.Id == argsItem.Id);
        if (index != -1)
        {
            GridData[index] = argsItem;
        }
    }

    private void OnGridCreate(GridCommandEventArgs args)
    {
        var argsItem = args.Item as Product;

        argsItem.Id = GridData.Count + 1;

        GridData.Insert(0, argsItem);
    }

    private void OnGridDelete(GridCommandEventArgs args)
    {
        var argsItem = args.Item as Product;

        GridData.Remove(argsItem);
    }

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

        var rnd = new Random();

        for (int i = 1; i <= 500; i++)
        {
            GridData.Add(new Product()
            {
                Id = i,
                Name = $"Product {i}",
                Price = (decimal)(rnd.Next(1, 100) * 3.14),
                Stock = (short)rnd.Next(0, 1000),
                ReleaseDate = DateTime.Now.AddMonths(-rnd.Next(0, 120)).AddDays(rnd.Next(1, 30)),
                Discontinued = Convert.ToBoolean(rnd.Next(0, 2))
            });
        }
    }

    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal? Price { get; set; }
        public short? Stock { get; set; }
        public DateTime? ReleaseDate { get; set; }
        public bool Discontinued { get; set; }

        public Product Clone()
        {
            return new Product()
            {
                Discontinued = Discontinued,
                Id = Id,
                Name = Name,
                Price = Price,
                ReleaseDate = ReleaseDate,
                Stock = Stock
            };
        }
    }
}

Regards,
Dimo
Progress Telerik

Stay tuned by visiting our public roadmap and feedback portal pages! Or perhaps, if you are new to our Telerik family, check out our getting started resources!