This is a migrated thread and some comments may be shown as answers.

using grid hierarchy to edit nested collection

7 Answers 722 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Casey
Top achievements
Rank 1
Casey asked on 01 May 2018, 09:20 PM

   is there a way to use the grid hierarchy to edit nested collections when you need the database generated ID to apply to the nested collection?  I have the grids and controllers set up, but i don't know how to send the ID to the nested collection.

cshtml

@(Html.Kendo().Grid<DeploymentRequestV2>()
                                .Name("DeploymentRequestGrid")
                                .HtmlAttributes(new { style = "margin-top:10px" })
                                .Columns(col =>
                                {
                                    col.Bound(d => d.RequestId).Hidden();
                                    col.Bound(d => d.DeploymentTitle);
                                    col.Bound(d => d.DeploymentId);
                                    col.Bound(d => d.ExtReqId);
                                    col.Bound(d => d.ElevatedUatApproval);
                                    col.Bound(d => d.PhaseId);
                                    col.Bound(d => d.DbaInstructions);
                                    col.Bound(d => d.Comments);
                                    //col.Bound(d => d.AttachmentFolderName);
                                })
                                .ClientDetailTemplateId("RequestStepsSubScript")
                                .DataSource(ds => ds
                                .Ajax()
                                .ServerOperation(true)
                                .Model(m =>
                                {
                                    m.Id(d => d.RequestId);
                                })
                                .Create("Create", "DeploymentRequestGrid")
                                .Read("GetById", "DeploymentRequestGrid"))
                                .Events(e=>e.DataBound("dataBound"))
                                .Pageable()
 
    )
</div>
<script id="RequestStepsSubScript" type="text/kendo-tmpl">
    @(Html.Kendo().Grid<DeploymentRequestSteps>()
                .Name("grid_#=RequestId#")
                .Columns(col =>
                {
                    col.Bound(d => d.RequestStepId).Hidden();
                    col.ForeignKey(d => d.TypeId, (System.Collections.IEnumerable)ViewBag.ListOfDeploymentTypes, "TypeId", "DeploymentType1").Title("Type");
                    col.ForeignKey(d => d.DbserverId, (System.Collections.IEnumerable)ViewBag.ListOfDBServers, "DbserverId", "FriendlyName").Title("DatabaseServer");
                    col.Bound(d => d.SsrsReportFolder);
                    col.ForeignKey(d => d.SsrsServerId, (System.Collections.IEnumerable)ViewBag.ListOfAllReportServers, "SsrsServerId", "SsrsServerName").Title("Ssrs Server");
                    col.Bound(d => d.IsComplete);
                    col.Bound(d => d.ExecutionTimeOnDev);
                    col.Bound(d => d.SourcePath).Hidden();
                    col.Bound(d => d.StepOrder).Hidden();
                    col.Bound(d => d.TfsMapId).Hidden();
                    col.Bound(d => d.ChangeSetId).Hidden();
                    col.Bound(d => d.CheckedInBy).Hidden();
                    col.Bound(d => d.CheckedInDate).Hidden();
                    col.Command(cmd => { cmd.Destroy(); });
                })
                .DataSource(ds => ds
                .Ajax()
                .Read(read => read.Action("GetById", "DeploymentRequestStepsSubGrid", new { id = "#=RequestId#" }))
                .Create(create=>create.Action("Create", "DeploymentRequestStepsSubGrid",new {id = "#=RequestId#" }))
                )
                .Pageable()
                .Scrollable()
                .ToClientTemplate()
    )
</script>

parent grid read and create controller

public IActionResult GetById([DataSourceRequest]DataSourceRequest request, string id)
        {
            return Json(_context.DeploymentRequestV2.Where(x => x.RequestId.ToString() == id).ToDataSourceResult(request));
        }
        public async Task<IActionResult> Create([DataSourceRequest]DataSourceRequest request, [Bind("DeploymentTitle", "DeploymentId", "ExtReqId", "ElevatedUatApproval", "DbaInstructions", "Comments", "AttachmentFolderName", "PhaseId", "RequestedBy", "RequestedDate")] DeploymentRequestV2 deploymentrequestv2)
        {
            try
            {
                if (ModelState.IsValid)
                {
 
                    _context.Add(deploymentrequestv2);
                    await _context.SaveChangesAsync();
                    ViewBag.RequestId = deploymentrequestv2.RequestId;
                    int returnid = deploymentrequestv2.RequestId;
                    return View(deploymentrequestv2);
                }
            }
            catch (DbUpdateException err)
            {
                ModelState.AddModelError("", "Unable to save changes to the request. " + err.InnerException);
                return View();
            }
            return RedirectToAction(nameof(Index));
        }

child grid read and create controller

public IActionResult GetById([DataSourceRequest]DataSourceRequest request, string id)
        {
            return Json(_context.DeploymentRequestV2.Where(x => x.RequestId.ToString() == id).ToDataSourceResult(request));
        }
        public async Task<IActionResult> Create([DataSourceRequest]DataSourceRequest request, [Bind("DeploymentTitle", "DeploymentId", "ExtReqId", "ElevatedUatApproval", "DbaInstructions", "Comments", "AttachmentFolderName", "PhaseId", "RequestedBy", "RequestedDate")] DeploymentRequestV2 deploymentrequestv2)
        {
            try
            {
                if (ModelState.IsValid)
                {
 
                    _context.Add(deploymentrequestv2);
                    await _context.SaveChangesAsync();
                    ViewBag.RequestId = deploymentrequestv2.RequestId;
                    int returnid = deploymentrequestv2.RequestId;
                    return View(deploymentrequestv2);
                }
            }
            catch (DbUpdateException err)
            {
                ModelState.AddModelError("", "Unable to save changes to the request. " + err.InnerException);
                return View();
            }
            return RedirectToAction(nameof(Index));
        }

I feel like i'm close but can't quite get it working

7 Answers, 1 is accepted

Sort by
0
Preslav
Telerik team
answered on 03 May 2018, 12:19 PM
Hi Casey,

Based on the provided description, I am not sure what is not working. Could you please elaborate?

In the meantime, I believe that you will be interested in checking these demos:
I look forward to your reply.


Regards,
Preslav
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Casey
Top achievements
Rank 1
answered on 03 May 2018, 02:58 PM

My parent grid will create a record with the below create method and return back the database generated ID.  Then it runs the child grids create method and passes along the ID.

public async Task<IActionResult> Create([DataSourceRequest]DataSourceRequest request, [Bind("DeploymentTitle", "DeploymentId", "ExtReqId", "ElevatedUatApproval", "DbaInstructions", "Comments", "AttachmentFolderName", "PhaseId", "RequestedBy", "RequestedDate","DeploymentRequestSteps")] DeploymentRequestV2 deploymentrequestv2)
        {
            deploymentrequestv2.PhaseId = 1;
 
            try
            {
                if (ModelState.IsValid)
                {
 
                    _context.Add(deploymentrequestv2);
                    await _context.SaveChangesAsync();
                    ViewBag.RequestId = deploymentrequestv2.RequestId;
                    int returnid = deploymentrequestv2.RequestId;
                    return RedirectToAction("Create", "DeploymentRequestStepsSubGrid", new { id = returnid.ToString() });
                    //return View(deploymentrequestv2);
                }
            }
            catch (DbUpdateException err)
            {
                ModelState.AddModelError("", "Unable to save changes to the request. " + err.InnerException);
                return View();
            }
            return RedirectToAction(nameof(Index));
        }

 

The child grid create method will run using the below method, but the data from the grid is never captured and "steps" is always a blank object except for the ID i passed it.  I don't understand why this is happening and how i can get the data from the child grid

public async Task<IActionResult> Create([DataSourceRequest]DataSourceRequest request, DeploymentRequestSteps steps, string id)
        {
            steps.RequestId = Convert.ToInt32(id);
            try
            {
                if (ModelState.IsValid)
                {
                    steps.RequestId = Convert.ToInt32(id);
                    _context.DeploymentRequestSteps.Add(steps);
                    await _context.SaveChangesAsync();
                    return View();
                }
            }
            catch (DbUpdateException err)
            {
                ModelState.AddModelError("", "Unable to save changes to the request. " + err.InnerException);
                return View();
            }
            return RedirectToAction("Index","RequestForm");
        }
0
Preslav
Telerik team
answered on 07 May 2018, 12:34 PM
Hello Casey,

I checked the provided code again, and I am still not sure how it is working. Could you elaborate on the following:

1) In both master and child grids, there is not "Create" command:

.ToolBar(toolbar => {
    toolbar.Create();
})

Could you share how the user creates new records?

2) Both grids are not editable:

.Editable(editable => editable.Mode(GridEditMode.InCell)) // or GridEditMode.InLine; or GridEditMode.PopUp

How the user edits the newly created records?

3) In the child grid there is a destroy command:

col.Command(cmd => { cmd.Destroy(); });

However, there is not Destroy configuration of the dataSource:

.Destroy(destroy=>destroy.Action("Destroy", "DeploymentRequestStepsSubGrid"))

This should result in a runtime exception.

4) What is the following code doing?

public async Task<IActionResult> Create([DataSourceRequest]DataSourceRequest request, [Bind("DeploymentTitle", "DeploymentId", "ExtReqId", "ElevatedUatApproval", "DbaInstructions", "Comments", "AttachmentFolderName", "PhaseId", "RequestedBy", "RequestedDate","DeploymentRequestSteps")] DeploymentRequestV2 deploymentrequestv2)

I do not think this is required. For example, check the demos from my last reply or this Demo(click "EditingController.cs" tab):
Finally, it will help me a lot to understand the scenario faster if you can prepare and share a sample runnable project that clearly replicates the scenario.

I look forward to hearing from you.


Regards,
Preslav
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Casey
Top achievements
Rank 1
answered on 07 May 2018, 02:55 PM

Hi Preslav,

I've numbered the below to answer your questions.

1) I've created buttons to add records to the grids.  When clicked, the create buttons add the data to the datasource using javascript like the below.  

ds.dataSource.insert({ RequestId: 0, DeploymentTitle: dtitle, DeploymentId: depid, ExtReqId: rfc, DbaInstructions: dba, Comments: comments, RequestedDate: reqdate, RequestedBy: reqby, ElevatedUatApproval: uat, AttachmentFolerName: attach, DeploymentRequestSteps: [{
                    TypeId: 0, DbserverId: 0, SsrsReportFolder: '', SsrsServerId: 1, IsComplete: true,
                    ExecutionTimeOnDev: '0:0:0', SourcePath: '', StepOrder: 0, TfsMapId: 6
                }]
            });

2) users are not allowed to edit records within the grid.  they must cancel the record and create a new one.  I created the cancel buttons that will cancel records buy running javascript like the below.

$("#DeploymentRequestGrid").data("kendoGrid").cancelChanges();

3) there is no destroy or delete option for the users and I've removed the code you mentioned

4) that code is used to prevent over posting on columns that are a part of the model, that are not populated by this grid.  it's not necessary to successfully create a record but it's useful to have for security practices.  

I will prepare a small solution to replicate this problem and share it when it is complete.

 

Thanks

0
Accepted
Preslav
Telerik team
answered on 09 May 2018, 10:25 AM
Hello Casey,

Thank you for the answers. Now, I do better understand the scenario.

I look forward to the small solution that you are preparing.


Regards,
Preslav
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Casey
Top achievements
Rank 1
answered on 09 May 2018, 02:26 PM

hi Preslav,

i found a solution to this issue, but i used two separate grids instead of hierarchical grids.  i used 1 grid to create a record and submit it to the database then had the second grid subscribed to the sync event of the first. that way the returned value from the first grid could be passed on to the second grid so that it could be used in the database insert from the second grid as well.  sorry if this was confusing or a waste of your time, i'm still learning how to use the grids.

thanks for your help

0
Preslav
Telerik team
answered on 10 May 2018, 12:19 PM
Hello Casey,

I am glad to hear that the issue is now resolved.

Thank you very much for sharing the solution with me and the community.


Regards,
Preslav
Progress Telerik
Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Tags
Grid
Asked by
Casey
Top achievements
Rank 1
Answers by
Preslav
Telerik team
Casey
Top achievements
Rank 1
Share this question
or