We have a grid that has a detail template, and in the detail template is another grid (in reality the child grid is housed within a tab panel but I'm presenting it this way for simplicity sake). The parent grid is readonly and the child grid contains editable rows. When adding a row to the child grid (using inline editing) we need one of the columns to display a dropdown containing values that are unique to each parent grid's row ID.
While searching through the demo's I came across the following:
http://demos.kendoui.com/web/grid/editing-custom.html
However, in our situation we need each row's dropdown to have different values (rather than binding to a single list in the viewbag).
I was horsing around with creating a column with a ClientTemplate containing a dropdownlist that pulls its data from a controller method, but was unable to figure out the exact syntax to get it to work within the context of a row detail template. Is this the only way to go about doing this or am I missing something obvious? Thanks!
17 Answers, 1 is accepted
Please check the example below of achieving the desired behavior:
- Set the column in the child Grid in the following way:
@(Html.Kendo().Grid<OrderViewModel>()
.Name(
"Orders_#=EmployeeID#"
)
.Columns(columns =>
{
//Product must be object
columns.Bound(o => o.Product)
.ClientTemplate(
"\\#= Product ? Product.ProductName : ''\\#"
)
.EditorTemplateName(
"DynamicDropDownList"
);
- Add "DynamicDropDownList.cshtml" editor under the EditorTemplates folder (for example under the Views -> Shared folder):
<script type=
"text/javascript"
>
function getParentId() {
return
{ EmployeeID:
'#=EmployeeID#'
};
}
</script>
@(Html.Kendo().DropDownList()
.Name(
"Product"
)
.DataValueField(
"ProductID"
)
.DataTextField(
"ProductName"
)
.DataSource(ds => ds
.Read(read => read.Action(
"Read_Products"
,
"Products"
).Data(
"getParentId"
)))
)
- Set the Controller action to return list of Products:
public
ActionResult Read_Products(
int
EmployeeID)
{
return
Json(context.Products.Where(e => e.EmployeeID == EmployeeID).Select(e =>
new
ProductViewModel
{
ProductID = e.ProductID,
ProductName = e.ProductName,
Price = e.Price
}), JsonRequestBehavior.AllowGet);
}
Vladimir Iliev
Telerik
In the example above how can I change the getParentId function to extract the value of a column in the Child Grid instead of the parent grid?
In other words, instead of getting EmployeeID I want the value of another column in Orders_#=EmployeeID#
Kind regards
In order to achieve the desired behavior, my recommendation is to try to do it by following this approach :
1. Declare a variable that will hold the value of the parameter.
2. Hook for the beforeEdit event of the child Grid.
.Events(ev=>ev.BeforeEdit("beforeEdit"))
3.And within the handler by using the event, could be accessed all of the properties of the record
e.model.FieldName;
4. Set the global variable to be equal the accessed through the event data.
5.In the DropDownList declaration, configure a handler which returs the global variable as a parameter :
.Read(read => read.Action("DDL_Read", "Home").Data("getParam")))
Here is are the event handler, the data function and the variable :
var param = { freight: 0 };
function beforeEdit(e) {
param.freight = e.model.Freight;
}
function getParam() {
return param;
}
I went ahead and implemented it and the edit template correctly populates a drop down, however now the toolbar add button isn't adding a new row to the grid. Here's an example of what the grid looks like:
@(Html.Kendo().Grid<
Document
>()
.Name("DocumentGrid_#=PackageID#")
.Columns(columns =>
{
columns.Bound(p => p.CreateDateTime).Width(110);
columns.Bound(p => p.OTest)
.ClientTemplate("\\#= OTest? OTest.Name : ''\\#")
.EditorTemplateName("DocumentDropDown");
columns.Command(commands =>
{
commands.Edit();
commands.Destroy();
}).Title("Commands").Width(200);
})
.ToolBar(toolbar =>
{
toolbar.Create();
})
.Editable(editable => editable.Mode(GridEditMode.InLine)) // Use inline editing mode
.DataSource(dataSource => dataSource
.Ajax()
.Model(model =>
{
model.Id(i => i.DocumentID);
model.Field(p => p.OTest);
})
.PageSize(5)
.Read(read => read.Action("PackageRead", "Dispatch", new { PackageID = "#=PackageID#"}))
.Update(update => update.Action("Document_Update", "Dispatch"))
.Destroy(delete => delete.Action("Document_Delete", "Dispatch"))
.Create(create => create.Action("Document_Create", "Dispatch"))
)
.ToClientTemplate())
I would suggest to try setting default value for the "OTest" field - please check the example below:
.Model(model =>
{
model.Id(p => p.ProductID);
model.Field(p => p.ProductID).Editable(
false
);
//set a empty object as default value - the DropDownList should have OptionLabel defined
model.Field(p => p.Category).DefaultValue(
new
Kendo.Mvc.Examples.Models.ClientCategoryViewModel());
// OR set a p[opulated object as default value
//model.Field(p => p.Category).DefaultValue(new Kendo.Mvc.Examples.Models.ClientCategoryViewModel() {CategoryID = 1, CategoryName = "Category 1" });
})
Vladimir Iliev
Telerik
The "ClientCategoryViewModel" model can be found in the offline demos that comes with your KendoUI for ASP.NET MVC installation, however I also included the model below:
public
class
ClientCategoryViewModel
{
public
int
CategoryID {
get
;
set
; }
public
string
CategoryName {
get
;
set
; }
}
Kind Regards,
Vladimir Iliev
Telerik
Cannot serialize objects of type ...
*scratches head*. I've checked and rechecked the grid and editor template and not seeing what could be causing the problem. Any ideas?
As this thread is out of the original topic, may I kindly ask you to open a new support thread for the appropriate product (KendoUI DataSource in that case)?
Vladimir Iliev
Telerik
I am looking for same functionality without parent grid ie., in a grid each row may have different dropdown values based on other column and I am using HTML5/ Jquery. Cloud you please provide the above example in with Jquery.
Thanks in advance for your time.
Thanks!
I am not sure if I understand the issue with the described scenario but you could just set the corresponding data when creating the editor. I have created an example based on the custom editor demo that filters the data based on the ProductID value.
Regards,
Daniel
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
In the step 2, getParentId(), it returns null in my try to return a titleId like return { TitleID: '#=TitleD#' }.
I saw the post is pretty old. does it still work for 2021?
[quote]
2.Add "DynamicDropDownList.cshtml" editor under the EditorTemplates folder (for example under the Views -> Shared folder):
<script type=
"text/javascript"
>
function getParentId() {
return
{ EmployeeID:
'#=EmployeeID#'
};
}
</script>
@(Html.Kendo().DropDownList()
.Name(
"Product"
)
.DataValueField(
"ProductID"
)
.DataTextField(
"ProductName"
)
.DataSource(ds => ds
.Read(read => read.Action(
"Read_Products"
,
"Products"
).Data(
"getParentId"
)))
)
Vladimir Iliev
Telerik
Hi Allen,
You can get the value of the ParentID in the BeforeEdit event of the Child grid. Save the id to a global variable and return this variable in the getParentId function.
Child grid:
.Events(e => e.BeforeEdit("onBeforeEdit"))
In the same view(.cshtml):
<script>
let titleId = 0;
function onBeforeEdit() {
let parentGrid = $("#grid").data("kendoGrid"); // get the parent grid.
let parentRow = this.wrapper.closest("tr").prev(); // get the parent row.
titleId = parentGrid.dataItem(parentRow).TitleID; // set the TitleID to the global variable.
}
function listAdditionalParameter() {
return {
TitleID: titleId // return the titleId to the DropDownList Read method.
}
}
</script>
Best Regards,
Georgi Denchev
Progress Telerik
Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.
Hey Georgi,
Thanks for reply. what I want to do is getting the value of the ParentID of a dropdown list instead of child grid.
I checked events for a dropdown list in the docucment section. There is no BeforeEdit for dropdown list. the only events I saw was 'Select', 'Change', 'DataBound', 'Filtering', 'Open', 'Close', 'Cascade'. None of them will be triggered when i clicked the dropdown list.
Do you have any other suggestion?
Thanks.
Allen
Hi Allen,
Perhaps you are looking for the Cascading DropDownList functionality where the second dropdown obtains it's values based on the value selected in the first dropdown?
Best Regards,
Georgi Denchev
Progress Telerik
Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.
Hey Georgi
Thanks for your reply. I am not looking for the cascading dropdown list. I am looking at how to get different dropdown for each row in a grid. In the attach screenshot, you can see there are dropdown lists in column Grade in the main grid, the dropdown will be different on each row which is depended on the titleId of the row. I am looking at an event when user clicks the dropdown, then i can get the title id of the row, then read the values for the dropdown. Right now I can only get same values in all dropdown in the column Grade. If there is no such event I can use,
Thank you very much.
Allen
[quote]Georgi Denchev said:
Hi Allen,
Perhaps you are looking for the Cascading DropDownList functionality where the second dropdown obtains it's values based on the value selected in the first dropdown?
Best Regards,
Georgi Denchev
Progress Telerik
Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.
Hello Allen,
Thank you for the additional information.
The approach would be the same as with the Child Grid. Attach the BeforeEdit event to the grid, get the titleId of the row that is currently being edited and pass it to the DropDownList Controller Action as additional data.
@(Html.Kendo().Grid<MyModel>()
.Name("grid")
.Events(ev => ev.BeforeEdit("onBeforeEdit"))
)
<script>
let titleId = 0;
function onBeforeEdit(e) {
titleId = e.model.TitleID; // e.model contains all of the data for the row that is currently being edited.
}
function listAdditionalParameter() {
return {
TitleID: titleId // return the titleId to the DropDownList Read method.
}
}
</script>
Best Regards,
Georgi Denchev
Progress Telerik
Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.
Thank you very much, Georgi.
It works very well.
Hi Allen,
I am glad the solution works for you!
Best Regards,
Georgi Denchev
Progress Telerik
Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.