I have a set of views to edit a model similar to this:
Person
ID
Name
Contacts -> List of Contact
Contact
ID
Description
Address
PhoneNumber
I would very much like to use a KendoUI grid for CRUDing the Person's Contact list (mainly because of layout and styling purposes). That I said, How can I achieve this? I need to make the grid bound to that property of the Person being edited or created as is. I mean, I would like to have only one controller (let's say PersonController) that knows how to persist my Person.
Is this possible? Having a grid without controller actions ? Has anyone been in the same situation also?
Thanks!
15 Answers, 1 is accepted
You can achieve similar behavior by using either Hierarchical Grid as shown in this demo or by using a custom columns.editor.
Regards,
Alexander Popov
Telerik

In fact I was going for the layout on the attached image, so I thought in using the grid for the contacts part. The ways you suggested doesn't appeal to me, and I'll probably go for the usual way, using EditorTemplates for the contacts part. It will give a bit of work to get the layout work with the Kendo skin, but I think it is doable.
Thanks.


Would you please share more details about your scenario and the desired results? You can also open a new support ticket.
Regards,
Alexander Popov
Telerik

Sure Alex
​Basically I have a model that contains a list property (shown below), I populate the list within the controller, return it using Json, I see all of the data elements populated correctly in fiddler and I want to bind the list property to a grid in my editor page. For some reason, I see the titles just fine for the columns, but I see no data whatsoever in my grid. My implementation is shown below, you advice would be appreciated.
------- MODEL
public class Lookup
{
public int LookupID { get; set; }
public int AssetClassID { get; set; }
public string AssetClassName { get; set; }
public string LookupName { get; set; }
public Boolean IsActive { get; set; }
public Boolean IsDeleted { get; set; }
public int LastUpdUSerID { get; set; }
public DateTime LastUpdDateTime { get; set; }
public List<LookupValue> Lookupvalue { get; set; }
}
------- Controller
[HttpGet]
public JsonResult GetLookupSpecific([DataSourceRequest] DataSourceRequest request, Lookup lookupmod)
{
ModelState.Clear();
if (lookupmod.LookupID > 0)
{
var lookupobj = contextdb.usp_get_lookups(lookupmod.LookupID, null).Select(s => new Models.Lookup
{
LookupID = s.LookupID,
LookupName = s.LookupName,
LastUpdUSerID = s.LastUpdUserID,
LastUpdDateTime = s.LastUpdDtm,
IsActive = s.IsActive,
Lookupvalue = contextdb.usp_get_lookup_values(s.LookupID).Select(v => new Models.LookupValue
{
LookupvalueId = v.LookupValueID,
TextValue = v.TextValue,
LookupID = v.LookupID
}).ToList()
}).ToList();
return Json(lookupobj.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
return Json(null);
}
-------------- View
@model MatsUser.Models.Lookup
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-wid
<!DOCTYPE html>
<html>
<head>
<meta name=" viewport" content="width=device-width" />
<title>Edit Lookup</title>
</head>
<body style="margin-left:45px; overflow-y: auto; overflow-x: hidden;">
<div style="margin-left:15px; width:80%; height:80%;">
@using (Html.BeginForm())
{
<table>
<tr>
<td style="text-align: right">
@Html.Label("Active" + ":")
</td>
<td style="text-align: left">
@(Html.CheckBoxFor(model => model.IsActive))
</td>
</tr>
<tr>
<td style="text-align: right">
@Html.Label("AssetClass" + ":")
</td>
<td style="text-align: left">
@ViewBag.AssetClassName
</td>
</tr>
<tr>
<td style="text-align: right">
@(Html.LabelFor(model => model.LookupName, "Lookup Name:"))
</td>
<td style="text-align: left">
@(Html.Kendo().TextBoxFor(model => model.LookupName))
</td>
</tr>
</table>
<br />
<script type="text/javascript">
function additionaldataUserIDAssetID() {
try {
var row = $(event.srcElement).closest("tr");
var grid = $(event.srcElement).closest("[data-role=grid]").data("kendoGrid");
var dataItem = grid.dataItem(row);
return { Lookupid: dataItem.LookupID };
}
catch (err) {
return { Lookupid: 99 };
}
}
</script>
<div style="margin-left:35px; width:80%; height:80%;" id="output">
<table>
<tr></tr>
<tr>
<td colspan="3" align="center">
Values
<br /><br />
@(Html.Kendo().Grid(Model.Lookupvalue)
.Name("Values")
.HtmlAttributes(new { style = "width:150px" })
.HtmlAttributes(new { style = "height:200px" })
.Columns(c =>
{
c.Bound(p => p.LookupvalueId);
c.Bound(p => p.TextValue).HtmlAttributes(new { style = "text-align:center" })
.HeaderHtmlAttributes(new { style = "text-align:center" });
c.Command(cs =>
{
cs.Custom("Delete").Click("DeleteLookupVal");
});
})
.Editable(e => e.Mode(GridEditMode.InCell))
.DataSource(d => d
.Ajax()
.Read(r => r.Action("GetLookupSpecific", "Lookup").Data("additionaldataUserIDAssetID"))
.Model(m =>
{
m.Id(mm => mm.LookupvalueId);
m.Field(mm => mm.TextValue);
m.Field(mm => mm.LookupID);
})
.Batch(true)
.ServerOperation(false)
)
.Navigatable()
)
</td>
</tr>
</table>
<br />
</div>
}
</div>
</body>
</html>
It looks like the GetLookupSpecific function is returning a list of Lookup objects, however the Grid is configured to work with LookupValue models. Providing the right type of data should solve the issue.
Regards,
Alexander Popov
Telerik

Alex,
Thank you for your response. Is there a way to make the grid bind to the list object that is part of the main model, or is that type of implementation better of done perhaps in a mvvm style where the lookupvalues is a secondary model in the view model?
Modifying the GetLookupSpecific function so it returns a LookupValue collection should be enough to populate the Grid. You can also use Ajax binding only, as currently the Grid is initially populated on the server using the Model.Lookupvalue collection. For example:
// @(Html.Kendo().Grid(Model.Lookupvalue)
@(Html.Kendo().Grid<LookupValue>()
...
return
Json(lookupobj.Lookupvalue.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
Regards,
Alexander Popov
Telerik

HI
I have the same problem and Form POST always return empty list property - BindTo() no Read() Action :
ViewModel1 with List-Model1 property :
public class ViewModel1
{
public string Column1 { get; set; }
public IEnumerable<Model1> Model1s { get; set; }
public ViewModel1()
{
this.Model1s = new List<Model1>();
}
View
@model Custom.ViewModels.ViewModel1
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.HiddenFor(model => model.Column1)
@(Html.Kendo().Grid(Model.Model1s)
.Name("Model1sGrid")
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Pageable(pageable => pageable.Enabled(false))
.Columns(columns =>
{
columns.Bound(m => m.Key1);
columns.Bound(m => m.Value1);
columns.Bound(m => m.Value2);
})
.DataSource(dataSource =>
{
dataSource.Ajax()
.Batch(true)
.ServerOperation(false)
.Model(model =>
{
model.Id(m => m.Key1);
});
}))
}
<input type="submit" formaction="Update" value="Save" class="k-button" />
Controller
[HttpPost]
public ActionResult Update(ViewModel1 viewmodel1)
{
... always viewmodel1.Models = 0 ...
How can I return the full view model (include Grid list data) correctly ?
Best regards
Chris
Generally, to display and edit a list of possible options to choose from, you can use a ForeignKeyColumn:
http://demos.telerik.com/aspnet-mvc/grid/foreignkeycolumn
You can also check the following post for additional details:
http://www.telerik.com/forums/combox-in-kendo-grid#nBzPXJy_gEq9tFIvNEvOmw
I hope this will prove helpful.
Regards,
Eyup
Telerik by Progress

HI
Very thanks and I need the solution of the DropDownList in Grid editing too.
But the primary question is :
Bind grid to list property of the model and 'Post data but controller get's empty list property in model'.
So, How can I get the full view model data (include list property data - Model.Model1s [Grid]) correctly
in Controller side while Form Post ?
Controller
[HttpPost]
public ActionResult Update(ViewModel1 viewmodel1)
{
... always viewmodel1.Model1s.Count = 0 now ...
Best regards
Chris
For this specific scenario, I would suggest that you open a formal support ticket and send a very basic runnable isolated version of your configuration so that our responsible support engineers provide a more precise and accurate approach or explanation for your specific scenario.
Regards,
Eyup
Telerik by Progress

HI
I have search and found a solution in the forum :
Submit form containing grid along with other input elements
http://www.telerik.com/support/code-library/submit-form-containing-grid-along-with-other-input-elements
Save Form Data in Same Transaction (Other Html Control value + Kendo Grid Values)
http://www.telerik.com/forums/save-form-data-in-same-transaction-(other-html-control-value-kendo-grid-values)
GridInForm.zip
@(Html.Kendo().Grid(Model.Products)
.Name("Products")
.Columns(columns =>
{
columns.Bound(p => p.Name).ClientTemplate("#= Name #" +
"<input type='hidden' name='Products[#= index(data)#].Name' value='#= Name #' />");
...
<script>
function index(dataItem) {
var data = $("#Products").data("kendoGrid").dataSource.data();
return data.indexOf(dataItem);
}
</script>
But it is written in Kendo UI Suite and Version 2012.2.710, Is it suitable for the newest Telerik ASP.NET MVC Grid ?
Why the Grid do not provide the built-in functionality for this situation ?
--
There have no official description about this situation in Kendo UI Grid FAQ :
Frequently Asked Questions | Kendo UI Grid HtmlHelper - Telerik
http://docs.telerik.com/aspnet-mvc/helpers/grid/faq#editing
--
And DropDownList in Grid editing (Kendo.Mvc.Examples - UIHint and EditorTemplate) :
C:\Program Files\Telerik\UI for ASP.NET MVC R3 2016\wrappers\aspnetmvc\Examples\VS2015\Kendo.Mvc.Examples\Models\ProductViewModel.cs
[UIHint("ClientCategory")]
public CategoryViewModel Category
{
get;
set;
}
C:\Program Files\Telerik\UI for ASP.NET MVC R3 2016\wrappers\aspnetmvc\Examples\VS2015\Kendo.Mvc.Examples\Views\grid
columns.Bound(p => p.Category).ClientTemplate("#=Category.CategoryName#").Width(180);
C:\Program Files\Telerik\UI for ASP.NET MVC R3 2016\wrappers\aspnetmvc\Examples\VS2015\Kendo.Mvc.Examples\Views\grid\EditorTemplates
@model Kendo.Mvc.Examples.Models.CategoryViewModel
@(Html.Kendo().DropDownListFor(m => m)
.DataValueField("CategoryID")
.DataTextField("CategoryName")
.BindTo((System.Collections.IEnumerable)ViewData["categories"])
)
Best regards
Chris
I'm glad that you've managed to find some directions and ideas for this specific requirement. You can also check the post-grid-with-form sample provided here:
https://github.com/telerik/ui-for-aspnet-mvc-examples/tree/master/grid
If you have different requirements or further instructions, please open a new support thread as suggested in my previous reply.
Regards,
Eyup
Telerik by Progress