This demonstration very nicely shows how to implement two level hierarchy on a kendo grid. http://demos.kendoui.com/web/grid/hierarchy.html
I tried using the same coding structure to implement three or four levels of hierarchy but couldn't get it to work properly. It works, but the third level grid overwrites and overlaps the second level grid. Please could you let me know if three, four or more levels of hierarchy is possible on kendo web grid and if yes, I'll be grateful if you could point me to an example.
Many Thanks
MB
33 Answers, 1 is accepted
It's possible to implement more than two nested grids using the same approach from the online demo, however currently there is no such demo which we can provide. Also from the provided information it's not clear for us what is the exact reason for overwriting/overlapping the parent grid - could you please provide your current grid code and more details how to reproduce the issue on our side?
Vladimir Iliev
the Telerik team

Thanks for getting back to me. Yes I did realize at a later stage that n level nested grids is indeed possible. What was happening in my case is the third level grid was ending up with same name as the second level grid; therefore, it was overlapping. I changed the dynamic naming logic on all levels and made sure that they are always unique and it worked like a charm after that!
Many thanks for offering help.
Much Appreciated,
Mithun

I am having a problem making this happen. I would like to have a grid with a tabstrip in it's detailtemplate. That would contain another grid. That grid would have a tabstrip in its detailtemplate which would in turn contain another grid.
GRID 1
TabStrip
-GRID 2
TabStrip
-GRID 3
I am using razor with server binding and I receive the following error:
Warning 1 Inline markup blocks (@<p>Content</p>) cannot be nested. Only one level of inline markup is allowed.
Here is my code:
@{ Html.Kendo().Grid(Model)
.Name("gvLaboratories")
.Columns(columns =>
{
columns.Bound(l => l.ID);
columns.Bound(l => l.Description);
})
.DetailTemplate(l =>
{
Html.Kendo().TabStrip()
.Name("ts" + l.ID)
.SelectedIndex(0)
.Items(items =>
{
items.Add().Text("User Facilities").Content(@<
text
>
@(Html.Kendo().Grid(l.User_Facilities)
.Name("gvUserFacilities" + l.ID)
.Columns(columns =>
{
columns.Command(command => { command.Edit(); }).Width(50);
columns.Bound(f => f.ID);
columns.Bound(f => f.Description);
columns.Command(command => { command.Destroy(); }).Width(50);
})
.DetailTemplate(f =>
{
Html.Kendo().TabStrip()
.Name("ts" + f.ID)
.SelectedIndex(0)
.Items(childitems =>
{
childitems.Add().Text("User Facility Admins").Content(@<
text
>
@(Html.Kendo().Grid(f.Users_Roles)
.Name("gvUserFacilityAdmins" + f.ID)
.Columns(columns =>
{
columns.Bound(a => a.User_ID).Template(a => a.User_ID.ToString()).Title("User ID");
columns.Bound(a => a.User.BNL_ID).Title("BNL ID");
columns.Bound(a => a.User.Pool.First_Name).Title("First Name");
columns.Bound(a => a.User.Pool.Last_Name).Title("Last Name");
columns.Bound(a => a.User.Account).Title("BNL Account");
columns.Command(command => { command.Destroy(); }).Width(50);
})
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.PopUp))
.Sortable()
.DataSource(dataSource => dataSource
.Server()
.Model(model => model.Id(a => a.User_ID))
.Read(read => read.Action("UserFacilities", "LabAdmin", new { facilityID = f.ID }))
.Create(create => create.Action("AddUserFacilityAdmin", "LabAdmin"))
.Destroy(destroy => destroy.Action("DeleteUserFacilityAdmin", "LabAdmin"))
)
)
</
text
>);
})
.Render();
})
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.PopUp))
.Sortable()
.DataSource(dataSource => dataSource
.Server()
.Model(model =>
{
model.Id(f => f.ID);
model.Field(field => field.ID).DefaultValue("");
model.Field(field => field.Description).DefaultValue("");
})
.Create(create => create.Action("AddUserFacility", "LabAdmin"))
.Read(read => read.Action("UserFacilities", "LabAdmin", new { labID = l.ID }))
.Update(update => update.Action("UpdateUserFacility", "LabAdmin"))
.Destroy(destroy => destroy.Action("DeleteUserFacility", "LabAdmin"))
)
.RowAction(row =>
{
if (row.DataItem.ID.ToString() == Request.QueryString["facilityID"])
{
row.DetailRow.Expanded = true;
}
})
)
</
text
>);
})
.Render();
})
.Pageable()
.Sortable()
.DataSource(dataSource => dataSource
.Server()
.Model(model => model.Id(l => l.ID))
.Read(read => read.Action("UserFacilities", "LabAdmin"))
)
.RowAction(row =>
{
if (row.DataItem.ID.ToString() == Request.QueryString["labID"])
{
row.DetailRow.Expanded = true;
}
})
.Render();
}
How else should I code the third grid if I can't use the inline markup blocks?
Thanks,
Steve
This is a limitation of the Razor view engine. Tags cannot be nested. In order to avoid the exception I can suggest to use a helper:
.DetailTemplate(f => myDetailDetailViewTemplate(
this
, f))
@helper myDetailDetailViewTemplate(WebViewPage page, MyModel f)
{
@{
Html.Kendo().TabStrip()
.Name(
"ts"
+ f.ID)
.SelectedIndex(0)
.Items(childitems =>
{
childitems.Add().Text(
"User Facility Admins"
).Content(@<text>
...
}
or the action overload of the Content method and the Render method for the inner controls:
Html.Kendo().TabStrip()
.Name(
"ts"
+ f.ID)
.SelectedIndex(0)
.Items(childitems =>
{
childitems.Add().Text(
"User Facility Admins"
).Content(() =>
Html.Kendo().Grid(f.Users_Roles)
...
.Render()
)
Regards,
Daniel
Telerik

Thanks for the info. I tried the action overload of the Content method (which is what I would prefer to use) but I was getting multiple errors so I tried the helper method which is the one I have seen most frequently used. I am getting an error there as well. It says there is an argument missing on this line:
@{ Html.Kendo().TabStrip()
Any ideas?
Thanks,
Steve

@(Html.Kendo().TabStrip()
.......
)
But the problem I am having now is a similar issue I experienced previously with a 2-level grid. Both levels of grid are editable but when I click and edit or add, before the popup would show the tab item would collapse. This was fixed by adding a parameter that indicates which row should be expanded and expand it in the master Grid RowAction callback.
I have that done here as well but now that it is in the helper template it is not working, at least not reliably.
Here is my full view code:
@helper myDetailViewTemplate(WebViewPage page, PASSLibrary.User_Facilities f)
{
@(Html.Kendo().TabStrip()
.Name("tabstrip" + f.ID)
.SelectedIndex(0)
.Items(childitems =>
{
childitems.Add().Text("User Facility Admins").Content(
@<
text
>
@(Html.Kendo().Grid(f.Users_Roles)
.Name("gridUserFacilityAdmins" + f.ID)
.Columns(columns =>
{
columns.Bound(a => a.User_ID).Template(a => a.User_ID.ToString()).Title("User ID");
columns.Bound(a => a.User.BNL_ID).Title("BNL ID");
columns.Bound(a => a.User.Pool.First_Name).Title("First Name");
columns.Bound(a => a.User.Pool.Last_Name).Title("Last Name");
columns.Bound(a => a.User.Account).Title("BNL Account");
columns.Command(command => { command.Destroy(); }).Width(50);
})
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.PopUp))
.Sortable()
.DataSource(dataSource => dataSource
.Server()
.Model(model => model.Id(a => a.User_ID))
.Read(read => read.Action("UserFacilities", "LabAdmin", new { facilityID = f.ID }))
.Create(create => create.Action("AddUserFacilityAdmin", "LabAdmin"))
.Destroy(destroy => destroy.Action("DeleteUserFacilityAdmin", "LabAdmin"))
)
)
</
text
>
);
})
)
}
@{ Html.Kendo().Grid(Model)
.Name("gridLaboratories")
.Columns(columns =>
{
columns.Bound(l => l.ID);
columns.Bound(l => l.Description);
})
.DetailTemplate(
@<
text
>
@(Html.Kendo().Grid(item.User_Facilities)
.Name("gridUserFacilities" + item.ID)
.Columns(columns =>
{
columns.Command(command => { command.Edit(); }).Width(50);
columns.Bound(f => f.ID);
columns.Bound(f => f.Description);
columns.Command(command => { command.Destroy(); }).Width(50);
})
.DetailTemplate(f => myDetailViewTemplate(this, f))
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.PopUp))
.Sortable()
.DataSource(dataSource => dataSource
.Server()
.Model(model =>
{
model.Id(f => f.ID);
model.Field(field => field.ID).DefaultValue("");
model.Field(field => field.Description).DefaultValue("");
})
.Create(create => create.Action("AddUserFacility", "LabAdmin"))
.Read(read => read.Action("UserFacilities", "LabAdmin", new { labID = item.ID }))
.Update(update => update.Action("UpdateUserFacility", "LabAdmin"))
.Destroy(destroy => destroy.Action("DeleteUserFacility", "LabAdmin"))
)
.RowAction(row =>
{
if (row.DataItem.ID.ToString() == Request.QueryString["facilityID"])
{
row.DetailRow.Expanded = true;
}
})
)
</
text
>
)
.Pageable()
.Sortable()
.DataSource(dataSource => dataSource
.Server()
.Model(model => model.Id(l => l.ID))
.Read(read => read.Action("UserFacilities", "LabAdmin"))
)
.RowAction(row =>
{
if (row.DataItem.ID.ToString() == Request.QueryString["labID"])
{
row.DetailRow.Expanded = true;
}
})
.Render();
}
Can you see anything missing or does this not work when it is in a helper template? If so, would it work using the other method of overloading the Content method?
Thanks for all of the help.
Steve
There should not be any difference if the Grid is added with a helper. Which row is not expanded correctly? If the "gridLaboratories" Grid row is not expanded then you should pass "labID" also with the "gridUserFacilityAdmins" read request.
Regards,
Daniel
Telerik

Yes it is the "gridLaboratories". What would the syntax be for sending multiple route values? I see the read.Action overload can take a routeDictionary instead of object type for the route values so maybe that's what to do but I'm not sure how to form that.
Currently I have:
.Read(read => read.Action("UserFacilities", "LabAdmin", new { facilityID = f.ID }))
Steve
You should pass the ID as parameter to the helper and then add it to the "gridUserFacilityAdmins" Grid route values:
.DetailTemplate(f => myDetailViewTemplate(
this
, f, item.ID))
@helper myDetailViewTemplate(WebViewPage page, PASSLibrary.User_Facilities f,
int
labID){
...
.Read(read => read.Action(
"UserFacilities"
,
"LabAdmin"
,
new
{ facilityID = f.ID, labID = labID}))
Daniel
Telerik


In this same scenario with the nested grids, in the popup editor of the second grid, how can I show the popup editor without the field for the primary key from the first grid?
For example, I have my main grid listing Laboratories and my nested grid showing the Facilities in that Laboratory. So once I have expanded a particular Laboratory and I want to add a new Facility, I already now what the Laboratory_ID is for this new Facility since I am in that grid. I can set the default value for that field in the model (as shown below) but how do I not show that field in the editor?
.DataSource(dataSource => dataSource
.Server()
.Model(model =>
{
model.Id(f => f.ID);
model.Field(field => field.ID).DefaultValue("");
model.Field(field => field.Description).DefaultValue("");
model.Field(field => field.Laboratory_ID).DefaultValue(item.ID);
})
Steve
In PopUp editing you could use an attribute on the property (ScaffoldColumn or HiddenInput) or create a custom editor template as demonstrated in this code-library in order to not show an editor for a field.
Daniel
Telerik

Currently my datasource on the grid looks like this:
.DataSource(dataSource => dataSource
.Server()
.Model(model =>
{
model.Id(f => f.ID);
model.Field(field => field.ID).DefaultValue("");
model.Field(field => field.Description).DefaultValue("");
model.Field(field => field.Laboratory_ID).DefaultValue(item.ID);
})
.Create(create => create.Action("AddUserFacility", "LabAdmin"))
.Read(read => read.Action("UserFacilities", "LabAdmin", new { labID = item.ID }))
.Update(update => update.Action("UpdateUserFacility", "LabAdmin"))
.Destroy(destroy => destroy.Action("DeleteUserFacility", "LabAdmin"))
)
[Authorize(Roles = "Lab_Admin")]
[HttpPost]
public ActionResult AddUserFacility(User_Facilities user_facility)
{
try
{
using (PASSEntities context = new PASSEntities())
{
context.User_Facilities.Add(user_facility);
context.SaveChanges();
}
return RedirectToAction("UserFacilities");
}
catch
{
return View();
}
}
@model PASSLibrary.User_Facilities
@Html.HiddenFor(model => model.ID)
<
div
class
=
"editor-label"
>
@Html.Label("ID")
</
div
>
<
div
class
=
"editor-field"
>
@Html.EditorFor(model => model.ID)
@Html.ValidationMessageFor(model => model.ID)
</
div
>
<
div
class
=
"editor-label"
>
@Html.Label("Description")
</
div
>
<
div
class
=
"editor-field"
>
@Html.EditorFor(model => model.Description)
@Html.ValidationMessageFor(model => model.Description)
</
div
>
If you do not wish to show the "Laboratory_ID" and it is needed to send it to the server then you should use a hidden input:
@Html.HiddenFor(model => model.ID)
@Html.HiddenFor(model => model.Laboratory_ID)
Regards,
Daniel
Telerik

Thanks for that. I added the hidden to the custom edit template and it works for me on the edit but on the add I get an error that it cannot find the view, which of course is there, so it seems like it is maybe not passing the Laboratory_ID for the add? Any other insight on that? My code is still the same as above with of course the hidden added to the editor template.
Thanks,
Steve
I am not sure what could be causing this problem. Even if the parameter is not passed the exception should be different. Could you provide the code for the controller so I can check the exact setup?
Regards,
Daniel
Telerik

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PASSLibrary;
namespace PASSAdmin.Controllers
{
public class LabAdminController : Controller
{
public ActionResult Index()
{
return View();
}
#region User Facilities
[Authorize(Roles = "Lab_Admin")]
public ActionResult UserFacilities()
{
var context = new PASSEntities();
IEnumerable<
Laboratory
> labList = (from l in context.Laboratories
join ur in context.Users_Roles on l.ID equals ur.Laboratory_ID
join u in context.Users on ur.User_ID equals u.ID
join r in context.Roles on ur.Role_ID equals r.ID
where u.Account == User.Identity.Name.Substring(4) && r.Name == "Lab_Admin"
select l).ToList();
return View(labList);
}
[Authorize(Roles = "Lab_Admin")]
[HttpPost]
public ActionResult AddUserFacility(User_Facilities user_facility)
{
try
{
using (PASSEntities context = new PASSEntities())
{
context.User_Facilities.Add(user_facility);
context.SaveChanges();
}
return RedirectToAction("UserFacilities");
}
catch
{
return View();
}
}
[Authorize(Roles = "Lab_Admin")]
[HttpPost]
public ActionResult DeleteUserFacility(string id, User_Facilities user_facility)
{
try
{
using (PASSEntities context = new PASSEntities())
{
context.Entry(user_facility).State = System.Data.EntityState.Deleted;
context.SaveChanges();
}
return RedirectToAction("UserFacilities");
}
catch
{
return View();
}
}
[Authorize(Roles = "Lab_Admin")]
[HttpPost]
public ActionResult UpdateUserFacility(string id, User_Facilities user_facility)
{
try
{
using (PASSEntities context = new PASSEntities())
{
context.Entry(user_facility).State = System.Data.EntityState.Modified;
context.SaveChanges();
return RedirectToAction("UserFacilities");
}
}
catch
{
return View();
}
}
#endregion
#region User Facility Admins
[Authorize(Roles = "Lab_Admin")]
[HttpPost]
public ActionResult AddUserFacilityAdmin(Users_Roles user_role)
{
try
{
using (PASSEntities context = new PASSEntities())
{
context.Users_Roles.Add(user_role);
context.SaveChanges();
}
return RedirectToAction("UserFacilities");
}
catch
{
return View();
}
}
[Authorize(Roles = "Lab_Admin")]
[HttpPost]
public ActionResult DeleteUserFacilityAdmin(int id, Users_Roles user_role)
{
try
{
using (PASSEntities context = new PASSEntities())
{
context.Entry(user_role).State = System.Data.EntityState.Deleted;
context.SaveChanges();
}
return RedirectToAction("UserFacilities");
}
catch
{
return View();
}
}
#endregion
}
}
Please let me know if you need anything else. Obviously there is an issue since its not working, but I think as you pointed out I am also having another problem in my solution with the error messages. I have client side validation enabled and unobtrusive javascript enabled in my web config but I keep getting errors like I have described when I should be getting other error messages.
From the code it seems that the described problem will occur if an exception is thrown when saving the changes. A ViewResult for the current action is returned when an exception is thrown and there does not seem to be a view named "AddUserFacility". Could you check if an exception is thrown?
Regards,Daniel
Telerik

Here is my custom editor template again:
@model PASSLibrary.User_Facilities
@Html.HiddenFor(model => model.ID)
@Html.HiddenFor(model => model.Laboratory_ID)
<
div
class
=
"editor-label"
>
@Html.Label("ID")
</
div
>
<
div
class
=
"editor-field"
>
@Html.EditorFor(model => model.ID)
@Html.ValidationMessageFor(model => model.ID)
</
div
>
<
div
class
=
"editor-label"
>
@Html.Label("Description")
</
div
>
<
div
class
=
"editor-field"
>
@Html.TextBoxFor(model => model.Description, new { style = "width: 250px;" })
@Html.ValidationMessageFor(model => model.Description)
</
div
>
If the value for the ID field should be entered by the user then you should remove the hidden input. Otherwise, the ModelBinder will always populate the value from the hidden input because it is first.
Regards,Daniel
Telerik

Ok I understand what you are saying and that makes sense to me when it is in "add" mode but what about when it is in "edit" mode. It uses the same custom edit template so doesn't the hidden need to be there for the "edit"?
Thanks,
Steve
If the user should enter the value only when creating a new item then you could check the Id value and render only the HiddenInput or the editor e.g.
@if (!String.IsNullOrEmpty(Model.ID))
{
@Html.HiddenFor(model=> model.ID)
}
else
{
<
div
class
=
"editor-label"
>
@Html.Label("ID")
</
div
>
<
div
class
=
"editor-field"
>
@Html.EditorFor(model => model.ID)
@Html.ValidationMessageFor(model => model.ID)
</
div
>
}
Regards,
Daniel
Telerik

In this particular case though I don't think I need to do that because I am using jquery to disable the ID field if it is an edit.
Thanks!

Ok posting one more time in this thread...hopefully.
I've got everything working now the way I want but there are two small things happening that I would like to fix.
1. When I add or delete an item from the nested grid, the parent grid collapses instead of remaining open. I thought I had fixed this issue early on but it seems to be happening again now.
2. When I click "Delete" on the nested grid, I get the "Delete this item" pop up twice.
Here is my view code:
@{ Html.Kendo().Grid(Model)
.Name("gridLaboratories")
.Columns(columns =>
{
columns.Command(command => { command.Edit(); }).Width(50);
columns.Bound(l => l.ID);
columns.Bound(l => l.Description);
columns.Command(command => { command.Destroy(); }).Width(50);
})
.DetailTemplate(l =>
{
Html.Kendo().TabStrip()
.Name("tabstrip" + l.ID)
.SelectedIndex(0)
.Items(items =>
{
items.Add().Text("Lab Admins").Content(@<
text
>
@(Html.Kendo().Grid(l.Users_Roles)
.Name("gridLabAdmins" + l.ID)
.Columns(columns =>
{
columns.Bound(a => a.User.BNL_ID).Title("BNL ID");
columns.Bound(a => a.User.Pool.First_Name).Title("First Name");
columns.Bound(a => a.User.Pool.Last_Name).Title("Last Name");
columns.Bound(a => a.User.Account).Title("BNL Account");
columns.Command(command => { command.Destroy(); }).Width(50);
})
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("SystemAdmin/LabAdmin"))
.Sortable()
.DataSource(dataSource => dataSource
.Server()
.Model(model => model.Id(a => a.ID))
.Read(read => read.Action("Laboratories", "SystemAdmin", new { labID = l.ID }))
.Create(create => create.Action("AddLabAdmin", "SystemAdmin"))
.Destroy(destroy => destroy.Action("DeleteLabAdmin", "SystemAdmin"))
)
)
</
text
>);
})
.Render();
})
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("SystemAdmin/Laboratory"))
.Pageable()
.Sortable()
.DataSource(dataSource => dataSource
.Server()
.Model(model =>
{
model.Id(l => l.ID);
model.Field(field => field.ID).DefaultValue("");
model.Field(field => field.Description).DefaultValue("");
})
.Create(create => create.Action("AddLaboratory", "SystemAdmin"))
.Read(read => read.Action("Laboratories", "SystemAdmin"))
.Update(update => update.Action("UpdateLaboratory", "SystemAdmin"))
.Destroy(destroy => destroy.Action("DeleteLaboratory", "SystemAdmin"))
)
.RowAction(row =>
{
if (row.DataItem.ID.ToString() == Request.QueryString["labID"])
{
row.DetailRow.Expanded = true;
}
})
.Render();
}
<
script
type
=
"text/javascript"
>
$(document).ready(function () {
var gridMode = getURLParameter("gridLaboratories-mode");
if (gridMode == "edit") {
$("#gridLaboratoriesPopUp").find('input[name="ID"]').attr("disabled", true);
}
});
function getURLParameter(name) {
return decodeURI((RegExp(name + '=' + '(.+?)(&|$)').exec(location.search) || [, null])[1]);
}
</
script
>
And here is my controller code:
public class SystemAdminController : Controller
{
public ActionResult Index()
{
return View();
}
#region Laboratories
[Authorize(Roles = "System_Admin")]
public ActionResult Laboratories()
{
var context = new PASSEntities();
return View(context.Laboratories.ToList());
}
[Authorize(Roles = "System_Admin")]
[HttpPost]
public ActionResult AddLaboratory(Laboratory laboratory)
{
try
{
using (PASSEntities context = new PASSEntities())
{
context.Laboratories.Add(laboratory);
context.SaveChanges();
}
return RedirectToAction("Laboratories");
}
catch
{
return View();
}
}
[Authorize(Roles = "System_Admin")]
[HttpPost]
public ActionResult DeleteLaboratory(string id, Laboratory laboratory)
{
try
{
using (PASSEntities context = new PASSEntities())
{
context.Entry(laboratory).State = System.Data.EntityState.Deleted;
context.SaveChanges();
}
return RedirectToAction("Laboratories");
}
catch
{
return View();
}
}
[Authorize(Roles = "System_Admin")]
[HttpPost]
public ActionResult UpdateLaboratory(string id, Laboratory laboratory)
{
try
{
using (PASSEntities context = new PASSEntities())
{
context.Entry(laboratory).State = System.Data.EntityState.Modified;
context.SaveChanges();
return RedirectToAction("Laboratories");
}
}
catch
{
return View();
}
}
#endregion
#region Lab Admins
public class EmployeeInfo
{
public string FirstName { get; set; }
public string LastName { get; set; }
public decimal UserID { get; set; }
};
public JsonResult GetEmployeeByBNLID(string bnlID)
{
var context = new PASSEntities();
User employee = context.Users.SingleOrDefault(user => user.BNL_ID == bnlID);
EmployeeInfo employeeInfo = new EmployeeInfo
{
FirstName = employee.Pool.First_Name,
LastName = employee.Pool.Last_Name,
UserID = employee.ID
};
return Json(employeeInfo);
}
[Authorize(Roles = "System_Admin")]
[HttpPost]
public ActionResult AddLabAdmin(Users_Roles user_role)
{
try
{
using (PASSEntities context = new PASSEntities())
{
context.Users_Roles.Add(user_role);
context.SaveChanges();
}
return RedirectToAction("Laboratories");
}
catch
{
return View();
}
}
[Authorize(Roles = "System_Admin")]
[HttpPost]
public ActionResult DeleteLabAdmin(Users_Roles user_role)
{
try
{
using (PASSEntities context = new PASSEntities())
{
context.Entry(user_role).State = System.Data.EntityState.Deleted;
context.SaveChanges();
}
return RedirectToAction("Laboratories");
}
catch
{
return View();
}
}
#endregion
}
The destroy command does not use the Read action since the Grid does not need to be rendered again and so the ID should also be sent with the destroy request:
.Destroy(destroy => destroy.Action(
"DeleteLabAdmin"
,
"SystemAdmin"
,
new
{ labID = l.ID }))
public
ActionResult DeleteLabAdmin(Users_Roles user_role,
int
labID)
{
try
{
using
(PASSEntities context =
new
PASSEntities())
{
context.Entry(user_role).State = System.Data.EntityState.Deleted;
context.SaveChanges();
}
return
RedirectToAction(
"Laboratories"
,
new
{labID = labID});
}
Daniel
Telerik

.RowAction(row =>
{
if (row.DataItem.ID.ToString() == Request.QueryString["labID"])
{
row.DetailRow.Expanded = true;
}
})
As for the double delete confirmation, I have the latest version of the Kendo MVC controls 2013.Q2. Note that it only happens with the nested grid and not the parent grid. Is it somehow referencing the delete from the parent grid?
The read action should be used for edit and create to render the Grid again in edit mode. After updating or creating the item however, the Update and Create actions are used so the ID should again be added to the route values.
I reproduced the problem with the double confirmation and it seems that the event is not stopped when server editing is used. We will look into it and will fix it for one of the next internal builds.
Daniel
Telerik


Hello , i am faced with a similar problem where my 3rd level grid seems to overwrite my second level..
Your solution , you mentioned the dynamic naming , can you tell me how i can get his done?
Thanks in advance...
Could you provide the code that you are using so I can check the setup? I would also suggest to check this code-library project which demonstrates hierarchy with 3 levels.
Regards,
Daniel
Telerik


hi Mithun, can you please provide what exactly you have changed ? because i am also facing slimier issue, my third grid is binding data from second grid. i couldn't figure out why its happening .
Thanks,Trushar
