I've spotted this in v20.3.0.60 and 20.3.0.59, I had it working in test projects on early versions.
I've got a grid displaying data from our SQL server database via EF and a service. I've allowed editing, and tried both Normal and Dialog methods of edit to try and get this working. I've since created a cut back Blazor component to try and remove some of the code and functionality to try and get the basic display / edit row / update model functionality working, but its stumped me for a couple of days now.
Either double clicking, or adding a toolbar "Edit" command switches to edit mode fine in my grid, and I can edit fields (I've opened up all fields for testing but the use case will be that only the right most code should be edited). BUT the changes don't apply - I can see in your demos clicking or tabbing on another row in the inline mode should trigger the 'save' - or in the model dialog box clicking 'Save' should save. In the model dialog the Save does nothing, only the cancel closes the window wiping out the change, and in the Normal inline mode, even with the control icon column displayed (and the icon appearing on a change), the icon doesn't trigger or fire any events, so nothing is saved.
I've also tried the Save in the toolbar and again that does not fire events. I've run in debug and added console code to try and trap any call to save in either OnActionBegin or OnActionComplete and while I see the initial Edit event fire, the save never gets triggered.
I've set both the IsPrimaryKey="true" IsIdentity="true" against the PK column as I realised that has to be set to allow CRUD to work.
Code of the razor component:
@page "/item-coll"
@using BusinessCentralDatabase.Data.Models;
@using BusinessCentralDatabase.Data.Interfaces;
@using Syncfusion.Blazor.Grids;
@inject IItemCollectionService ItemCollectionService
<div class="col-lg-12">
<div class="control-wrapper">
<SfGrid DataSource="@ItemCollections" TValue="ItemCollection" @ref="IcGrid" ID="Grid"
Toolbar="@(new List<string>() {"Edit", "Update"})">
<GridEditSettings AllowAdding="true" AllowDeleting="false" AllowEditing="true" Mode="EditMode.Normal"></GridEditSettings>
<GridSelectionSettings Type="Syncfusion.Blazor.Grids.SelectionType.Single"></GridSelectionSettings>
<GridEvents OnToolbarClick="ToolbarClick" TValue="ItemCollection" OnActionBegin="ActionBeginHandler" OnActionFailure="ActionFailure" OnActionComplete="ActionCompleteHandler"></GridEvents>
<GridColumns>
<GridColumn Field="@nameof(ItemCollection.ProductId)" HeaderText="Prod ID" Visible="true" Width="70px" IsPrimaryKey="true" IsIdentity="true" ></GridColumn>
<GridColumn Field="@nameof(ItemCollection.ProductName)" HeaderText="Title Name" Visible="true" Width="240px" ></GridColumn>
<GridColumn Field="@nameof(ItemCollection.IssueCode)" HeaderText="Issue Ref" Visible="true" Width="100px" ></GridColumn>
<GridColumn Field="@nameof(ItemCollection.ShortDescription)" HeaderText="Description" Visible="true" Width="100px" Type="ColumnType.Number" Format="c"></GridColumn>
<GridColumn Field="@nameof(ItemCollection.MainOnSaleDate)" HeaderText="On-sale" Format="d" Visible="true" Width="65px" ></GridColumn>
<GridColumn Field="@nameof(ItemCollection.MainOffSaleDate)" HeaderText="Off-sale" Format="d" Visible="true" Width="65px" ></GridColumn>
<GridColumn Field="@nameof(ItemCollection.CoverPrice)" HeaderText="Coverprice" Visible="true" TextAlign="TextAlign.Right" Width="75px" Format="C2" ></GridColumn>
<GridColumn Field="@nameof(ItemCollection.RunOnCost)" HeaderText="Run On Cost" Visible="true" TextAlign="TextAlign.Right"
EditType="EditType.NumericEdit" Width="100px" ValidationRules="@(new ValidationRules{ Required=true, Range = new object[]{0, 10}})" ></GridColumn>
<GridColumn HeaderText="Manage Records" Width="150">
<GridCommandColumns>
<GridCommandColumn Type="CommandButtonType.Edit" ButtonOption="@(new CommandButtonOptions() {IconCss="e-icons e-edit", CssClass="e-flat" })"></GridCommandColumn>
<GridCommandColumn Type="CommandButtonType.Save" ButtonOption="@(new CommandButtonOptions() {IconCss="e-icons e-save", CssClass="e-flat" })"></GridCommandColumn>
<GridCommandColumn Type="CommandButtonType.Cancel" ButtonOption="@(new CommandButtonOptions() {IconCss="e-icons e-cancel-icon", CssClass="e-flat" })"></GridCommandColumn>
</GridCommandColumns>
</GridColumn>
</GridColumns>
</SfGrid>
</div>
</div>
@code {
SfGrid<ItemCollection>? IcGrid ;
private DateTime Start { get; set; }
private DateTime End { get; set; }
public IEnumerable<ItemCollection>? ItemCollections { get; set; }
public ItemCollection? SelectedItemCollection { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
// I think need to use this version, as server side pre-renders on the server, so we need to show spinner after initial render.
if (firstRender)
{
await LoadData();
StateHasChanged();
}
}
// load the main data list - nice place to use a lamda as there's a simple 'do this' method.
public async Task LoadData()
{
int SelectedProductId = 55;
Start = DateTime.Now;
End = DateTime.Now.AddMonths(6);
// hardcode a few things to start!
ItemCollections = await ItemCollectionService.GetItemCollectionsForUserAsync("Frontline-1\\Kristian Brown", SelectedProductId, Start, End);
Console.WriteLine($"data loaded for mag id {SelectedProductId}, num rows = {ItemCollections?.Count() ?? 0}"); // the ?? is like an 'if null' test. the ? does the check
}
public async Task ActionBeginHandler(ActionEventArgs<ItemCollection> args)
{
Console.WriteLine($"ARGS: {args.RequestType} {args.Action}");
if (args.RequestType.Equals(Syncfusion.Blazor.Grids.Action.Save))
{
if (args.Action == "Add")
{
try
{
Console.WriteLine("GOT SAVE / ADD");
}
catch (Exception Ex)
{
Console.WriteLine("GOT THERE EXCEPTION ");
}
}
else // update
{
try
{
Console.WriteLine("GOT SAVE UPDATE");
}
catch (Exception Ex)
{
Console.WriteLine("GOT AN EXCEPTION ");
}
}
}
if (args.RequestType.Equals(Syncfusion.Blazor.Grids.Action.Delete))
{
try
{
Console.WriteLine("GOT THE DELETE");
}
catch (Exception Ex)
{
Console.WriteLine("GOT AN EXCEPTION ");
}
}
}
public async Task ActionCompleteHandler(ActionEventArgs<ItemCollection> args)
{
Console.WriteLine($"ARGS: {args.RequestType} {args.Action} {args.Data?.ToString()}");
if (args.RequestType == Syncfusion.Blazor.Grids.Action.Save)
{
// Triggers once save operation completes
Console.WriteLine("*********** COMPLETED SAVE spotted");
}
else
{
Console.WriteLine($"ARGS: {args.RequestType}");
}
}
public void ToolbarClick(Syncfusion.Blazor.Navigations.ClickEventArgs args)
{
Console.WriteLine($"ARGS: {args.ToString} : {args.Item.Id}");
}
public void ActionFailure(Syncfusion.Blazor.Grids.FailureEventArgs args)
{
Console.WriteLine($"ERROR: {args.Error.Message} {args.Error.Source} {args.Error.StackTrace}");
}
}
OK please ignore - unless someone else gets the same and pulls their hair out too :-)
It turns out the problem is due to the odd nature of the database I'm mapping too - it's a Business Central database, where all columns are non nullable. Business central puts a space into text fields, zeros in numbers.
The entity framework mapped some of those columns as [required]
I only included a fraction of the columns on the huge table in my screen - what I'd not realised was, if a required column on the model object does not have a column in the sfgrid screen, you don't see any validation error, so it quietly fails with no errors, and just ignores the 'save' calls - validation silently fails but nothing is displayed on screen and no events trigger.
As I don't need to display or want to edit those fields, I've changed my mapping removing the 'required' from those technically 'null' columns, and now the save works a
Hi Kristian ,
Welcome
We are glad to hear that your query has been resolved by you.
Please get back to us if you need further assistance.
Regards,
Naveen Palanivel.
OMG! I was almost a day trying to find a solution to similar problem. Find that my EF has 3 [required] fields that I dont use on Grid...
Hi Lindolfo,
Thanks for an update.
Mentioned issue has been resolved by own at your end.
If you have any further queries in this, please get back to us.
Regards,
Sarvesh