using grid hierarchy to edit nested collection

8 posts, 1 answers
  1. Casey
    Casey avatar
    9 posts
    Member since:
    Feb 2018

    Posted 01 May 2018 Link to this post

       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

  2. Preslav
    Admin
    Preslav avatar
    579 posts

    Posted 03 May 2018 Link to this post

    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.
  3. Casey
    Casey avatar
    9 posts
    Member since:
    Feb 2018

    Posted 03 May 2018 in reply to Preslav Link to this post

    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");
            }
  4. Preslav
    Admin
    Preslav avatar
    579 posts

    Posted 07 May 2018 Link to this post

    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.
  5. Casey
    Casey avatar
    9 posts
    Member since:
    Feb 2018

    Posted 07 May 2018 in reply to Preslav Link to this post

    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

  6. Answer
    Preslav
    Admin
    Preslav avatar
    579 posts

    Posted 09 May 2018 Link to this post

    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.
  7. Casey
    Casey avatar
    9 posts
    Member since:
    Feb 2018

    Posted 09 May 2018 in reply to Preslav Link to this post

    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

  8. Preslav
    Admin
    Preslav avatar
    579 posts

    Posted 10 May 2018 Link to this post

    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.
Back to Top