Telerik Forums
Kendo UI for jQuery Forum
1 answer
346 views
Kendo UI version 2014.2.903

I'm having some Hierarchical data source / tree view headaches, and wondering if I'm just doing this wrong.

Summary: we want a single local fully populated hierarchical data source as our model, so its easy to visit any node in the hierarchy. And, we want a lazy loaded treeview (dom wise, not data wize) on top of it.


I'm attempting to display our data in a treeview, while having a single datasource/model behind it. All data is already local, so I would like to access the model assuming it's already completely loaded. Of course, the treeview should operate lazily, not creating dom elements until the user expands a node. So, we want the datasource fully loaded, but the treeview dom elements lazy. From what I see, this is not possible.

Here is what I see... Maybe I'm doing something wrong...

Our data in this example is about 6000 items structured hierarchically in an array of objects, each of which may have a Children array field.

Manually populating a hierarchical data source with add() / append() takes about 4 extra seconds. Apparently due to wrapping all the objects? This is too slow for our use case.

Also tried using code just like kendo.observableHierarchy which internally creates a fully loaded hierarchical datasource But again, same extra 4 seconds.

Question: is it really slow due to wrapping? Or due to events firing? Is there a way to batch the updates and make it fast? Again, this is all running against local data.

Let's say we were OK with this extra time. I discovered what I think is a bug in the treeview. On expanding a single node, when it encounters such a fully-loaded datasource structure, the treeview creates its dom elements all the way down the structure, NOT just the level that was expanded. This is obviously a non-starter since it very slow to create all those dom elements.

So, instead we're forced to use the hierarchical data source in its natural lazy mode: children are not copied/wrapped from the input data array until you load the Node, which happens for example when a tree item gets expanded.

This lazy loading causes annoyance any time you need to read/write your model:
For example, you want to find an item in the data source (your model) by ID, in order to set some fields on it, so you recursively visit the items starting from the top. When a level is already loaded, you need to access Children (our own field in the model). But when the level is not loaded, you need to access the hierarchical data source's internal copy of the data at children.options.data (this is the data that will eventually be copied/wrapped and put under Children once the level is loaded).

And, checking whether a level is loaded is also kludgy:
The hasChildren seems accurate, so you know if there are children in general. But, the loaded() function seems to be true in some cases, when in fact nothing has been wrapped/copied under Children yet.

So, you need to check node.hasChildren && Children.length. If that fails, then you know you need to access the children.options.data. This obviously makes dealing with the model a pain.

I'm hoping that I'm just doing this wrong and someone can help me understand the right way to do this.

Summary: we want a single local fully populated data source as our model, so its easy to visit any node in the hierarchy. And, we want a lazy loaded treeview (dom wise, not data wize) on top of it.

Thanks,
Ryan
Alex Gyoshev
Telerik team
 answered on 09 Oct 2014
1 answer
153 views
Hello, 

could you please provide an example how to bind a mobile listview to a hierarchical datasource bound to local json data?
When I try to load child nodes, I get a type error that undefined is not a function.

var node = dataSource.at(0);
node.load(); 

Is it possible to slide the listview content instead of the entire view, when I don't want to use a splitview?

Kind regards
Axel

Alex Gyoshev
Telerik team
 answered on 06 Oct 2014
1 answer
156 views
Hi Guys,

I need you help on the problem that I'm encountering right now. I'm using Kendo I grid with Hierarchy and I have two date picker and button which is not part of the Grid (Please refer to the attachment grid.png). What I want to do is, when the "Update Date" button is clicked, the Period Start and Period End dates will be updated by what ever is selected in the datepicker outside the grid. All the data of all the child is more than 1,000 records. My current code is working, I was able to update all the data of all the child grid. The only problem is, the internet browser is not respoding due to a long running script. I expecting this process to be quick since I'm just only updating the data locally. Do you know a work around for this? Please see my code implementation below.

Grid initialization:

01.var grid = $("#gridJobsH");
02. 
03.grid.kendoGrid({
04.    dataSource: dataSource
05.    , columns: [               
06.        { field: 'HasSAPAccrualsTop', title: " ", template: '<span class="AccrualStatus-#= HasSAPAccrualsTop #"></span>', width: 50, filterable:false, sortable: false}            
07.        ,{ field: 'CommitmentCode', title: 'Purchase Order'}
08.        ,{ field: 'CommitmentSeller', title: 'Subcontractor'}                  
09.    ]
10.    , sortable: true
11.    , reorderable: true
12.    , groupable: false
13.    , filterable: true
14.    , columnMenu: true
15.    , selectable: false
16.    , pageable: false
17.    , resizable: true
18.    , scrollable: {
19.        virtual: true
20.    }
21.    , detailInit: detailInit
22.    , toolbar: [
23.        { template: kendo.template($("#gridJobsHToolbarTemplate").html()) }
24.     ]
25.});

Detail Grid:

01.//Detail grid
02.function detailInit(e) {
03.    $('<div class="hdChildGrid"></div>').appendTo(e.detailCell).kendoGrid({
04.        dataSource: {
05.            data: gridDetails
06.            , autoSync: false
07.            , schema: {
08.                model: {
09.                    id: "PhaseCode"
10.                    ,fields: {                             
11.                        HasSAPAccruals:{ editable: false }
12.                        ,PhaseCode: { editable: false }
13.                        ,Description: { editable: false }
14.                        ,PeriodStart: { editable: true, type: "date" }
15.                        ,PeriodEnd: { editable: true, type: "date" }
16.                        ,CommittedCost: { editable: false }
17.                        ,TotalCostActual: { editable: false }
18.                        ,Accruals: { editable: false }
19.                        ,Incurred: { editable: false, type: "number"  }
20.                        ,CurrentSAPValue: { type: "number" }
21.                        ,SAPAccrualValue: { type: "number"  }
22.                    }
23.                }
24.            }
25.            , filter: { field: "CommitmentCode", operator: "eq", value: e.data.CommitmentCode }
26.        }
27.        , columns: [   
28.            { field: 'HasSAPAccruals', title: " ", template: '<span class="AccrualStatus-#= HasSAPAccruals #"></span>', width: 50, filterable:false, sortable: false, locked: true, lockable: false}
29.            ,{ field: "PhaseCode", title: "Phase Code",  width: 150, locked: true, lockable: false }
30.            ,{ field: "Description", title: "Description", width: 150 }
31.            ,{ field: "PeriodStart", title: "Period Start", width: 150, format:"{0:MM-dd-yyyy}"}
32.            ,{ field: "PeriodEnd", title: "Period End", width: 150, format:"{0:MM-dd-yyyy}"}
33.            ,{ field: "CommittedCost", title: "PO Value", width: 110, type: "number", format: "{0:c}" }
34.            ,{ field: "TotalCostActual", title: "Expenditures", width: 130, type: "number" , format: "{0:c}"}
35.            ,{ field: "Accruals", title: "Accruals", width: 100, type: "number" , format: "{0:c}" }
36.            ,{ field: "Incurred", title: "Incurred", width: 100, format: "{0:c}" }
37.            ,{ field: "CurrentSAPValue", title: "Current SAP Value", width: 170, format: "{0:c}"}
38.            ,{
39.                field: "SAPAccrualValue"
40.                ,title: "SAP Accrual Value"
41.                ,width: 170
42.                ,format: "{0:c}"
43.                ,lockable: false
44.                ,editor: function(cont, options) {
45.                    var amt;
46.                     
47.                    kendo.culture("en-US");
48.                    amt = kendo.toString(options.model.CurrentSAPValue, "c");
49.                     
50.                    $("<span>" + amt + "</span>").appendTo(cont);
51.                }
52.            }
53.        ]
54.        , scrollable: true
55.        , sortable: true
56.        , filterable: true
57.        , columnMenu: true 
58.        , editable: true
59.        , resizable: true
60.        , selectable: "multiple"
61.        , save: function(d) {
62.            if (d.values.CurrentSAPValue) {
63.                d.model.set("SAPAccrualValue", d.model.Incurred - d.values.CurrentSAPValue);
64.                d.model.set('Dirty',true);
65.            }          
66.        }
67.    });
68.}

Button event:

01.var btnUpdateDate = $('#btnUpdateAllDate')
02.    ,infoDialog = $('#infoDialog')
03.    ,btnInfoOK = $("#btnInfoOK").data("kendoButton")
04.    ,infoDialogMsg = $('#infoDialogMsg');  
05.     
06.start = $("#StartDate").kendoDatePicker({value: new Date()}).data("kendoDatePicker");
07. 
08.end = $("#EndDate").kendoDatePicker({value: new Date()}).data("kendoDatePicker");
09. 
10.btnUpdateDate.kendoButton({
11.    click: function(e) {
12.        var startDate = start.value()
13.            ,endDate = end.value()
14.            ,parentGrid = $('#gridJobsH').data("kendoGrid")
15.            ,child = $('.k-detail-row').find('td.k-detail-cell').find('div.k-grid').data("kendoGrid");             
16.             
17.        if(endDate < startDate ) {
18.            infoDialogMsg.html('End date must be ahead to Start date.');
19.            infoDialog.data("kendoWindow").open();
20.        } else {
21.         
22.            var chilEl = $('.hdChildGrid')
23.                ,childGrid = $(chilEl[0]).data('kendoGrid');                   
24.                 
25.            if(childGrid != null) {
26.                var dataSource = childGrid.dataSource;
27.                 
28.                dataSource.fetch(function() {
29.                    var models = dataSource.data()
30.                      ,modelsLength = models.length;
31. 
32.                    for (var i = 0; i < modelsLength; i++) {
33.                        var m = models[i];
34. 
35.                        m.set('PeriodStart', startDate);
36.                        m.set('PeriodEnd', endDate);
37.                    }                   
38.                });
39.            }
40.        }      
41.    }
42.});

Your idea is highly appreciated.

Thanks
Alexander Valchev
Telerik team
 answered on 21 Aug 2014
3 answers
338 views
Dear Team

I have a application need to read a contract from server, when done with edit, need post back how contract back in one time.

let's say the data structure is :
Contract { contractID : string;
                   contractDate: date;
                  contractDetails[] {
                       contractDetailID: string;
                       contractQuantity: integer
                       }
                  }

now I managed to pull the json data from server by webservice.  but I can't bind to contractDetails to KendoGrid.

what I want is holding the instance of  this model in memory and bind the main data to textbox or combo, then bind the children(ContactDetails) to Kendo Grid 

with obeservable applied, the modified will effect this model in order to post back to server to save.

I know there is a way to use "kendo.bind" to bind to the html tag, but will be lack of convenient and style to use Kendo Grid.And there is a way to add to kendo grid manually. But it will lost the convenient of obeservable method.

Please help me, I am a new to Kendo UI and in evaluating stage.

With best regards

Jason

Alex Gyoshev
Telerik team
 answered on 20 Aug 2014
1 answer
252 views
I wanted to ask if it was possible to cause a widget to sort by nested objects' properties. For example, if I had  a data source like the one below, could I sort the data source by parent.name? 

var data = [
    { student: { name: "Peter" }, 
      parent: { name: "Sally"} 
    },
    { student: { name: "Steven" }, 
      parent: { name: "Logan"} 
    },
    { student: { name: "Michael" }, 
      parent: { name: "Liz"} 
    }
];

The hierarchical data source api doesnt have anything on sorting, and the normal datasource api shows how to sort, but not for hierarchical structures. 

Thanks for help!
Alexander Popov
Telerik team
 answered on 04 Apr 2014
1 answer
163 views
Hi,

I am using parameterMap function in HierarchicalDataSource. At root level everything works as expected. But when it is called from nested datasource, then "type" parameter is undefined. I need mapping only for "create" request.

My treeview definition with datasource looks like this:

$("#tree").kendoTreeView({
        dragAndDrop: true,
        dataSource: {
            transport: {
                read: {
                    url: '@Url.Action("Read", "TreeView")'
                },
                update: {
                    url: '@Url.Action("Update", "TreeView")',
                    dataType: 'json',
                    type: 'POST'
                },
                create: {
                    url: '@Url.Action("Create", "TreeView")',
                    type: 'POST',
                    contentType: "application/json; charset=utf-8",
                    dataType: 'json'
                },
                parameterMap: function (data, type) {
                    if (type == "create") {
                        return JSON.stringify(data);
                    }
                    return data;
                }
            },
            schema: {
                model: {
                    id: "Id",
                    hasChildren: "HasChildren"
                }
            }
        },
        dataTextField: 'Name',
        drop: onTreeviewDrop,
        drag: onTreeviewDrag
    });

Thanks for any help!

Daniel
Telerik team
 answered on 19 Mar 2014
1 answer
226 views
Hi,
   I have a problem getting the Hierarchical Data Source to work with a CORS configured WebAPI server whereas a standard Data Source works fine for a grid.  My sample code for a working grid on a CORS data source is as follows:

var buildTestGrid = function () {
        // Setup Data Source
        var ds = new kendo.data.DataSource({
            transport: {
                read: function (options) {
                    console.log("Setting-up testGrid");
                    console.log("Token: " + token);
                    $.ajax({
                        cache: false,
                        url: getUrl("api/v1/items(parent_id=null,is_template=false)"),
                        type: "GET",
                        headers: { "X-Token": token },
                        success: function (response) {
                            console.log("Test Grid... it's ALIVE!");
                            if (response == null || response == "null")
                                console.log("ERROR: No response");
                            else {
                                options.success(response);
                            }
                        },
                        error: function (xhr, status, error) {
                            console.log("Test Grid Error");
                        },
                    });
                },
                batch: true
            },
            pageSize: 10
        });


        // Now configure the grid
        $("#testGrid").kendoGrid({
            dataSource: ds,
            groupable: false,
            sortable: true,
            pageable: {
                refresh: true,
                pageSizes: true,
                buttonCount: 5
            }
        });
    }

However, the data source fails when building a tree control using the following code:

    var buildTestTree = function () {
        // Setup the data source
        var ds = new kendo.data.HierarchicalDataSource({
            transport: {
                read: function (options) {
                    console.log("Setting-up testGrid");
                    console.log("Token: " + token);
                    $.ajax({
                        cache: false,
                        url: getUrl("api/v1/items(parent_id=null,is_template=false)"),
                        dataType: "json", // "jsonp" is required for cross-domain requests; use "json" for same-domain requests
                        type: "GET",
                        headers: { "X-Token": token },
                        success: function (result) {
                            console.log("Test Tree... it's ALIVE!");
                            if (result.length == 0) {
                                console("ERROR: No response");
                            }
                            options.success(result);
                        },
                        error: function (result) {
                            console.log("Test Tree Error");
                            options.error(result);
                        }
                    });
                },
            }
        });


        $("#testTree").kendoTreeView({
            animation: {
                collapse: {
                    duration: 400,
                    effects: "fadeOut"
                },
                expand: {
                    duration: 400,
                    effects: "fadeIn"
                }
            },
            dataSource: ds,
        }).data("kendoTreeView");
    }

Strangely if I configure my service to just return an error message the GET request works fine, but when the tree actually get's data it appears to make a second call and gives the following error:

OPTIONS <URL> 405 (Method Not Allowed) jquery-1.9.1.js:9597
OPTIONS <URL> Invalid HTTP status code 405 jquery-1.9.1.js:9597
XMLHttpRequest cannot load <URL>. Invalid HTTP status code 405 

Thanks










Alex Gyoshev
Telerik team
 answered on 13 Mar 2014
6 answers
650 views
Hi,

i am having trouble with the Hierarchical Data Source in conjunction with the TreeView and nesting. The goal is to show a treeview with root items like "employees", "profiles" and sub items being the acutal items. So every root item is using a different data source. This is not working, as the root nodes are not expanding while the data source seems to load perfectly.
I have prepared a small fiddle to show the problem: http://jsfiddle.net/ruapho/GaFd6/4/

Any ideas?
Daniel
Telerik team
 answered on 11 Mar 2014
1 answer
198 views

http://stackoverflow.com/questions/22156602/angular-kendo-treeview-checkbox-change-event-firing-multiple-times


I am trying to implement the checkbox change event using angular but seeing the event firing multiple times when a checkbox is clicked.I have created a plnkr for this, please help. Ideally it should be fired only once.


$scope.treeOptions = {
checkboxes: {
checkChildren: true
},
dataBound: function(e) {
$scope.attachChangeEvent(e);

}

};Event change code: $scope.attachChangeEvent = function(e) {

var dataSource = e.sender.dataSource;
// issue : change event is getting called multiple times for every click on checkbox
dataSource.bind("change", function(e) {
var selectedNodes = 0;

var checkedNodes = [];

$scope.checkedNodeIds(dataSource.view(), checkedNodes);


for (var i = 0; i < checkedNodes.length; i++) {
var nd = checkedNodes[i];
if (nd.checked) {
selectedNodes++;
}
}
// check the console - this is called multiple times for one checkbox click
console.log(selectedNodes);
});
};
Atanas Korchev
Telerik team
 answered on 04 Mar 2014
1 answer
116 views
I have a TreeView with HierarchicalDataSource and my question is simple: Can I access the current dataItem in the transport.read function?

For instance, consider this code:

new kendo.data.HierarchicalDataSource({
    transport: {
        read: function() {
            // Here i'll prepare my url to be called
            return "my/controller/" + dataItem.Id;
        }
    }
});

I want to access the dataItem's properties of the current expanding node inside the read function. Is this possible?
Alex Gyoshev
Telerik team
 answered on 25 Feb 2014
Narrow your results
Selected tags
Tags
+? more
Top users last month
Mark
Top achievements
Rank 1
Yurii
Top achievements
Rank 1
Leland
Top achievements
Rank 2
Iron
Iron
Iron
Hon
Top achievements
Rank 1
Iron
Deltaohm
Top achievements
Rank 3
Bronze
Iron
Iron
Want to show your ninja superpower to fellow developers?
Top users last month
Mark
Top achievements
Rank 1
Yurii
Top achievements
Rank 1
Leland
Top achievements
Rank 2
Iron
Iron
Iron
Hon
Top achievements
Rank 1
Iron
Deltaohm
Top achievements
Rank 3
Bronze
Iron
Iron
Want to show your ninja superpower to fellow developers?
Want to show your ninja superpower to fellow developers?