SFGrid - Update Field Value After Add New Record

I have seen many references to this, but nothing is quite working for me.

The SFGRID I have built is performing all CRUD operations fine.  The issue is that the primary key for the new record comes from an identity field in SQL Server.  After the Add operation, the record is created in the database.  The PK field is set to zero.  I have tried to do a grid.refresh in the ActionCompleteHandler.  This is not helping.


To initially load the grid, the code looks like this:

protected override async Task OnInitializedAsync()

        {

            ServerTypes = (await LookupDataDataService.GetServerTypes()).ToList();


            FileHeadersTemplateA = (await FileTemplateHeaderDataService.GetFileTemplateHeaders()).ToList();

        }


The grid column that needs refreshing after the ADD function is defined as follows

<GridColumn Field=@nameof(FileTemplateHeader.Ftsan) HeaderText="FTSAN" IsPrimaryKey="true" LockColumn="true" AllowAdding="false" TextAlign="TextAlign.Center" MinWidth="10" Width="4" />


The question is, how do I force the bound dataset get the new ID field from the database?  Do I need to re-read all records for the dataset?  Can I just get the ID value for the record that was just added?


Thanks,

M




12 Replies

JP Jeevakanth Palaniappan Syncfusion Team September 27, 2021 10:17 AM UTC

Hi Marc, 

Greetings from Syncfusion support. 

We have validated your query and we suspect that the added data gets saved in the database but the primarykey value is not refreshed in the grid. If so, in these cases it is recommend to use the Custom adaptor feature to achieve your requirement. 

In custom adaptor, the data is set in the Read method and you have to return the added/edited/deleted data in the Custom adaptor’s Insert/Update/Remove methods and also you can execute the codes which needs to be updated to the database in the Insert/Update/Remove methods. Now when the grid is re-rendered, the Read method of Custom adaptor will be executed and the new data is fetched from your service in Read method and the added record will be refreshed in the grid. 

Please refer the below documentation for your reference. 


Get back to us if you have any other queries. 

Regards, 
Jeevakanth SP. 



MA Marc September 27, 2021 08:41 PM UTC

Thanks for the response.  I can say I really do not even know where to start with this on.  do you have a sample project with the custom adaptor in it I can look at?


Thanks,

Marc.



MA Marc September 27, 2021 08:53 PM UTC

Also, I sometimes am seeing notation to EJ2.  I assume this is referring to an older version or naming standard?



JP Jeevakanth Palaniappan Syncfusion Team September 28, 2021 01:46 PM UTC

Hi Marc, 

Query :Custom Adaptor sample 

We have prepared a custom adaptor sample for your reference. Please find it below. 


Documentation  

Query : I sometimes am seeing notation to EJ2.  I assume this is referring to an older version or naming standard? 
 
We are quite unclear about your query. Could you please share more information about your query and also kindly share us a screenshot/video demo showing the problem you are facing. 

Regards, 
Jeevakanth SP. 




MA Marc September 28, 2021 05:00 PM UTC

Thank you for the code example.  Extremely helpful.  I have some questions.  The functionality looks like what I am after.


  • How is the READ method triggered when the razor page first loads?

  • In the DataGridFeatures.razor file there is an INSERT Method

    • How/why does clicking the update button in the grid toolbar invoke this method?  Is this a reserved word?  I was looking for documentation on this but could not find anything.




  • Why/how after the INSERT method does the READ method get called

    • Is that a default of the adaptor?




  • In the INSERT method (all of them) they have a return value statement

      •  What is it returning that to?


  • In READ method - where are the dataManagerRequest values coming from in the parameter?




In regards to EJ2, I see it on this page https://help.syncfusion.com/cr/aspnetcore-js2/Syncfusion.EJ2.Base.DataManagerRequest.html   I also download a sample project from git that had this declaration in it. 


JP Jeevakanth Palaniappan Syncfusion Team September 29, 2021 02:23 PM UTC

Hi Marc, 
 
Please find the answers for your queries below. 
 
Query : How is the READ method triggered when the razor page first loads? 
Query : In READ method - where are the dataManagerRequest values coming from in the parameter? 
The Read method will be invoked from the grid source to set the grid datasource which you will return in the form of Result, Count. Also you can perform/customize the data operations. On performing every data operation, you will get the corresponding action query in the DataManagerRequest of read method which is passed from our grid source. So using this, you can customize based on your requirement 
Query : How/why does clicking the update button in the grid toolbar invoke this method?  Is this a reserved word?  I was looking for documentation on this but could not find anything. 
On performing the CRUD operation, the Insert/Update/Remove methods will be triggered which is the default behavior of custom adaptor. The custom adaptor feature is to customize the data operations and CRUD operations. In these method, you will be customizing CRUD/ handling the codes which you need to update to the database. 
Documentation   
 
Query : In the INSERT method (all of them) they have a return value statement 
As we said, the customer adaptor is to customize the CRUD/data operations based on your requirement. So the customized values has to be returned in the methods so that it will be further processed by the grid in our source. 
 
Query : In regards to EJ2, I see it on this page 
 
EJ2 grid will be available in the Javascript/Typescript/React/Angular/MVC/Core. The shared link is related to Core and not related to blazor framework. You can refer the below link for blazor framework. 
 
 
Also we suggest you to once go through the below documentation regarding the custom adaptor. 
 
Please get back to us if you have any other queries. 
 
Regards, 
Jeevakanth SP. 



MA Marc September 29, 2021 02:51 PM UTC

Thanks for the detailed reply. 


I quick followup question.  Are you saying that the object/component is tracking the state of the grid.  so it knows I am in insert mode.  When I hit the update button, it inserts a record.  That I get.  Is triggering the read after the update a default behaviour of the adaptor?   Could I prevent that behaviour from happening if I wanted?



JP Jeevakanth Palaniappan Syncfusion Team September 30, 2021 05:32 AM UTC

Hi Marc, 

Please find the details of your query below. 

Query: Are you saying that the object/component is tracking the state of the grid.  so it knows I am in insert mode.  When I hit the update button, it inserts a record.  
 
Yes, when you add a record and hit the update button, the grid know that you are in insert mode and trying to save the newly added record. 
 
Query: Is triggering the read after the update a default behavior of the adaptor?   Could I prevent that behavior from happening if I wanted? 
 
No, the read method will be triggered. This is the default behavior and it cannot be prevented. 
 
Regards, 
Jeevakanth SP. 



MA Marc September 30, 2021 11:59 AM UTC

Jeevakanth.


I think you have covered all of my questions on this topic.  Thanks for you patience on this.  Is there any documentation on these order of events?


Marc.



JP Jeevakanth Palaniappan Syncfusion Team October 1, 2021 11:35 AM UTC

Hi Marc, 

Query: Is there any documentation on these order of events? 
 
We are quite unclear about your query. We suspect that you want to know the order of the Read/Insert/Update/Remove methods triggered. If so, the Insert/Update/Remove methods will be triggered when you are performing the Insert/Update/Remove CRUD operations. The Read method will be triggered during the rendering of the grid/refreshing the grid. 

Regards, 
Jeevakanth SP. 



MA Marc October 4, 2021 08:41 PM UTC

Hi Jeevakanth.


I have reviewed the documentation and sample you provided, and believe I understand how it works.


To make things a bit more challenging, my app uses a REST API as a data source with the razor page have a partial CS code class. This part works fine. In my version, the dbcontext, controller and repository reside on the REST server and are obviously not accessible by the razor page.


The CS looks like this:

namespace dataCatAdminBLZ.App.Pages

{

    public partial class FileTemplateHeaderSFG

    {

        [Inject]

        public IFileTemplateHeaderDataService FileTemplateHeaderDataService { get; set; }

        [Inject]

        public ILookupDataServiceApp LookupDataDataService { get; set; }

        [Inject]

        public NavigationManager NavManager { get; set; }

        public IEnumerable<FileTemplateHeader> FileHeadersTemplateA { get; set; }

        public List<LookupLists> ServerTypes { get; set; } = new List<LookupLists>();

 ....


        protected override async Task OnInitializedAsync()

        {

            ServerTypes = (await LookupDataDataService.GetServerTypes()).ToList();

            FileHeadersTemplateA = (await FileTemplateHeaderDataService.GetFileTemplateHeaders()).ToList();

        }



In the example you provided for the the custom adaptor, the content is local. I am struggling to adapt my REST code to your example. I am definitely not doing something correctly. I have put the data-adaptor class within the partial class. I know this code is not correct, but what I am trying to do is get rid of the dbcontext references. My data will come back through the FileHeadersTemplateA = (await FileTemplateHeaderDataServiceINJ.GetFileTemplateHeaders()).ToList(); call.


I am also finding the scoping of variable between the 2 classes is not correct, hence I am repeating the definition.


Any guidance here would be greatly appreciated.  If you have a sample project with custom adaptor and REST, that would also be very welcome.


thanks,

Marc.



Code as I have tried so far:


namespace dataCatAdmin.App.Pages

{

    public partial class FileTemplateHeaderSFG_B

    {

        //[Inject]

        //public IFileTemplateHeaderDataService FileTemplateHeaderDataServiceINJ { get; set; }

        [Inject]

        public ILookupDataServiceApp LookupDataDataServiceINJ { get; set; }


        [Inject]

        public NavigationManager NavManager { get; set; }




        public IEditorSettings SvrClsParams = new DropDownEditCellParams

        {

            Params = new DropDownListModel<object, object>() { AllowFiltering = true, ShowClearButton = true }

        };


        SfGrid<FileTemplateHeader> GridHead;

        //public IEnumerable<FileTemplateHeader> FileHeadersTemplateA { get; set; }


        public List<LookupLists> ServerTypes { get; set; } = new List<LookupLists>();



        public string BannVal = "File Template Headers B";



        protected override async Task OnInitializedAsync()

        {

            ServerTypes = (await LookupDataDataServiceINJ.GetServerTypes()).ToList();

            FileHeadersTemplateA = (await FileTemplateHeaderDataServiceINJ.GetFileTemplateHeaders()).ToList();

        }



//This is where things I think go off the rails.

        public class CustomAdaptor2 : DataAdaptor

        {

            [Inject]

            public IFileTemplateHeaderDataService FileTemplateHeaderDataServiceINJ { get; set; }


            [Inject]

            public ILookupDataServiceApp LookupDataDataServiceINJ { get; set; }


            public IEnumerable<FileTemplateHeader> FileHeadersTemplateA { get; set; }


            ServerTypes = CustomAdaptor2.LookupDataDataServiceINJ.GetServerTypes()).ToList();

            FileHeadersTemplateA = (await FileTemplateHeaderDataServiceINJ.GetFileTemplateHeaders()).ToList();



            // Performs data Read operation

            public override object Read(DataManagerRequest dm, string key = null)

            {

                DataResult DataObject = new DataResult();


                if (dm.Search != null && dm.Search.Count > 0)

                {

                    // Searching

                    FileHeadersTemplateA = DataOperations.PerformSearching(FileHeadersTemplateA, dm.Search);

                }


                if (dm.Sorted != null && dm.Sorted.Count > 0)

                {

                    // Sorting

                    FileHeadersTemplateA = DataOperations.PerformSorting(FileHeadersTemplateA, dm.Sorted);

                }


                if (dm.Where != null && dm.Where.Count > 0)

                {

                    // Filtering

                    FileHeadersTemplateA = DataOperations.PerformFiltering(FileHeadersTemplateA, dm.Where, dm.Where[0].Operator);

                }


                int count = FileHeadersTemplateA.Cast<FileTemplateHeader>().Count();

                if (dm.Skip != 0)

                {

                    //Paging

                    FileHeadersTemplateA = DataOperations.PerformSkip(FileHeadersTemplateA, dm.Skip);

}


                if (dm.Take != 0)

                {

                    FileHeadersTemplateA = DataOperations.PerformTake(FileHeadersTemplateA, dm.Take);

                }

                return dm.RequiresCounts ? new Syncfusion.Blazor.Data.DataResult() { Result = FileHeadersTemplateA, Count = count } : (object)FileHeadersTemplateA;

            }




JP Jeevakanth Palaniappan Syncfusion Team October 5, 2021 01:17 PM UTC

Hi Marc, 

We have checked your query and we suggest you to refer the below documentation to use the dbcontext in the custom adaptor class. 

Get back to us if you have any other queries. 

Regards, 
Jeevakanth SP. 


Loader.
Up arrow icon