Unplanned
Last Updated: 18 Oct 2023 10:50 by Craig
Craig
Created on: 18 Oct 2023 10:50
Category: Grid
Type: Feature Request
7
Add the ability to lock a column on a certain index

I would like to lock a column at a certain index in the Grid. For example, I would like to have a column on index 0 (the first column in the Grid) and it should not be reordered by any user interaction (dragging the column itself or dragging other columns in its place). 

Also if the user tries to drag a column over my locked column the drag handlers must not be present/or show that it is an invalid drop location.

===

Telerik edit:

In the meantime, a possible workaround is to:

  1. Handle the Grid OnStateChanged event.
  2. Check if args.PropertyName is equal to "ColumnStates".
  3. Check if the Index of the first Grid column (args.GridState.ColumnStates.First()) is greater than zero.
  4. Reset at least 2 column indexes, according to your preferences, so that the first column in the Grid markup is also the first column in the UI.
  5. Reset the Grid state with SetStateAsync().

 

<p>The <strong>Name</strong> column index will always be 0.
    The Grid will either move the reordered column to index 1, or put it back to its previous index (revert).</p>

<p><label><TelerikCheckBox @bind-Value="@ShouldRevertGridColumnOrder" /> Revert Invalid Column Reordering</label></p>

<TelerikGrid @ref="@GridRef"
             Data="@GridData"
             TItem="@SampleModel"
             Pageable="true"
             Sortable="true"
             Reorderable="true"
             OnStateChanged="@OnGridStateChanged">
    <GridColumns>
        <GridColumn Field="@nameof(SampleModel.Name)" Reorderable="false" />
        <GridColumn Field="@nameof(SampleModel.GroupName)" />
        <GridColumn Field="@nameof(SampleModel.Price)" />
        <GridColumn Field="@nameof(SampleModel.Quantity)" />
        <GridColumn Field="@nameof(SampleModel.StartDate)" />
        <GridColumn Field="@nameof(SampleModel.IsActive)" />
    </GridColumns>
</TelerikGrid>

@code {
    private TelerikGrid<SampleModel>? GridRef { get; set; }

    private List<SampleModel> GridData { get; set; } = new();

    private bool ShouldRevertGridColumnOrder { get; set; }

    private IEnumerable<int>? CachedGridColumnIndexes { get; set; }

    private async Task OnGridStateChanged(GridStateEventArgs<SampleModel> args)
    {
        if (args.PropertyName == "ColumnStates")
        {
            if (args.GridState.ColumnStates.First().Index > 0 && GridRef != null)
            {
                if (ShouldRevertGridColumnOrder)
                {
                    await RevertGridColumnOrder();
                }
                else
                {
                    args.GridState.ColumnStates.First(x => x.Index == 0).Index = 1;

                    args.GridState.ColumnStates.First().Index = 0;

                    await GridRef.SetStateAsync(args.GridState);
                }
            }

            CacheGridColumnOrder();
        }
    }

    private void CacheGridColumnOrder()
    {
        var gridColumnState = GridRef?.GetState().ColumnStates;

        if (gridColumnState != null)
        {
            CachedGridColumnIndexes = gridColumnState.Select(x => x.Index);
        }
    }

    private async Task RevertGridColumnOrder()
    {
        var gridState = GridRef?.GetState();

        if (gridState != null && CachedGridColumnIndexes != null)
        {
            for (int i = 0; i < gridState.ColumnStates.Count; i++)
            {
                gridState.ColumnStates.ElementAt(i).Index = CachedGridColumnIndexes.ElementAt(i);
            }

            await GridRef!.SetStateAsync(gridState);
        }
    }

    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            CacheGridColumnOrder();
        }

        base.OnAfterRender(firstRender);
    }

    protected override void OnInitialized()
    {
        var rnd = new Random();

        for (int i = 1; i <= 7; i++)
        {
            GridData.Add(new SampleModel()
            {
                Id = i,
                Name = $"Name {i}",
                GroupName = $"Group {i % 3 + 1}",
                Price = rnd.Next(1, 100) * 1.23m,
                Quantity = rnd.Next(0, 1000),
                StartDate = DateTime.Now.AddDays(-rnd.Next(60, 1000)),
                IsActive = i % 4 > 0
            });
        }
    }

    public class SampleModel
    {
        public int Id { get; set; }
        public string Name { get; set; } = string.Empty;
        public string GroupName { get; set; } = string.Empty;
        public decimal Price { get; set; }
        public int Quantity { get; set; }
        public DateTime StartDate { get; set; }
        public bool IsActive { get; set; }
    }
}

 

0 comments