Completed
Last Updated: 26 Jan 2021 08:46 by ADMIN
Release 2.21.1
Emran
Created on: 05 Jan 2021 17:08
Category: Grid
Type: Bug Report
1
Hitting Enter while inserting a record in InLine edit mode calls the OnUpdate handler instead of OnCreate

Using the keyboard to save items works inconsistently. When editing an item, hitting enter seems to save the change as expected. When inserting an item, however, the item is lost.

---

ADMIN EDIT

Tthe grid calls the OnUpdate handler again, not OnCreate which results in data loss - the newly inserted item is unlikely to match existing data and so it appears to be lost.

Workaround - call the OnCreate handler yourself when the ID of the record is the default for its type - for example, zero for an integer. This indicates a newly inserted record in the grid.

<TelerikGrid Data=@MyData EditMode="@GridEditMode.Inline" Pageable="true" Height="500px" Navigable="true"
             OnUpdate="@UpdateHandler" OnDelete="@DeleteHandler" OnCreate="@CreateHandler" OnCancel="@CancelHandler">
    <GridToolBar>
        <GridCommandButton Command="Add" Icon="add">Add Employee</GridCommandButton>
    </GridToolBar>
    <GridColumns>
        <GridColumn Field=@nameof(SampleData.ID) Title="ID" Editable="false" />
        <GridColumn Field=@nameof(SampleData.Name) Title="Name" />
        <GridCommandColumn>
            <GridCommandButton Command="Save" Icon="save" ShowInEdit="true">Update</GridCommandButton>
            <GridCommandButton Command="Edit" Icon="edit">Edit</GridCommandButton>
            <GridCommandButton Command="Delete" Icon="delete">Delete</GridCommandButton>
            <GridCommandButton Command="Cancel" Icon="cancel" ShowInEdit="true">Cancel</GridCommandButton>
        </GridCommandColumn>
    </GridColumns>
</TelerikGrid>

@code {
        async Task UpdateHandler(GridCommandEventArgs args)
        {
            SampleData item = (SampleData)args.Item;

            if (item.ID == 0)
            {
                await CreateHandler(args);
            }
            else
            {
                // perform actual data source operations here through your service
                await MyService.Update(item);

                // update the local view-model data with the service data
                await GetGridData();

                Console.WriteLine("Update event is fired.");
            }
        }

        async Task DeleteHandler(GridCommandEventArgs args)
        {
            SampleData item = (SampleData)args.Item;

            // perform actual data source operation here through your service
            await MyService.Delete(item);

            // update the local view-model data with the service data
            await GetGridData();

            Console.WriteLine("Delete event is fired.");
        }

        async Task CreateHandler(GridCommandEventArgs args)
        {
            SampleData item = (SampleData)args.Item;

            // perform actual data source operation here through your service
            await MyService.Create(item);

            // update the local view-model data with the service data
            await GetGridData();

            Console.WriteLine("Create event is fired.");
        }

        async Task CancelHandler(GridCommandEventArgs args)
        {
            SampleData item = (SampleData)args.Item;

            // if necessary, perform actual data source operation here through your service

            Console.WriteLine("Cancel event is fired.");
        }


    // in a real case, keep the models in dedicated locations, this is just an easy to copy and see example
    public class SampleData
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }

    public List<SampleData> MyData { get; set; }

    async Task GetGridData()
    {
        MyData = await MyService.Read();
    }

    protected override async Task OnInitializedAsync()
    {
        await GetGridData();
    }

    // the following static class mimics an actual data service that handles the actual data source
    // replace it with your actual service through the DI, this only mimics how the API can look like and works for this standalone page
    public static class MyService
    {
        private static List<SampleData> _data { get; set; } = new List<SampleData>();

        public static async Task Create(SampleData itemToInsert)
        {
            itemToInsert.ID = _data.Count + 1;
            _data.Insert(0, itemToInsert);
        }

        public static async Task<List<SampleData>> Read()
        {
            if (_data.Count < 1)
            {
                for (int i = 1; i < 50; i++)
                {
                    _data.Add(new SampleData()
                    {
                        ID = i,
                        Name = "Name " + i.ToString()
                    });
                }
            }

            return await Task.FromResult(_data);
        }

        public static async Task Update(SampleData itemToUpdate)
        {
            var index = _data.FindIndex(i => i.ID == itemToUpdate.ID);
            if (index != -1)
            {
                _data[index] = itemToUpdate;
            }
        }

        public static async Task Delete(SampleData itemToDelete)
        {
            _data.Remove(itemToDelete);
        }
    }
}

---

 

0 comments