Kndo TreeView LoadOnDemand not hitting the server - kendo-ui

for my kendo treeview, i set load on demand to true but it is not hitting the server to load childs, because the 'children' property is set for the datasource model, even its empty.
homogeneous = new kendo.data.HierarchicalDataSource({
transport: {
read: {
type: 'POST',
contentType: "application/json; charset=utf-8",
url: obj.DataSourcesURL,
dataType: "json"
},
parameterMap: function (options) {
if (!options.Id) {
options.Id = null;
}
if (options.filter) {
options.Search = options.filter.filters[0].name;
}
else {
options.Search = '';
}
return JSON.stringify(options);
}
},
schema: {
data: "d",
errors: function (response) {
console.log(response);
console.log("errors");
},
model: {
hasChildren: "hasChild",
children:'items',
id: "Id"
}
}
});
And treeView code is
$treeView.kendoTreeView({
dataTextField: 'Description',
checkboxes: {
checkChildren: true
},
dataSource: homogeneous,
loadOnDemand: loadOnDemand,
check: function () {
var checkedNodes = [];
var treeView = $treeView.data("kendoTreeView");
getCheckedNodes(treeView.dataSource.view(), checkedNodes);
setMessage(checkedNodes.length);
},
dataBound: function (e) {
if (e !== undefined)
resetCheckedNodes(e.sender.dataItems());
},
messages: {
loading: "Laden..."
},
expand: function (e) {
var dataItem = this.dataItem(e.node);
}
});

Try to set hasChildren like this in your schema:
schema: {
data: "d",
errors: function (response) {
console.log(response);
console.log("errors");
},
model: {
hasChildren: function(e) {
return e.items && e.items.length;
},
children:'items',
id: "Id"
}
}
And also from your question I am not sure do you even get any data or it is only Children data that is not returned. Maybe you could also show how your data structure look like.

Related

Kendo Multiselect with pre determined values

I have looked everywhere and cant seem to get this figured out. My issue..
I have 1 kendo dropdown list and 3 kendo mutliselects. each selection filters the next object. Dropdownl => MS1 => MS2 => MS3...
At times, a user may come into this page with a predetermined set of values that need to be selected in the above objects. 1 for the DD and 1+ for the MS.
I can get the dropdown to populate and have the corrected selected item. I can get the first MS to populate with the correct values but not select the values that are needed (0 values are selected) and the next 2 dont work cause i cant get past the first MS properly. I feel like I am running into some kind of sync/async issues that I cant wrap my head around.
See code below. I have included all my data sources, object setups and functions that i felt were relevant (maybe too much). The important function is prePopulateSelectedValues. this is the one that gets called to use the values to select the DD list values. I only included one of the updateLineShopGroupMS (for example) as the other update functions are basically the same. Right now I am stuck on 2 different versions of code which both provide the same results - a promise and non-promise version which you can see in prePopulateSelectedValues.
Thank you in advance
var lineShopGroupDataSource = new kendo.data.DataSource({
serverFiltering: false,
transport: {
read: {
url: "/Base/GetLineShopGroupsFilteredByLocationGroup",
type: "GET",
dataType: "json",
data: function (e) {
return {
LocationGroupId: getDropDownLists("LocationGroupId").value()
};
}
}
}
});
var locationGroupDataSource = new kendo.data.DataSource({
transport: {
read: {
type: "GET",
dataType: "json",
url: '/Base/GetLocationGroupNames',
data: function (e) {
return {
LocationGroupId: getDropDownLists("LocationGroupId").value()
};
}
}
}
});
var substationDataSource = new kendo.data.DataSource({
transport: {
read: {
type: "GET",
dataType: "json",
url: '/Base/GetSubstationFilteredByLineShopGroup',
data: function (e) {
let ids = getMultiSelect("LineShopGroup").value();
return {
LineShopIds: ids.toString()
};
}
}
}
});
var circuitDataSource = new kendo.data.DataSource({
transport: {
read: {
type: "GET",
dataType: "json",
url: '/Base/GetCircuitFilteredBySubstation',
data: function (e) {
let ids = getMultiSelect("Substation").value();
return {
SubstationIds: ids.toString()
};
}
}
}
});
function setUpCircuit() {
$("#Circuit").kendoMultiSelect({
autoBind: false,
enable: false,
placeholder: "Select Circuit(s)...",
dataTextField: "Text",
dataValueField: "Value",
dataSource: circuitDataSource,
filter: "contains",
change: function () {
getHiddenCircuitList();
}
});
}
function setUpSubstation() {
$("#Substation").kendoMultiSelect({
autoBind: false,
enable: false,
dataTextField: "Text",
dataValueField: "Value",
placeholder: "Select Substation(s)...",
dataSource: substationDataSource,
filter: "contains",
change: function () {
if (document.getElementById('Circuit')) {
updateCircuitMS();
}
getHiddenSubstationList();
}
});
}
function setUpLineShopGroup() {
$("#LineShopGroup").kendoMultiSelect({
autoBind: false,
dataTextField: "Text",
dataValueField: "Value",
headerTemplate: "<label style='padding-left: 10px;'><input type='checkbox' id='selectAllLineShopGroups'> Select All</label>",
dataSource: lineShopGroupDataSource,
placeholder: "Select Line Shop/Group...",
change: function () {
if (document.getElementById('Substation')) {
updateSubstationMS();
}
checkAllFlag("LineShopGroup");
getHiddenLineShopList();
}
});
}
function setUpLocationGroupId() {
$("#LocationGroupId").kendoDropDownList({
autoBind: true,
dataTextField: "Text",
dataValueField: "Value",
optionLabel: "Select Location Group...",
dataSource: locationGroupDataSource,
change: function () {
if (document.getElementById('LineShopGroup')) {
updateLineShopGroupMS();
}
}
});
}
function prePopulateSelectedValues(locGroupList, lineShopGroupsList, substationList, circuitList) {
if (locGroupList !== "0") {
var locGrpDD = $('#LocationGroupId').data('kendoDropDownList');
var lineShopMS;
$("#LocGroupString").val(locGroupList);
locGrpDD.value(locGroupList);
if (document.getElementById('LineShopGroupString')) {
debugger
var promise = new Promise(function (resolve, reject) {
debugger
resolve(function () {
updateLineShopGroupMS();
});
});
promise.then(function() {
//we have our result here
debugger
var lineShopMS = $('#LineShopGroup').data('kendoMultiSelect');
return lineShopMS; //return a promise here again
}).then(function(result) {
//handle the final result
debugger
$("#LineShopGroupString").val(lineShopGroupsList);
result.value([lineShopGroupsList]);
}).catch(function (reason) {
debugger
});
}
if (document.getElementById("SubstationString")) {
updateSubstationMS();
var substationMS = $('#Substation').data('kendoMultiSelect');
$("#SubstationString").val(substationList);
substationMS.value(substationList);
}
if (document.getElementById("CircuitsString")) {
updateCircuitMS();
var circuitMS = $('#Circuit').data('kendoMultiSelect');
$("#CircuitsString").val(circuitList);
substationMS.value(circuitList);
}
}
}
function updateLineShopGroupMS() {
var msObj = getMultiSelect('LineShopGroup');
var ddValue = getDropDownLists('LocationGroupId').value();
if (ddValue !== '') {
msObj.enable();
lineShopGroupDataSource.read();
}
else {
msObj.enable(false);
msObj.value([]);
}
}

Change Kendo Grid Cell With Ajax Response When Another Cell Changes

Using a Kendo grid with 3 columns, I have an event that fires when the first column is changed that makes an ajax call and returns some data. I want to update the second column with the returned data but I'm not having any luck and I'm not even sure if this is the correct approach. I can change the second column with static data by adding a change event to my datasource of my grid, but that of course doesn't help. The only examples I can seem to find show changing another column with client side data, not data returned from the server. Here's what I have so far:
$("#manualStatsGrid").kendoGrid({
dataSource: this.GetManualStatisticsDataSource(),
sortable: true,
pageable: false,
filterable: true,
toolbar: ["create"],
editable: "inline",
messages: {
commands: {
create: "Add New Statistic"
}
},
edit: function (e) {
var _this = _manualStats;
var input = e.container.find(".k-input");
var value = input.val();
input.keyup(function(){
value = input.val();
});
$("[name='Statistic']", e.container).blur(function(){
var input = $(this);
$("#log").html(input.attr('name') + " blurred " + value);
//valid the GL account number
$.ajax({
type: "GET",
url: _this.ValidateGlUrl,
dataType: 'json',
data: { glNumber: value },
success: function (response) {
var newDescription = response.Data.description;
console.log(newDescription);
//change description column here?
},
error: function (response) {
console.log(response);
}
});
});
},
columns: [
{ field: "Statistic" },
{ field: "Description" },
{ field: "Instructions" },
{ command: ["edit", "destroy"], title: " ", width: "250px"}
]
});
}
this.GetManualStatisticsDataSource = function () {
var _this = _manualStats;
var dataSource = {
type: "json",
transport: {
read: {
type: "POST",
url: _this.GetManualStatisticsUrl,
dataType: "json"
},
update: {
type: "POST",
url: _this.UpdateManualStatisticsUrl,
dataType: "json"
},
create: {
type: "POST",
url: _this.CreateManualStatisticsUrl,
dataType: "json"
},
destroy: {
type: "POST",
url: _this.DeleteManualStatisticsUrl,
dataType: "json"
}
},
schema: {
model: {
id: "Statistic",
fields: {
Statistic: {
type: "string",
editable: true,
validation: { required: true, pattern: "[0-9]{5}.[0-9]{3}", validationmessage: "Please use the following format: #####.###" }
},
Description: { editable: false },
Instructions: { type: "string", editable: true }
}
}
}
Inside the edit event, you have e.model. The model has the method set() which can change any dataItem's property value:
edit: function (e) {
...
var editEvent = e; // Creates a local var with the edit's event 'e' variable to be available inside the 'blur' event
$("[name='Statistic']", e.container).blur(function() {
...
$.ajax({
...
success: function(e, response) { // 'e' inside this callback is the 'editEvent' variable
e.model.set("Description", response.Data.description); // e.model.set() will change any model's property you want
}.bind(null, editEvent) // Binds the 'editEvent' variable to the success param
});
});
Working demo
Made this snippet of top of my head. Tell me if there is something wrong with it.

Kendo treeview HierarchicalDataSource not showing child nodes

I have a kendo Treeview which is showing the parent nodes but the child nodes are not seen. Can anyone tell me where am i going wrong. I am new to this concept. I followed the below link but its not working.
http://demos.telerik.com/kendo-ui/treeview/remote-data-binding
function treeView() {
var treeM = new kendo.data.HierarchicalDataSource({
schema: {
data: function (response) {
console.log("response" + JSON.stringify(response));
var rdata = {};
if (response.d) {
rdata = JSON.parse(response.d);
}
else {
rdata = response;
}
return rdata; // ASMX services return JSON in the following format { "d": <result> }.
},
model: {
hasChildren: true,
id: "ID",
expanded: true,
fields: {
ID: { editable: false, nullable: false, type: "string" },
LINK: { editable: true, nullable: true, type: "string" },
},
},
},
transport: {
read: {
url: "/getParent",
contentType: "application/json; charset=utf-8",
type: "POST",
datatype: "json"
},
parameterMap: function (data, type) {
if ((type == "update") || (type == "create") || (type == "destroy")) {
console.log('parameterMap:');
return JSON.stringify({ "LinksJson": data });
console.log(JSON.stringify(data));
} else {
return data;
}
}
}
});
$("#treeview1").kendoTreeView({
dataSource: treeM,
dataValueField: "ID",
dataTextField: ["LINK","Name"]
});
}
$("#treeview").on("click", ".k-in", function (e) {
var tree = $("#treeview").data('kendoTreeView');
tree.toggle($(e.target).closest(".k-item"));
});
$(document).ready(function () {
treeView();
});
Service:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string getParent()
{
using (var context = new Data.Entities())
{
IQueryable<ERPv2.Data.Links> dataQuery = from x in context.Links
where x.ParentID == 68
select x;
var newQry = dataQuery.AsEnumerable().Select(c => new
{
ID = c.ID,
Name = c.Name,
Children = HasChildren(231)
});
JavaScriptSerializer JSON = new JavaScriptSerializer();
return JSON.Serialize(newQry);
}
}
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public bool HasChildren(int ID)
{
using (var context = new Data.Entities())
{
IQueryable<ERPv2.Data.Links> dataQuery = from x in contextLinks
where x.ParentID == ID
select x;
return dataQuery.AsEnumerable().Any();
}
}
Even when you try to view the child nodes, it will try to call getLinks and not the getreports.
From what i have seen , you should have only one method for getting parent and children. Can be an array inside each parent node.
Can you combine the data from GetReports method inside getlinks itsself and give it a shot.
You should try and get this working here with hardcoded values and then do configure with services.
http://docs.telerik.com/kendo-ui/api/javascript/ui/treeview#configuration-dataSource

How to make the method getItem from the offlineStorage of the Kendo Datasource work with LocalForage

I need to setup my datasource to use localForage to manage my offline data storage.
The problem I'm having is that localForage is asynchronous by nature, only allowing us to use a callback or a promise to retrieve data.
This is how my code is set-up:
(function () {
'use strict';
var serviceId = 'employeeDataSource';
angular.module('app').factory(serviceId, function () {
var crudServiceBaseUrl = 'Data/Employees';
var dataSource = new kendo.data.DataSource({
type: "odata",
offlineStorage: {
getItem: function () {
localforage.getItem('employees-key').then(function (value) {
console.log(value);
return JSON.parse(value);
});
},
setItem: function (item) {
if (item.length > 0) {
localforage.setItem("employees-key", JSON.stringify(item));
}
}
},
transport: {
read: {
url: crudServiceBaseUrl + "/",
dataType: "json"
},
update: {
url: function (data) {
return crudServiceBaseUrl + "(guid'" + data.EmployeeId + "')";
}
},
create: {
url: crudServiceBaseUrl
},
destroy: {
url: function (data) {
return crudServiceBaseUrl + "(guid'" + data.EmployeeId + "')";
}
}
},
batch: false,
pageSize: 5,
serverPaging: true,
schema: {
data: function (data) {
return data.value;
},
total: function (data) {
return data['odata.count'];
},
model: {
id: "EmployeeId",
fields: {
EmployeeId: { editable: false, nullable: true },
Name: { validation: { required: true } },
Email: { validation: { required: true } },
IsManager: { type: "boolean" },
MaxHolidaysPerYear: { editable: false, type: "number", validation: { min: 0, required: true } },
HolidaysLeftThisYear: { type: "number", validation: { min: 0, required: true } }
}
}
},
error: function (e) {
if (e.xhr.responseText !== undefined) {
console.log(e.xhr.responseText);
}
}
});
dataSource.online(navigator.onLine);
$(window).on("offline", function () {
dataSource.online(false);
});
$(window).on("online", function () {
dataSource.online(true);
});
return dataSource;
});
})();
When off-line, the getItem gets called, then the setItem gets call as well with an empty array, hence the:
if (item.length > 0) {
localforage.setItem("employees-key", JSON.stringify(item));
}
When the promise finally returns the off-line data (with the correct values I expected), the Grid displays no results.
This behaviour is presumably because of the promise ?
I tried the same thing with sessionStorage and its worked perfectly... i.e.:
getItem: function () {
return JSON.parse(sessionStorage.getItem("employees-key"));
},
setItem: function (item) {
sessionStorage.setItem("employees-key", JSON.stringify(item));
}
What can I do to get around this?
Just got a heads-up from Telerik
There is an issue logged in their GitHub repo about the same problem.
You can keep track on the progress here:
https://github.com/telerik/kendo-ui-core/issues/326

Kendo UI reload treeview

I load a complex treeview with kendo ui via ajax because I need to load the tree with one request (works fine):
$(document).ready(function() {
buildTree();
});
function buildTree(){
$.getJSON("admin_get_treedata.php", function (data) {
$("#treeview").kendoTreeView({
select: function(item) { editTreeElement(item,'tree'); },
dataSource: data
});
})
}
If I try to reload the complete tree after changing some data via ajax the new build tree does not work correct and does not update the text.
$.ajax({
type: 'POST',
url: 'ajax/ajax_update_layer.php',
data: {
layerid:id,
...
},
success: function(data){
buildTree();
}
});
What can Ido?
Thanks
Sven
try this on ajax success callback
var data = $("#treeView").data('kendoTreeView');
data.dataSource.read();
I got mine to work.
This is what I did:
Function that creates the tree view:
function CreateNotificationTree(userId)
{
var data = new kendo.data.HierarchicalDataSource({
transport: {
read: {
url: "../api/notifications/byuserid/" + userId,
contentType: "application/json"
}
},
schema: {
model: {
children: "notifications"
}
}
});
$("#treeview").kendoTreeView({
dataSource: data,
loadOnDemand: true,
dataUrlField: "LinksTo",
checkboxes: {
checkChildren: true
},
dataTextField: ["notificationType", "NotificationDesc"],
select: treeviewSelect
});
function treeviewSelect(e)
{
var $item = this.dataItem(e.node);
window.open($item.NotificationLink, "_self");
}
}
Modification & data source refresh:
$('#btnDelete').on('click', function()
{
var treeView = $("#treeview").data("kendoTreeView");
var userId = $('#user_id').val();
$('#treeview').find('input:checkbox:checked').each(function()
{
var li = $(this).closest(".k-item")[0];
var notificationId = treeView.dataSource.getByUid(li.getAttribute('data-uid')).ID;
if (notificationId == "undefined")
{
alert('No ID was found for one or more notifications selected. These notifications will not be deleted. Please contact IT about this issue.');
}
else
{
$.ajax(
{
url: '../api/notifications/deleteNotification?userId=' + userId + '&notificationId=' + notificationId,
type: 'DELETE',
success: function()
{
CreateNotificationTree(userId);
alert('Delete successful.');
},
failure: function()
{
alert('Delete failed.');
}
});
treeView.remove($(this).closest('.k-item'));
}
});
});
Hope that helps.

Resources