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

Creating new row in nested Grid: How do I get parent key?

10 Answers 603 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Shea
Top achievements
Rank 1
Shea asked on 19 Jul 2013, 06:22 AM
I have spent the night searching, and can't seem to find an answer for what must be a fairly common question.

I have a grid of 'Clients'. The client grids detail template is a grid of Licenses. Everything works fine, except when I add a row to the license grid, I can't  get access to the Client's Id column.

ViewModel
public class LicenseClient
{
    public int Id { get; set;  }
    public String Name { get; set; }
    public String Email { get; set; }
    public String City { get; set; }
    public int NumLicenses { get; set; }
}
 
public class LicenseInfo
{
    public int ClientId { get; set; }
    public Guid LicenseId { get; set; }
    public String Product { get; set; }
    public int Count { get; set; }
    public String Notes { get; set; }
}
My View:
@{
    ViewBag.Title = "Index";
}
 
<h2>Client Licenses</h2>
 
@(
    Html.Kendo().Grid<CoreLM.Models.ViewModels.LicenseClient>()
        .Name("clientGrid")
        .Columns( columns => {
            columns.Bound(c => c.Name);
            columns.Bound(c => c.City);
            columns.Bound(c => c.Email);
            columns.Bound(c => c.NumLicenses).Title("Total Licenses");
        })
        .DataSource(ds => ds.Ajax()
            .Read(r => r.Action("GetLicenseClients", "License"))
        )
        .Sortable()
        .Scrollable()
        .HtmlAttributes(new { style = "height:500px;" })
        .ClientDetailTemplateId("ClientLicenseDetailTemplate")
)
 
<script id="ClientLicenseDetailTemplate" type="text/kendo-tmpl" >
@(
 Html.Kendo().Grid<CoreLM.Models.ViewModels.LicenseInfo>()
        .Name("clientLicensesGrid_#=Id#")
        .Columns(columns =>
        {
            columns.Bound(c => c.Product);
            columns.Bound(c => c.Count).Title("Licenses");
            columns.Bound(c => c.Notes);
            columns.Command(c => c.Destroy());
            columns.Command(c => c.Edit());
        })
        .DataSource(ds => ds.Ajax()
            .Read(r => r.Action("GetLicensesForClient", "License", new { clientId = "#=Id#" }))
            .Create(c => c.Action("CreateLicenseForClient", "License", new { clientId = "#=Id#}))
            .Update(u => u.Action("ChangeLicensesForClient", "License"))
            .Destroy(d => d.Action("DeleteLicensesForClient", "License"))
            .Model(m => {
                m.Id(l => l.LicenseId);
            })
        )
        .ToolBar(tb => tb.Create())
        .Scrollable()
        .Sortable()
        .Editable()
        .ToClientTemplate()
)
</script>
My Controller method for creating a new license:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreateLicenseForClient([DataSourceRequest]DataSourceRequest request, int clientId, LicenseInfo li)
{
            //clientId is always 0
}

I have even tried hard coding an Id, and it still doesn't work:
.Create(c => c.Action("CreateLicenseForClient", "License", new { clientId = 99}))

and in my controller method, 'clientId' is still 0.

How can I pass the client (parent) id to the CreateLicenseForClient method? Without that id, I can't establish the Client has-many Licenses relationship.

Thanks,
~S

10 Answers, 1 is accepted

Sort by
0
Dimiter Madjarov
Telerik team
answered on 19 Jul 2013, 02:33 PM
Hello Shea,


This the correct way to pass the parent key to the Controller Actions and I was unable to reproduce the issue on my side and in the demos. The id is sent as expected. 

The provided code seems correct, so probably the reason for the issue is somewhere else. Could you please send me a sample runnable project, where the issue is reproducing so I could inspect it locally and assist you further?

 

Regards,
Dimiter Madjarov
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
1
Accepted
Shea
Top achievements
Rank 1
answered on 19 Jul 2013, 02:39 PM
I discovered the problem this morning, but haven't had a chance to post the solution back here.

The fact that I was using 'clientId' as my route variable was the problem. It was trying to use the 'clientId' of the new row, which of course was 0. Changing the name of the route variable to 'parentId' fixed the problem.
.Create(c => c.Action("CreateLicenseForClient", "License", new { parentId = "#=Id#}))
and then in controller:
public ActionResult CreateLicenseForClient([DataSourceRequest]DataSourceRequest request, LicenseInfo li, int parentId)
{
      //....
}
Hope this helps someone else.
Donny
Top achievements
Rank 1
commented on 29 Sep 2022, 08:21 PM

You'll pull your hair out trying to find out why this argument's value is never passed into the Action. This is definitely the cause, as explained here. Thank you for posting your solution. It saved so much time for me.
0
David
Top achievements
Rank 1
answered on 02 Aug 2013, 10:10 AM
I'm having the same problem, can you post the rest of your fixed view?

0
Rachael
Top achievements
Rank 1
answered on 14 Jun 2014, 09:08 PM
Thank you for posting your fix! I had the exact same problem and changing the variable name indeed caused the value to be posted.
0
Steve
Top achievements
Rank 1
answered on 10 Mar 2016, 06:57 PM

Dimiter,

In the above example, how would you pass the value "clientId" to the UPDATE operation?   I've tried to do this an all I get are 0 values in the UPDATE() but I get a valid value in the CREATE()?

Thanks,

Steve

0
Dimiter Madjarov
Telerik team
answered on 14 Mar 2016, 07:37 AM

Hello Steve,

Passing the id value should be the same for all CRUD operations. If the problem is persisting, you could send us an isolated runnable example in which it is reproducing, here or in a support ticket, so we take a look at our end.

Regards,
Dimiter Madjarov
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Gareth
Top achievements
Rank 1
answered on 06 Jan 2017, 09:55 AM

Thanks Shea  

had the same problem caused by using an id from the sub grid which would default to 0 

 .Create(read => read.Action("Create_Next", "Workflow", new { workflowId = "#=WorkflowId#" }))

 .Create(read => read.Action("Create_Next", "Workflow", new { parentId = "#=WorkflowId#" }))

 

 

0
ksafadi
Top achievements
Rank 1
answered on 13 Aug 2017, 04:08 PM

I had problems with this as well and indeed changing the variable name from something like:

.Create(create => create.Action("KuendigungHistorie_Create", "Api", new { Id= "#=Id#" }))

to:

.Create(create => create.Action("KuendigungHistorie_Create", "Api", new { parentId = "#=Id#" }))

... fixed the problem.
But how does the variable name relate to the fact of the value beeing passed or not?

0
Tsvetina
Telerik team
answered on 15 Aug 2017, 12:51 PM
Hello KSafadi,

I expect that the problem occurs when you use a name for the parameter that matches an existing id field name in your Grid DataSource. On create, the id field is by default set to 0 until the server returns the actual id, so passing this field would result in passing 0.

Regards,
Tsvetina
Progress Telerik
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Kevin
Top achievements
Rank 1
answered on 24 Oct 2018, 05:54 PM
Thank you. This worked for me.
Tags
Grid
Asked by
Shea
Top achievements
Rank 1
Answers by
Dimiter Madjarov
Telerik team
Shea
Top achievements
Rank 1
David
Top achievements
Rank 1
Rachael
Top achievements
Rank 1
Steve
Top achievements
Rank 1
Gareth
Top achievements
Rank 1
ksafadi
Top achievements
Rank 1
Tsvetina
Telerik team
Kevin
Top achievements
Rank 1
Share this question
or