I have a grid when adding a new record I can fill the record in two ways:
1- Either manually entering one cell after another
2- or pressing the Shift key on the keyboard, it opens a Dialog, there is a list from which I choose an item, and when I press OK, it adds this item to the grid, but after this addition process, it must modify this record automatically through the StartEdit method
To here everything works well, but when I make a save after the editing, it saves twice, once for the record, before the editing and once after the editing. What is the reason?
this is a brief code:
<CascadingValue Value="IsNumber">
<ItemsSearch @bind-ProductDtoDescription="@searchProduct" Visibility="@VisibleDialog"
@bind-SearchValue="@searchValue" @bind-DisOkBtn="@DisOkBtn">
<DialogButtons>
<DialogButton Content="Enter" IsPrimary="true" OnClick="@OkClick" Disabled="DisOkBtn" />
<DialogButton Content="Del" />
<DialogButton Content="Esc" OnClick="@CancelClick" />
</DialogButtons>
</ItemsSearch>
</CascadingValue>
<SfGrid DataSource="@invoiceDetailsList.invoiceDetails" @ref="invoiceDetailsGrid" @onkeypress:preventDefault @onkeyup="KeyUpHandler"
Toolbar="@(new List<string>() { "Add", "Edit", "Update", "Delete", "Cancel" })">
<GridSortSettings>
<GridSortColumns>
<GridSortColumn Field="detailID" Direction="SortDirection.Ascending">
</GridSortColumn>
</GridSortColumns>
</GridSortSettings>
<GridKeySettings MoveDownCell="ArrowDown" MoveUpCell="ArrowUp" MoveLeftCell="ArrowRight" MoveRightCell="ArrowLeft"></GridKeySettings>
<GridEvents TValue="AddInvoiceDetailsDto" OnActionComplete="ActionComplete></GridEvents>
<GridEditSettings AllowAdding=" true" AllowEditing="true" AllowDeleting="true" AllowEditOnDblClick="true"
Mode="EditMode.Normal" NewRowPosition="NewRowPosition.Bottom" AllowNextRowEdit="true">
</GridEditSettings>
<GridColumns>
<GridColumn Field="@nameof(AddInvoiceDetailsDto.detailID)" IsPrimaryKey="true"></GridColumn>
<GridColumn Field="@nameof(AddInvoiceDetailsDto.titem)">
<EditTemplate>
@{
var con = context as AddInvoiceDetailsDto;
}
<input @bind-value="con.titem" @bind-value:event="oninput" id="titem"
@onkeyup="@(e=> e.Key == "Shift" ? search(con.titem,true) : null)" />
</EditTemplate>
</GridColumn>
<GridColumn Field="@nameof(AddInvoiceDetailsDto.itemDiscr)">
<EditTemplate>
@{
var con = context as AddInvoiceDetailsDto;
}
<input @bind-value="con.itemDiscr" @bind-value:event="oninput" id="itemDiscr" class="e-input text-center"
@onkeyup="@(e => e.Key == "Shift" ? search(con.itemDiscr,false) : null)" />
</EditTemplate>
</GridColumn>
</GridColumns>
</SfGrid>
private bool addRecordAfterEdit { get; set; } = false;
public string searchValue = "";
public string inputType = "";
public bool IsNumber = true;
async Task KeyUpHandler(KeyboardEventArgs e)
{
if (e.Key == "+")
{
await AddRecordMethod();
}
else if (e.Key == "ArrowLeft")
{
await _js.InvokeVoidAsync("invokeTabKey");
}
else if (e.Key == "ArrowRight")
{
await _js.InvokeVoidAsync("invokeTabShiftKey");
}
}
public async Task AddRecordMethod()
{
await invoiceDetailsGrid.AddRecordAsync();
timer?.Dispose();
}
void ActionComplete(ActionEventArgs<AddInvoiceDetailsDto> args)
{
if (args.RequestType.Equals(Syncfusion.Blazor.Grids.Action.Delete))
{
invoiceDetailsGrid.Refresh();
}
if (args.RequestType.Equals(Syncfusion.Blazor.Grids.Action.Save))
{
if (args.Action == "Add" || addRecordAfterEdit)
{
timer = new System.Threading.Timer(async (object? stateInfo) =>
{
await InvokeAsync(async () =>
{
await AddRecordMethod();
StateHasChanged();
});
},
new System.Threading.AutoResetEvent(false), 50, 50); // fire every 100 milliseconds
addRecordAfterEdit = false;
}
}
}
async Task search(string Value,bool isNumber)
{
searchValue = Value;
DisOkBtn = true;
IsNumber = isNumber;
this.VisibleDialog = true;
}
private async Task OkClick()
{
if (!preventEnterBtn)
{
invoiceDetails = new AddInvoiceDetailsDto()
{
titem = searchProduct.itmNo,
itemDiscr = searchProduct.itmADescr,
twh = searchProduct.productUnits?.FirstOrDefault().uAName,
tprice = searchProduct.itmLstCost
};
invoiceDetailsList.invoiceDetails.Add(invoiceDetails);
invoiceDetailsGrid.Refresh();
this.VisibleDialog = false;
addRecordAfterEdit = true;
timer = new System.Threading.Timer(async (object? stateInfo) =>
{
await InvokeAsync(async () =>
{
var lastIndex = invoiceDetailsList.invoiceDetails.IndexOf(invoiceDetailsList.invoiceDetails.LastOrDefault());
await invoiceDetailsGrid.SelectRowAsync(lastIndex);
edit();
StateHasChanged();
});
},
new System.Threading.AutoResetEvent(false), 50, 50); // fire every 50 milliseconds
}
}
void edit()
{
invoiceDetailsGrid.StartEdit();
timer?.Dispose();
}
Note: the ItemSearch component has a list of items which I choose from
Hi Haneen,
Greetings from Syncfusion support.
Before proceeding further kindly share the following details to validate the reported query further at our end.
In your code snippet, ItemsSearch, DialogButtons are Custom component? Please explain about that
Share the video demo of an issue and also share about the expected outcome
If possible, share issue reproducible runnable sample to us
Above requested details will be helpful for us to validate the reported query at our end and provide solution as early as possible.
Regards,
Sarveswaran PK
Hi
thanks for reply
1- the dialogButton is a component from syncfusion ,All I did was add a method for the button
2- how to share a video , I tried to share a gif image but the allowed size just 100kb
I shared the video in zip file
We are currently Validating the reported query at our end and we will update the further details shortly. Until then we appreciate your patience.
Ok,
I am waiting for your solving, please don't late,
Do you catch the problem and solve it?
Hi Haneen,
Sorry for the inconvenience.
we are currently Validating the reported query with high importance at our end and we will update the further details shortly . Until then we appreciate your patience.
Regards,
Naveen Palanivel
Hi Haneen,
Based on the given grid code, we made the simple sample but unfortunately reported issue does not occur. We also attached the sample in this forum. Can you provide the issue reproducible runnable simple sample for further validate at our end.