I have a multi-step UI that requires the user select a group from a TreeList. That group selection must then be used to feed into a Grid that is populated by People that are in that selected Group.
How do I do this? I've been using the PanelBar up to this point to perform multi-step processes. However, I've never had to base the data selection in step 2 with the selection from step 1. Can I late bind the Grid so it will go get its data when the host Tab is selected?
5 Answers, 1 is accepted
Hello, Joel,
Straight to your question - yes you can bind the grid on a later stage. You can do that at a given time of the lifecycle, using the Client API of the component and by executing the read method on the DataSource instance of the Grid:
var grid = $("#grid").getKendoGrid()
grid.dataSource.read()The above will trigger the request for data binding, and at this point, you can take into consideration the selection.
Hope this would help.
Regards,
Nencho
Progress Telerik
I believe I'm close on this... but no cigar. The TreeList:
@(Html.Kendo().TreeList<NameValueParent>() .Name("treelist") .Columns(columns => { columns.Add().Command(c => { c.Custom().Text("Select") .Name("selectButton").ClassName("selectButton") .Click("goDetail"); }) .Width(Glossary.Portal.ButtonWidth); columns.Add().Field(e => e.Name); columns.Add().Field(e => e.Description); columns.Add().Width(330).Command(c => { c.CreateChild().Text("Add"); c.Edit(); c.Destroy(); }) .HtmlAttributes(new { style = "text-align: center;" }); }) .Events(ev => ev.DataBound("onDataBound")) .Editable() .Selectable(s => s.Mode(TreeListSelectionMode.Single)) .DataSource(dataSource => dataSource .Create(create => create.Action("Create", "Site")) .Read(read => read.Action("IndexJson", "Site").Data("getData")) .Update(update => update.Action("Update", "Site")) .Destroy(delete => delete.Action("Destroy", "Site")) .Model(m => { m.Id(f => f.Id); m.ParentId(f => f.ParentId); m.Expanded(true); m.Field(f => f.Name); }).Events(events => { events.Error("onError"); }) ).Height(540))The goDetail script that stores the value in an id field tells the Grid to read:
function goDetail(e) { e.preventDefault(); //alert("goDetail: " + e.toString()); var dataItem = this.dataItem($(e.currentTarget).closest("tr")); //alert("goDetail: " + dataItem.id); $('#itemId').val(dataItem.id); var grid = $("#grid").getKendoGrid(); grid.dataSource.read();}The above script successfully tells the Grid to read. My Grid:
@(Html.Kendo().Grid<NameValuePair>() .Name("grid") .Columns(columns => { columns.Bound(p => p.Id); columns.Bound(p => p.Name); columns.Bound(p => p.Value); }) .Pageable() .Sortable() .Scrollable() .HtmlAttributes(new { style = "height:550px;" }) .DataSource(dataSource => dataSource .Ajax() .PageSize(20) .Read(read => read.Action("GridJson", "Site") .Data("getData"))))When reading I need to get the selected value from the TreeList fed into the Controller's parameter list. My attempt that is not working. I tried to just return the raw value... this is an attempt to give the parameter.name:value.
function getData() { var id = document.getElementById("itemId").value; alert(id); if (id != null) { var str = "'id': '" + id + "'"; alert(str); return str; } else { return 0; }}And finally my controller method. The id parameter value is always 0:
public IActionResult GridJson( [DataSourceRequest] DataSourceRequest request, int id){ NameValuePairList lst = new NameValuePairList(); for (int i = 0; i < 5; i++) { lst.Add(new NameValuePair() { Id = $"{i}", Name = nameof(id), Value = $"{id}" }); } var dsResult = lst.ToDataSourceResult(request); return Json(dsResult);}
Thanks again for your help,
Joel
Hello, Joel,
The Data function should return the key-value pair so that the controller can be aware of the parameter name to receive. Check this forum thread, where this is described in details:
In other words, the getData function should look similar to the below implementation:
unction getData() {
var id = document.getElementById("itemId").value;
alert(id);
if (id != null) {
var str = "'id': '" + id + "'";
alert(str);
return {
id: str
} } else {
return 0;
}
}Also, the param in the controller should probably be in string type
Regards,
Nencho
Progress Telerik
Our thoughts here at Progress are with those affected by the outbreak.
I finally got to work through this in detail. TreeList Click Event puts the Item.Id value into a model.Item.Id field using the #itemId id on the form's input field. I then capture the KendoGrid and tell it to read. On Grid.Read, the Item.Id value is pulled out of the model and fed to the controller's parameter by "return { id: id }" (param name: param value) syntax.
$("#treelist").on("click", function (e) { //alert("click"); var tree = $("#treelist").data("kendoTreeList"); //alert(tree == null); var item = tree.dataItem($(e.target).closest("tr")); //alert(item == null); //alert(item.id); $('#itemId').val(item.id); var grid = $("#grid").getKendoGrid(); grid.dataSource.read();});Controller (Note: param is defined as int)
public IActionResult GridJson( [DataSourceRequest] DataSourceRequest request, int id){ NameValuePairList lst = new NameValuePairList(); for (int i = 0; i < 5; i++) { lst.Add(new NameValuePair() { Id = $"{i}", Name = nameof(id), Value = $"{id}" }); } var dsResult = lst.ToDataSourceResult(request); return Json(dsResult);}
Script:
<script type="text/javascript"> function getData() { // alert("grid.getData"); var id = document.getElementById("itemId").value; // alert(id); if (id != null) { return { id: id }; } else { return 0; } }</script>
Grid:
<div class="col-sm-4"> <form> <div asp-validation-summary="ModelOnly" class="text-danger"></div> <input type="hidden" id="groupId" asp-for="Item.Id" /> <div class="form-group" style="margin-right: 5%"> <label asp-for="Item.Id" class="control-label"></label> <input asp-for="Item.Id" class="form-control" id="itemId" readonly="true" /> <span asp-validation-for="Item.Id" class="text-danger"></span> </div> </form> @(Html.Kendo().Grid<NameValuePair>() .Name("grid") .Columns(columns => { columns.Bound(p => p.Id); columns.Bound(p => p.Name); columns.Bound(p => p.Value); }) .Pageable() .Sortable() .Scrollable() .HtmlAttributes(new { style = "height:550px;" }) .DataSource(dataSource => dataSource .Ajax() .PageSize(20) .Read(read => read.Action("GridJson", "Site") .Data("getData"))))</div>
Hello, Joel,
The solution seems great! Thank you for sharing it with the community as well.
Regards,
Nencho
Progress Telerik
Our thoughts here at Progress are with those affected by the outbreak.
