I Have two Kendo Grids (UI for Asp.Net MVC) on my page. The first grid gets results from database using an action method of a controller which is bound at grid initialization(I guess). The second grid should get the results of a column from first grid and pass as parameters to second grid which should pass these to action method of another controller bound to second grid. I tried to use autobind(false) but has no use. Please suggest.
2 Answers
Please try with the below code snippet.
VIEW
@(Html.Kendo().Grid<MvcApplication1.Models.TestModel>()
.Name("Grid")
.Columns(columns =>
{
columns.Bound(e => e.ID);
columns.Bound(e => e.Name);
})
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("GetData", "Home"))
)
.Events(events => events.Change("onChange"))
.Selectable(selectable => selectable
.Mode(GridSelectionMode.Single))
)
@(Html.Kendo().Grid<MvcApplication1.Models.ChildModel>()
.Name("ChildGrid")
.Columns(columns =>
{
columns.Bound(e => e.ChildID);
columns.Bound(e => e.ChildName);
})
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("GetChildData", "Home").Data("GetData"))
)
)
<script>
var ID = 0;
var Name = "";
function onChange(arg) {
ID = this.dataItem(this.select()).ID;
Name = this.dataItem(this.select()).Name;
$('#ChildGrid').data('kendoGrid').dataSource.read();
$('#ChildGrid').data('kendoGrid').refresh();
}
function GetData() {
return {
ID: ID,
Name: Name
};
}
</script>
CONTROLLER
public ActionResult GetChildData([DataSourceRequest] DataSourceRequest request, int ID, string Name)
{
List<ChildModel> lst = new List<ChildModel>();
if (ID == 0)
{
return Json(lst.ToDataSourceResult(request));
}
string str = ":" + ID + "_" + Name;
lst.Add(new ChildModel() { ChildID = 1, ChildName = "Name1" + str });
lst.Add(new ChildModel() { ChildID = 2, ChildName = "Name2" + str });
lst.Add(new ChildModel() { ChildID = 3, ChildName = "Name3" + str });
return Json(lst.ToDataSourceResult(request));
}
public ActionResult GetData([DataSourceRequest] DataSourceRequest request)
{
List<TestModel> lst = new List<TestModel>();
lst.Add(new TestModel() { ID = 1, Name = "Name1", MyDate = DateTime.Now });
lst.Add(new TestModel() { ID = 2, Name = "Name2", MyDate = DateTime.Now });
lst.Add(new TestModel() { ID = 3, Name = "Name3", MyDate = DateTime.Now });
return Json(lst.ToDataSourceResult(request));
}
MODEL
namespace MvcApplication1.Models
{
public class TestModel
{
public int ID { get; set; }
public string Name { get; set; }
[DataType(DataType.DateTime)]
public DateTime? MyDate { get; set; }
}
public class ChildModel
{
public int ChildID { get; set; }
public string ChildName { get; set; }
}
}
Let me know if any concern.
I have done something like that in my project. I've searched a lot and I finally realize that the solution is creating master and detail grids, the first gird will be the master and the second which get information from the first is detail, in my example is have two grid, one for Sport Branch and the other is for Federation. Federation get information from Sport Branch.
The Sport Branch grid:
<div >
@(Html.Kendo().Grid<SportBranchViewModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(p => p.SportBranchTitle).Title("Title").Width(120);
columns.Command(command => { command.Edit().Text("Edit").UpdateText("OK").CancelText("Cancel");
command.Destroy().Text("Delete");
})
.Width(172);
})
.ToolBar(toolbar => toolbar.Create().Text("Create"))
.Editable(editable =>
{
editable.Mode(GridEditMode.InLine);
editable.DisplayDeleteConfirmation("Are you sure you want to delete");
})
.Scrollable()
.Sortable(sortable => sortable.AllowUnsort(true))
.ClientDetailTemplateId("federationtemplate")
.DataSource(dataSource => dataSource
.Ajax()
.Events(events => events.Error("onError"))
.Model(model => model.Id(p => p.SportBranchID))
.Read(read => read.Action("SportBranch_Read", "BaseData"))
.Update(update => update.Action("SportBranch_Update", "BaseData"))
.Create(create => create.Action("SportBranch_Create", "BaseData"))
.Destroy(destroy => destroy.Action("DeleteSportBranch", "BaseData"))
)
.Events(events => events.DataBound("collapseGrid"))
.HtmlAttributes(new { style = "height:400px;" }))
</div>
the Federation grid:
<script id="federationtemplate" type="text/kendo-tmpl">
@(Html.Kendo().Grid<SportBranchFederationViewModel>()
.Name("grid_#=SportBranchID#")
.Columns(columns =>
{
columns.Bound(p => p.FederationName).Title("Title").Width(200);
columns.Command(command =>
{
command.Edit().Text("Edit").UpdateText("OK").CancelText("Cancel");
command.Destroy().Text("Delete");
})
;
})
.ToolBar(toolbar =>
{
toolbar.Create().Text("Create");
}
)
.Editable(editable =>
{
editable.Mode(GridEditMode.InLine);
editable.DisplayDeleteConfirmation("Are you sure you want to delete?");
})
.Scrollable()
.Sortable(sortable => sortable.AllowUnsort(true))
.Pageable()
.Events( e=> e.DataBound("onDataBoundFederation"))
.DataSource(dataSource => dataSource
.Ajax()
.Events(events => events.Error("onError"))
.Model(model => model.Id(p => p.FederationID))
.Read(read => read.Action("SportBranchFederation_Read", "BaseData", new { sportBranchID = "#=SportBranchID#" }))
.Create(create => create.Action("SportBranchFederation_Add", "BaseData", new { sportBranchID = "#=SportBranchID#" }))
.Update(update => update.Action("SportBranchFederation_Update", "BaseData", new { sportBranchID = "#=SportBranchID#" }))
.Destroy(destroy => destroy.Action("SportBranchFederation_Destroy", "BaseData", new { sportBranchID = "#=SportBranchID#" }))
.PageSize(7)
)
.HtmlAttributes(new { style = "height:250px;" })
.ToClientTemplate()
)
</script>
in the controller:
public ActionResult SportBranchFederation_Read(int sportBranchID , [DataSourceRequest] DataSourceRequest request)
{
var data = _bvaDataService.GetFederations(sportBranchID);
return Json(CreateSportBranchFederationsFromFederations(data.ToList()).ToDataSourceResult(request));
}
Here is the steps:
put the second grid in a script tag and specify an id for the script tag.
In the first grid use the
ClientDetailTemplateId()
and pass the id of script tag which enclose the second grid.In the action of second grid which you want pass the value of a column of the first gird use the expression "#= [column's name of the first grid]#" (here is
"#=SportBranchID#"
). Note the "#= #" can use in grid to use a value of a field from the current grid or another. I send this field to my read action to get the corresponding result( look at my controller)adding
ToClientTemplate()
to the second grid
read these samples too :
http://demos.telerik.com/kendo-ui/grid/detailtemplate ,
http://demos.telerik.com/aspnet-mvc/grid/detailtemplate