KendoUI TreeView Dynamic JSON - javascript

I'm attempting to use the KendoUI by Telerik and get a treeview to bind to dynamic JSON from a generic handler.
In my generic handler, I'm using Newtonsoft.Json to convert a List to my JSON results, which works just great and even works with a different KendoUI control (charts).
Here is what I have as far as the javascript to build the treeview:
var treeSource = new kendo.data.DataSource({
transport: {
read: {
url: "Services/CategoryHandler.ashx",
dataType: "json",
contentType: "application/json; charset=utf-8",
type: "GET"
}
}
});
$("#treeview").kendoTreeView({
dataSource: treeSource
});
Here is a shortened example of the returned JSON:
[
{
"text":"Node 1",
"expanded":true,
"items":null
},
{
"text":"Node 2",
"expanded":true,
"items":null
}
]
"items" will be sub collections in the tree.
When I add the items directly to the datasource such as:
var treeview = $("#treeview").kendoTreeView({
dataSource: [
{ text: "Item 1", expanded: true, items: [
{ text: "Item 1.1" },
{ text: "Item 1.2" },
{ text: "Item 1.3" }
] },
{ text: "Item 2", items: [
{ text: "Item 2.1" },
{ text: "Item 2.2" },
{ text: "Item 2.3" }
] },
{ text: "Item 3" }
]
})
It works just fine. It just does not work when I call a service which writes out the JSON, and what I mean by it does not work, is no data shows up, it is blank.
Any thoughts to what I might be missing or guidance to how I can verify my data is even being returned from the service and even filling my DataSource properly?
Thanks

IMPORTANT As November 8th, 2012 KendoUI already supports it.
The Kendo TreeView does not support binding to a data source yet. The good news is that this is in the plans and will be implemented soon (next release).

It works for me with a trick. I am using the dynamic ViewBag with Json serialized at the controller and therefore, nodes are being drawn great.
My issue is that the events don't seem to work ok. For instance I want to catch the onDrop and rise an alert to show the actual values of such node, and instead it displays the text for ALL nodes. This is driving me crazy by the way.
This is my code, hope can help someone.
function onDrop(e) {
alert(treeView.text(e.sourceNode));
}
A Template must be assigned in order to work:
template: "<span rel='#= item.Id #'> #=item.text #</span>",

Related

Unflattening line items in inputData when rendered by function

I have dynamic children input fields that need to be rendered in a function, but when they are, then they are not included in inputData properly/not under the parent input field's key. When the children are included directly in the inputFields, it works as expected, but I can't use a function within the children array with Zapier.
Here is the inputData currently, when the line items are rendered in a function, the LI_ denotes that it is a child input key -
"inputData": {
"supplier": "1",
"LI_budget": 1,
"LI_tax": 1,
"company": "1",
"currency": "1",
"LI_price": "1",
"LI_description": "1"
}
I'm expecting ("parent" is the inputField parent key here):
"inputData": {
"supplier": "1",
"parent": [{
"LI_budget": 1,
"LI_tax": 1,
"LI_price": "1",
"LI_description": "1"
}],
"company": "1",
"currency": "1",
}
This is the function I'm using to pull in the parent and children input fields:
const getLineItems = async (z, bundle) => {
let lineItem = {
key: 'parent',
children: [{
key: 'LI_description',
label: 'Description',
required: true
},
{
key: 'LI_budget',
required: true,
label: 'Budget',
dynamic: 'budget.id'
},
{
key: 'LI_price',
required: true,
type: 'number',
label: 'Unit price',
helpText: 'Example: 50.25'
},
{
key: 'LI_tax',
required: true,
label: 'Tax Rate',
dynamic: 'tax_rate.id'
},
]
}
return [lineItem];
};
There are dynamic fields generated in the getLineItems function that I took out to simplify. TIA
Caleb here from Zapier Platform Support. This is a tough one! We have a pretty long-standing issue report on our platform for supporting custom fields with parent keys (it boils down to a chicken vs the egg problem that really makes my head spin when I read the discussion on the issue). Your inputFields function is spot-on, it's just a matter of properly storing it in the bundle on our part.
I think we could cobble together a workaround to unflatten it. Before I do that though, could you give this a test in the editor and submit actual line items from a previous step to this step? I'm not sure what the inputData looks like (e.g. if multiple items are split like 1,2,3 or in some other fashion). If you want to iterate on this, it might be better to switch over to our public developer Slack (http://zpr.io/ttvdr); then we can post the results here for the next person to run into this. 😁

JSTree not displaying in container

I am trying to incorporate a JSTree structure into my javascript project; however, the tree doesn't seem to be displaying/rendering in its parent container. Here is the code that I am using to display the tree:
let tree=this.tree_div.find('#treeDiv');
tree.jstree(
{
"json_data":
{
"data": [
{
"data": "First",
"children": [{"data": "First"},{"data":"Second"},{"data": "Third"}]
},
{
"data": "Second",
"children": [{"data":"First"},{"data":"Second"},{"data": "Third"}]
},
{
"data": "Third",
"children": []
}
],
},
"plugins": ["checkbox","themes", "html_data", "ui"]
}
).bind("select_node.jstree", function(e, data){});
console.log(tree[0]);
In this example, #treeDiv is the div that is contained by the parent container.
In the last line where the value of the tree is printed, the following line comes up in the console:
To my understanding, this implies that the tree is being successfully initialized and set up, but it still isn't displaying on the web page. Any input would be appreciated. Thanks.
The most plausible explanation here would be that you are initializing the tree using the older jsTree API, while using the newer jsTree library.
Old JSON API: https://old.jstree.com/documentation/json_data
New JSON API: https://www.jstree.com/docs/json/
The newer API has a different object structure for populating the tree. Some of the functions and events remain the same, however many other things including the configuration object has changed.
myTree.jstree({ 'core' : {
'data' : [
'Simple root node',
{
'text' : 'Root node 2',
'state' : {
'opened' : true,
'selected' : true
},
'children' : [
{ 'text' : 'Child 1' },
'Child 2'
]
}
]
} });

Kendo grid removes row, but does not call destory URL

I have a Kendo grid where I'm trying to add a delete feature. My datasource looks like:
var datasource = new kendo.data.DataSource({
transport: {
read: {
url: Router.action("Admin", "GetScansForMailItem", { mailItemIdnt: detailinit.data.MailItemIdnt }),
dataType: "json"
},
destroy: {
url: Router.action("Admin", "DeleteScan"),
type: "post"
}
},
model: {
id: "ScanIdnt",
fields: {
ScanIdnt: {editable: false, nullable: false}
}
},
pageSize: 5
});
I added the model part because this answer, however it made no difference.
The actual grid looks like:
.kendoGrid({
dataSource: datasource
scrollable: false,
sortable: true,
pageable: true,
editable: "inline",
columns: [{
field: "ScanIdnt",
title: "Scan ID"
}, {
field: "CreatedDate",
title: "Created",
template: "#= kendo.parseDate(CreatedDate, 'yyyy/MM/dd') #"
}, {
field: "ScanDocumentRelativePath",
title: "File Path",
template: "<a href='/CAMP/Admin/Download?scanIdnt=#= ScanIdnt #'>#= ScanDocumentRelativePath.substring(1) #</a>"
}, {
field: "ScanUserIdnt",
title: "Scanned By"
},{
command: "destroy",
title: ""
}]
});
Strangely, clicking the delete button removes the from the gird on the UI, but there is absolutely no Ajax call is made the the destroy URL. I can't seem to figure out why. Any ideas?
EDIT I'd like to point out that this grid is in fact a nested grid inside of another grid (like here) I discovered that the parent grid handles actually makes a call, but to the wrong function. For some reason, it clicking delete on a to level item calls the read function of the nested grid, however, the nested grids do nothing
Figured it out (sorta). While I think there were many issues with my code and the grid, It seems that when it came down to it, Kendo didn't like how I had my data.
In the Kendo docs related to hierarchical grids, the data for the child grid is stored in a field of the data for the parent. For example, given the following JSON:
"ParentItems": [
{
"Id": 12345 ,
"Name": "Test1",
"ChildItems": [
{"Id": 1, "Name": "Test"},
{"Id": 2, "Name": "Test"}
]
},
{
"Id": 12346 ,
"Name": "Test2",
"ChildItems": [
{"Id": 1, "Name": "Test"},
{"Id": 2, "Name": "Test"}
]
}
]
In the parent grid, each ParentItem would display it's respective ChildItems in the child grid.
On the other hand, I was pulling both data sets separately. Basically, I pulled the ParentItems like:
"ParentItems": [
{
"Id": 12345,
"Name" : "Test1"
},
{
"Id": 12346,
"Name" : "Test2"
}
]
And then made a second request to pull the child items, based on the parent's id.
"ChildItems": [
{"Id": 1, "Name": "Test", "ParentId": "12345"},
{"Id": 2, "Name": "Test", "ParentId": "12345"}
]
I was able to modify the server side code to serve the data like in the very first example and managed to get things working. The specific document that helped me out can be found here

Kendo, kendoDropDownList, _selectedValue, always the first option

This is probably easy but I'm stuck.
I have a function that works with a kendoDropDownList and I cannot retrieve the value of the selectedIndex. Ignoring what the function actually does, can someone explain this?
function setDocTypeAssociates(event){
var dropdownlist = $("#type_doma_ky").data("kendoDropDownList");
console.log(dropdownlist);
console.log(dropdownlist._selectedValue);
console.log(dropdownlist.selectedIndex);
...
The result of those three console.log()s you can see in the attached screendump.
Why are the values correct (65 and 4) in the object, yet incorrect (67 and 0) when I dump them individually?
It is really hard to say why you get these results, I personally tried to reproduce them and was unable.
Any way the best way to get your data would be:
var dropdownlist = $("#list").data("kendoDropDownList");
console.log(dropdownlist);
console.log(dropdownlist.text());
console.log(dropdownlist.value());
console.log(dropdownlist.selectedIndex);
with text() and value() functions.
In general Telerik does not recommend using fields that start with underscore because they are setup for internal use and might change. For example in the latest version of Kendo UI _selectedValue returns undefined.
I have created working example for your reference.
http://dojo.telerik.com/eNUkU
look at this fiddle:
(https://jsfiddle.net/cr1v6cvh/1/)
Get Data
<script>
$("#btnGetData").kendoButton({
click: function (event){
var dropdownlist = $("#dataList").data("kendoDropDownList");
console.log(dropdownlist);
console.log(dropdownlist.text());
console.log(dropdownlist.value());
console.log(dropdownlist.selectedIndex);
}
})
$(document).ready(function() {
$(".ddlData").kendoDropDownList({
dataTextField: "text",
dataValueField: "value",
dataSource: [
{ text: "data 1", value: "1" },
{ text: "data 2", value: "2" },
{ text: "data 3", value: "3" },
{ text: "data 4", value: "4" }
]
});
});
</script>

KendoUI ObservableArray children being clobbered by KendoUI treeView

Backstory
I'm using AngularJS/KendoUI and using angular-kendo-ui as a the 'bridge' between the two. I'm using Kendo for it's treeview component and this piece is a client requirement.
What I need to accomplish is
1. draw the tree menu from data provided by a service
2. periodically check each element in this data, and update a 'disabled' prop
3. redraw elements in the treeview based on the results from the above step.
Assumptions
1. If I want to be able to update the kendo tree view, then I need to use Kendo's observeables
2. I may be using Kendo's ObservableArray incorrectly here.
The problem
If I create a new ObservableArray like so
var things = new kendo.data.ObservableArray([{
text: "Parent 1",
items: [{text: "Child 1"}, {text: "Child 2"}, {text: "Child 3"}]
}])
things be logged to the console and the structure is intact.
However, once the treeview is instantiated with this data, further logging of things to the console show that the children (items) are no longer present. It is very hard to iterate over and update children if they don't exist!
Plunker here http://plnkr.co/edit/qJpIvK?p=info, if you view the 'script.js' file and open the console, you should be able to see my issue.
here is the code
HTML
<div ng-app="MyApp">
<div ng-controller="TreeController">
<div kendo-tree-view k-options="thingsOptions"></div>
</div>
</div>
JS
var app = angular.module("MyApp", ["kendo.directives"]);
app.controller('TreeController', function($scope, $timeout) {
var things = new kendo.data.ObservableArray([{
text: "Parent 1",
items: [{
text: "Child 1"
}, {
text: "Child 2"
}, {
text: "Child 3"
}]
}, {
text: "Parent 2",
items: [{
text: "Child 1"
}, {
text: "Child 2"
}, {
text: "Child 3"
}]
}]);
// should have 3 items
console.log('preTreeView init', things[1].items);
$scope.thingsOptions = {
dataSource: things
};
$timeout(function() {
// the 3 items expected are gone, why?
console.log('postTreeView init', things[1].items);
}, 1000);
});
Is this a misuse of ObservableArray and if so, what is the correct approach?
Internally, the TreeView widget turns your ObservableArray into a kendo.data.HierarchicalDataSource http://docs.telerik.com/kendo-ui/api/framework/hierarchicaldatasource which moves each of the children into DataSource objects of their own.
You can navigate them afterward like this:
var treeViewWidget = $(".k-treeview").data("kendoTreeView");
var dataSource = treeViewWidget.dataSource; // this is a HierachicalDataSource
var parents = dataSource.data(); // Parent1 and Parent2
var parent1 = parents[0];
var doesParent1HaveChildren = parent1.hasChildren; // true
var childrenDataSource = parent1.children; // this is a HierarchicalDataSource
var child1 = childrenDataSource.data()[0]; // this is {text: "Child 1"}

Categories

Resources