havit / Havit.Blazor

Free Bootstrap 5 components for ASP.NET Blazor + optional enterprise-level stack for Blazor development (gRPC code-first, layered architecture, localization, auth, ...)
https://havit.blazor.eu
MIT License
475 stars 66 forks source link

HxGrid Inline editing HandleSelectedDataItemChanged.after sends wrong edititemrow #756

Closed bluisanajmr closed 6 months ago

bluisanajmr commented 6 months ago

Hello,

I have noticed strange behavior with inline editing using the HandleSelectedDataItemChanged.after.

Using an example grid like below.

image

`private InvoiceLineItemGrid edititem;

 <HxGrid MultiSelectionEnabled="true" @bind-SelectedDataItems="MultiInvoiceLineItems"
 @ref="InvoiceLineItemDataGrid" TItem="InvoiceLineItemGrid" Responsive="true" DataProvider="GetGridData" PageSize="10" 
 @bind-SelectedDataItem:after="HandleSelectedDataItemChanged"
 @bind-SelectedDataItem="edititem">

public async Task HandleSelectedDataItemChanged()
{
    //edititem is always data from the clicked row without changes
    //shouldn't this be the changed data from the previously edited row?
    if (edititem != null)
    {
        //we just remove and add edited items
        await _InProcessLineItems.RemoveInvoiceLineItemAsync(edititem.Id);

        await _InProcessLineItems.AddInvoiceLineItemAsync(edititem);

    }
}
`

if you click on the second row of this grid (Order = 2) the HandleSelectedDataItemChanged fires and you get the edititem data for (Order = 2) while in this method. This is great but I haven't changed any data on that row yet. Now I change the description of this row to 3 and then click on the 3rd row (Order = 3) .

The 3rd row becomes inline editable and HandleSelectedDataItemChanged fires again but the edititem is now (order = 3) instead of my edited data from (order = 2). The grid shows the correct changes but I have no way to save the changes I made to (order =2) back to the database? All I can do is get the current values for the rows that are clicked on before I make any changes to them.

Am I completely missing something or is this a bug?

hakenr commented 6 months ago

The SelectedDataItem parameter does represent the current item selected in the grid. The @bind-SelectedDataItem:after="..." is called after the value changes, e.g. after the selection changes (= the new value is already in edititem.

If you want to save the changes "when another item is selected", you need to use the original value of editItem. Try this approach:

<HxGrid SelectedDataItem="edititem" SelectedDataItemChanged="HandleSelectedDataItemChanged" ...>

@code {
  private InvoiceLineItemGrid editItem;
  public async Task HandleSelectedDataItemChanged(InvoiceLineItemGrid newSelectedDataItem)
  {
     // at the beginning, the editItem still holds the original item selected
     // save it here

    editItem = newSelectedDataItem; // this is needed when you use custom `SelectedDataItemChanged` handling, this is what was missing in your orignal approach #755 

    // the rest of the method is analogous to @bind-SelectedDataItemChanged:after="...",
    // the editItem is already populated with the newSelectedDataItem
  }
}