Configure kendo ui treeview for my json data - kendo-ui

I have the following data:
[
{"id":1,"parendId":0,"name":"Foods","hasItems":"true},
{"id":2,"parentId":1,"name":"Fruits","hasItems":"true"},
{"id":3,"parentId":1,"name":"Vegetables","hasItems":"true"},
{"id":4,"parentId":2,"name":"apple","hasItems":"false"},
{"id":5,"parentId":2,"name":"orange","hasItems":"true"},
{"id":6,"parentId":3,"name":"tomato","hasItems":"true"},
{"id":7,"parentId":3,"name":"carrot","hasItems":"true"},
{"id":8,"parentId":3,"name":"cabbage","hasItems":"true"},
{"id":9,"parentId":3,"name":"potato","hasItems":"true"},
{"id":10,"parentId":3,"name":"lettuce","hasItems":"false"}
]
Can someone tell how I can configure kendo ui treeview for the above data?
Also, is it possible to have this treeview inside kendo ui dropdownlist?
Update:
This is what I have so far...
categories = new kendo.data.HierarchicalDataSource({
transport: {
read: {
url: UrlThatFetchesData
}
},
schema: {
model: {
id: 'id',
parentId: 'parentId',
name: 'name'
}
}
});
$('#tvCategories').kendoTreeView({
dataSource: categories,
dataTextField: 'name',
dataValueField: 'id'
});
All items are displayed as main category, one right below the other.
How do I get the the treeview to use the parentId?

Are you trying to embed inside the treeview item those other data? If that is so, your KendoTreeview should look like this:
#( Html.Kendo().TreeView()
.Name("Treeview")
.DataTextField("name") //display text
.DataSource(dataSource => dataSource
.Read(read => read
.Action("ActionThatFetchesData", "ControllerName")
)
)
.TemplateId("treeview-template") //name of the template
)
And then use a Kendo Template that will display the json
<script id="treeview-template" type="text/kendo-ui-template">
<span>#: item.id#</span>
<span>#: item.parentId#</span>
<span>#: item.name#</span>
<span>#: item.hasItems#</span>
</script>

Related

Kendo headerTemplate

I am trying to build this dojo with the headerTemplate and the columns title and data fields under it but I am not sure what I am doing wrong I am not getting any errors so its hard to understand what is happening?
https://dojo.telerik.com/#mcdevittnccn/iNinebUm
I would suggest a bit different approach here. Problem is that your data is a complex nested object (an object with an array of objects - basically grid inside grid). Kendo data source best works with flattened data. If you can't change data you can use the kendo grid detailInit event so every object array has an inner table with data. Something like this:
$(document).ready(function () {
$("#kendogrid").kendoGrid({
dataSource: {
data: data,
pageSize: 10
},
pageable: true,
scrollable: false,
persistSelection: true,
toolbar: ["search"],
search: {
fields: ['Name']
},
sortable: true,
columns: [
{
field: "Name",
title: "Name"
}
],
detailTemplate: '<div class="grid"></div>',
detailInit: function (e) {
e.detailRow.find(".grid").kendoGrid({
dataSource: e.data.PanelsMeetingViewModel
});
}
});
});
Example: Kendo grid detail init
Note: because of the inner table quick search will not work.

Kendo grid unable to handle script tag data

I am using kendo grid. Some of the data I am getting has script tag in it. I have set column encoded property to true. Still it is not encoding script tag.
You can try this small smaple.
<div id="grid"></div>
<script>
$("#grid").kendoGrid({
columns: [
{ field: "name", encoded: true }
],
dataSource: [ { name: "<script>Jane Doe</script>" } ]
});
</script>
Try stripping those <script> tags in the dataSource.schema.parse event, where you can manipulate dataSource's data before it's been used to render the widget:
schema: {
parse: function(data) {
data.forEach(x => x.name = x.name.replace(/<(\/?)script>/g, ''));
return data;
}
}
Note that the replace is made specific for <script> tags, other tags won't be managed. Regex isn't the best way to handle html, but in case of a specific tag it's ok.
Demo

Issue with expanding and selecting the first node of kendo tree view

I have a kendo tree view which is populated by a hierarchical data source. I want to set the parent node selected and expanded on load of the tree view. I have written the following expand and select to do so. But it is not working .Could anyone provide any solution?
var treeData = new kendo.data.HierarchicalDataSource({
transport: {
read: {
url: NsMenuMaster.urls.getMenuTreeUrl,
data: data,
datatype: "json",
type: "POST"
}
},
schema: {
model: {
id: "MenuConfigUid",
children: "Child"
}
}
});
$("#MenuTreelist").kendoTreeView({
dataSource: treeData,
dataTextField: ["MenuText"],
dataValueField: ["MenuConfigUid"],
height: 1000,
template: kendo.template($("#treeview-template").html()),
checkboxes: {
template: "<input type='checkbox' name='StudentClassID' value='#= item.id #' />",
checkChildren: true
},
select: NsMenuMaster.onSelect
});
$("#MenuTreelist").getKendoTreeView().select(".k-first");
$("#MenuTreelist").getKendoTreeView().expand(".k-first");
The place where you have the .select() and .expand() code is in the wrong spot. At the point at which you are currently calling them, there are not yet any nodes in the tree as the remote dataSource has not yet been populated.
You have to move your select and expand code to after the remote dataSource is read and the .k-first node exists.
You can do this by binding to the first dataBound event of TreeView, i.e:
$("#MenuTreelist").kendoTreeView({
....
});
var treeView = $("#MenuTreelist").getKendoTreeView();
treeView.one("dataBound", function () {
treeView.select(".k-first");
treeView.expand(".k-first");
});
Example: http://dojo.telerik.com/#Stephen/iYIBo

Kendo UI Dropdownlist slow loading from a large datasource

I'm using Kendo dropdownlist in a template. It loads a list of client names which are used to sign a record. The client name list has 8k entries.
The form loads ok but if I select the dropdownlist to change the client name it takes around 10 seconds for the list to appear. Is there something I can do to speed this up?
My datasource:
var dsClients = new kendo.data.DataSource({
transport: {
read: {
url: "/data/clients/key",
dataType: "jsonp"
},
parameterMap: function(options, operation) {
if (operation === "read") {
return options;
}
}
},
serverSorting: true,
sort: [{ field: "text", dir: "asc" }]
});
The element in my template:
<input name="idclt_clm" data-bind="value:idclt_clm" data-value-field="value"
data-text-field="text" data-option-label="Select" data-source="dsClients"
data-role="dropdownlist" required validationMessage="Required" />
There are 2 options that I know of.
You can add virtualization, which I just found from
Kendo.
You can turn of auto-bind and use a search filter that require 2 characters before it triggers a search. Below is how I've done it with asp.net and JS
#(Html.Kendo()
.DropDownList()
.Name("GridName")
.HtmlAttributes(new { #class = "form-control" })
.DataSource(ds => ds.Read(read =>
read.Action("YourFunction","YourController").Data("filterFunction"))
.ServerFiltering(true))
.MinLength(2)//number of characters for a valid search
.Delay(250)//milliseconds delay to trigger search
.AutoClose(false)
.AutoBind(false)
.IgnoreCase(true)
.DataTextField("Text")
.DataValueField("Value")
.Placeholder("Enter at least 2 letters to search")
.Filter(FilterType.Contains)
)
<script>
function filterFunction() {
return {
text: $("#GridName").data("kendoDropDownList").input.val()
};
}
</script>
If the search is still slow, you can change the number of characters
Well, what if you do both? Is maybe not the best aproach, but for me it worked.
I have a ComboBox that gets its info from an cascade event, so it would try either way to fill it up. So, after send the request to fill on server-side, I have a client-side event:
.Filter(Contains).MinLength(n).Filtering("Action")
Which will get to server throgh ajax to catch a Session var with the table/list with which you are trying to fill up your CB. Then filtering the desired list and send it back to your CB.

Kendo Grid does not update the grid with newly created id after creation

I am trying to build a very simple Kendo CRUD grid with a table that has only two columns: ID and Name. I have configured the grid with serverside pagination and serverside filtering.
Everything seems to function as expected but after the new record is created, the grid shows the new record but without the ID field. On creation, the request has ID null but I am sending the value of id and the full object after creation. In example grids, the grid is updated with new values. What do I need to change / add to ensure that the ID of the newly created record shows up in Grid as well?
Following is the JSP:
<script>
$(function() {
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url:"http://localhost:8181/baseweb/countrylist",
dataType: "jsonp"
},
update: {
url: "http://localhost:8181/baseweb/countryupdate",
dataType: "jsonp"
},
destroy: {
url: "http://localhost:8181/baseweb/countrydelete",
dataType: "jsonp"
},
create: {
url: "http://localhost:8181/baseweb/countrycreate",
dataType: "jsonp"
},
parameterMap: function(data, operation) {
if (operation !== "read" && data.models) {
return {grid_options: kendo.stringify(data.models)};
}
return {grid_options: kendo.stringify(data)};
}
},
serverPaging: true,
serverFiltering: true,
pageSize: 10,
schema: {
data: "data",
total: "total",
model: {
id: "id",
fields: {
id: { editable: false, nullable: true },
name: { validation: { required: true } }
}
}
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
pageable: true,
filterable: true,
height: 400,
toolbar: ["create"],
columns: [
{ field: "id", title:"Identification"},
{ field: "name", title:"Country Name" },
{ command: ["edit", "destroy"], title: " ", width: "160px" }
],
editable: "popup"
});
});
</script>
Parameter Sent to the server on create:
_ 1380846899054
callback jQuery19108827040256333442_1380846899052
grid_options {"id":null,"name":"testing"}
Parameter sent back from server as response:
jQuery19108827040256333442_1380846899052([ {"id":"4028828f4180d64a014180e3bda20002","name":"testing"}])
I am expecting that the ID sent back by server should be displayed in the Grid. I have searched this forum, Kendo documentation and Google for an answer but I am unable to find a solution.
What am I missing?
Update with Solution:
Jack's answer provided the clue to finding the solution. I was making two mistakes:
a. The callback in Kendo Grid seems to expect the data back in a "data:" attribute. I was not naming the result set as "data:" in my response.
b. The callback also expects a JSONArray of objects in the data: attribute. I was sending a JSONObject since I was only creating one object.
After I changed the response to include data: attribute and JSONArray, it works perfectly.
The request parameter from the client looks like this:
_ 1386350196768
callback jQuery19101285024500179227_1386350196765
grid_options {"id":null,"name":"Ghana"}
The edited response looks like this:
jQuery19101285024500179227_1386350196765( {"data":[{"id":"2c9323ca42c8df630142c944450b0002","name":"Ghana"}]})
Hope it helps someone else as this is not clearly documented in the official documentation.
There is a nice clean way of doing this...
If your grid is created in script block:
dataSource: {
transport: {
read: {
url: "..."
},
create: {
url: "...",
type: "POST",
complete: function(e) {
$("#grid").data("kendoGrid").dataSource.read();
}
},
}...
OR in HTML
#(Html.Kendo().Grid<ViewModel>()
.Name("grid")
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(10)
.Model(model =>
{
model.Id(i => i.Cde);
model.Field(i => i.Description).Editable(true);
})
.Read(read => read.Action("EditingInline_Read", "UserGroups"))
.Update(update => update.Action("EditingInline_Update", "UserGroups")).Read("EditingInline_Read", "UserGroups")
.Destroy(delete => delete.Action("EditingInline_Delete", "UserGroups"))
.Create(create => create.Action("EditingInline_Create", "UserGroups")).Read("EditingInline_Read", "UserGroups")
)
.Columns(columns =>
{
columns.Bound(s => s.Decription);
columns.Bound(s => s.enabled);
columns.Command(command => { command.Edit(); command.Destroy(); }).Width(200);
})
.Pageable()
.Sortable()
.Selectable(selectable => selectable
.Mode(GridSelectionMode.Single))
.ToolBar(toolbar => toolbar.Create()))
Check out the CRUD calls, more specific, Update and Create.
I've had the same problem and think I may have found the answer. If in the schema you define the object that holds the results, you must return the result of the created link in that same object. Example:
schema: {
data: "data",
total: "total", ....
}
Example MVC method:
public JsonResult CreateNewRow(RowModel rowModel)
{
// rowModel.id will be defaulted to 0
// save row to server and get new id back
var newId = SaveRowToServer(rowModel);
// set new id to model
rowModel.id = newId;
return Json(new {data= new[] {rowModel}});
}

Resources