jQWidgets Forums
jQuery UI Widgets › Forums › TreeGrid › TreeGrid question
Tagged: jquery treegrid, jqwidgets treegrid, treegrid
This topic contains 9 replies, has 2 voices, and was last updated by Peter Stoev 10 years, 2 months ago.
-
AuthorTreeGrid question Posts
-
Dear jQwidgets.
I have created a webbapplication using jqxTreeGrid and jqxGrid. The process goes as following:
1- The treegrid loads json data from C# webservice codebehind. (sucessfull)
2- User select the root node in the tree, the node expandes to multiple values (rows) in the grid with different types KPI’s
3- The user selects Child node, the application gets the root node and takes the value from the kpi(defined as ‘md-0054’), setting the Child node value (that has the same kpicode with the root value)
4- the grid populates with no problems.The problem is the first time there is no problem with the performance but while changing the value over again, the site hangs and in the end chrome crashes. The application tested on jqxTree & jqxTreeGrid with one column(title)
I will try to make a fiddle for this application.
public List<NodeService> LoadTreeView(string s)
{
try
{DataTable CompleteList = new DataTable();
dt = dbService.LoadTree();
dtCom = dbService.LoadRecords();
List<NodeService> ds = new List<NodeService>();
for (int i = 0; i < dt.Rows.Count; i++)
{
n = new NodeService();
n.KeyId = dt.Rows[i][“KeyId”].ToString();
n.ParentId = dt.Rows[i][“ParentId”].ToString();
n.TextDescription = dt.Rows[i][“TextDescription”].ToString();
//n.Node = new Node();
n.ChildrenItems = new List<NodeService>();
n.OriginalItems = new List<NodeService>();
//DataRow dr = new DataRow();
for (int j = 0; j < dtCom.Rows.Count; j++)
{if (dt.Rows[i][“KeyId”].ToString() == dtCom.Rows[j][“ParentId”].ToString())
{n.ChildrenItems.Add(FillNode(j));
}
if (dt.Rows[i][“KeyId”].ToString() == dtCom.Rows[j][“KeyId”].ToString())
{
n.OriginalItems.Add(FillNode(j));}
}
ds.Add(n);}
return ds;
}catch (Exception exception)
{
return new List<NodeService>();
}
}jQuery / JavaScript
———————————<link rel=”stylesheet” href=”jqwidgets/styles/jqx.base.css” type=”text/css” />
<link rel=”stylesheet” href=”jqwidgets/styles/jqx.energyblue.css” type=”text/css” />
<script type=”text/javascript” src=”scripts/jquery-1.10.2.min.js”></script>
<script src=”Code/jqwidgets/jqx-all.js”></script>function LoadTreeView() {
$.ajax({
type: “POST”,
contentType: “application/json; charset=utf-8”,
url: “CompService.svc/LoadTreeView”,
data: JSON.stringify(”),
dataType: “json”,
// prepare the data
success: function (response) {
NodeList = response;
if (NodeList.length) {
InitTreeGrid();
}
treeGrid.jqxTreeGrid(‘expandRow’, ‘-2645627091709935600’);
},
failure: function (response) {
}
});
}function InitTreeGrid() {
treeGrid = $(‘#treeGrid’);
var source =
{
dataType: “array”,
dataFields: [
{ name: ‘KeyId’, type: ‘number’ },
{ name: ‘TextDescription’, type: ‘string’ },
{ name: ‘ParentId’, type: ‘number’ },
{ name: ‘ChildrenItems’, type: ‘array’ },
{ name: ‘OriginalItems’, type: ‘array’ }
],
hierarchy:
{
keyDataField: { name: ‘KeyId’ },
parentDataField: { name: ‘ParentId’ }
},
id: ‘KeyId’,
localData: NodeList
};var dataAdapter = new $.jqx.dataAdapter(source);
treeGrid.jqxTreeGrid(
{
width: ‘100%’,
source: dataAdapter,
height:’100%’,
pageable: true,
//scrollBarSize: 20,
pageSize: 573,
pageSizeOptions: [’15’, ’30’, ‘573’] ,
theme:theme,selectionMode: “singleCell”,
columnsResize: true,
editSettings: {saveOnSelectionChange: true,
cancelOnEsc: true,
saveOnEnter: true,
editSingleCell: true,
editOnDoubleClick: true,
editOnF2: true
},sortable: true,
showHeader: false,
columns: [{ text: ‘TextDescription’, datafield: ‘TextDescription’, cellsAlign: ‘left’, width: 475, editable: false, cellsrenderer: cellsRendererFunction },
{ text: ‘ParentId’, datafield: ‘ParentId’, cellsAlign: ‘center’, width: 100, editable: false, hidden: true },
{ text: ‘KeyId’, datafield: ‘Id’, cellsAlign: ‘center’, width: 100, editable: false, hidden: true }
// { text: ‘MeetingType’, dataField: ‘Id’, hidden: true, filterable: false }
]
});
treeGrid.on(‘rowSelect’,function (event) {var args = event.args;
var row = treeGrid.jqxTreeGrid(‘getRow’, args.key);
var rowkey = row.KeyId;
if (row.OriginalItems[0].TextDescription!=undefined)
header = row.OriginalItems[0].TextDescription.substring(row.OriginalItems[0].TextDescription.indexOf(‘>’) + 1, row.OriginalItems[0].TextDescription.length);var root = treeGrid.jqxTreeGrid(‘getRows’)[0];
for (var r = 0; r < row.OriginalItems.length; r++) {
for (var i = 0; i < root.OriginalItems.length; i++) {
if (row.OriginalItems[r].KPICode.toLowerCase() == root.OriginalItems[i].KPICode.toLowerCase() && root.OriginalItems[i].KPICode.toLowerCase() == ‘md-0015’) {
row.OriginalItems[r].Value=root.OriginalItems[i].Value ;
}}
}
treeGrid.jqxTreeGrid(‘beginUpdate’);
treeGrid.jqxTreeGrid(‘updateRow’, row.KeyId, row);treeGrid.jqxTreeGrid(‘endUpdate’);
var source =
{
localdata: row.OriginalItems,
datatype: “array”,
datafields:
[
{ name: ‘KPIGoalsCategoryScorecardId’, type: ‘string’ },
{ name: ‘LevelNo’, type: ‘string’ },
{ name: ‘KeyId’, type: ‘string’ },
{ name: ‘Code’, type: ‘string’ },
{ name: ‘TextDescription’, type: ‘string’ },
{ name: ‘ParentId’, type: ‘string’ },
{ name: ‘KPICode’, type: ‘string’ },
{ name: ‘KPIShortDescription’, type: ‘string’ },
{ name: ‘TextPrecision’, type: ‘string’ },
{ name: ‘Unit’, type: ‘string’ },
{ name: ‘AggregationMethod’, type: ‘string’ },
{ name: ‘SortOrder’, type: ‘string’ },
{ name: ‘PeriodCode’, type: ‘string’ },
{ name: ‘PeriodDescription’, type: ‘string’ },
{ name: ‘IsReadOnly’, type: ‘string’ },
{ name: ‘DisplayValue’, type: ‘string’ },
{ name: ‘Value’, type: ‘string’ },
{ name: ‘WeightingFactor’, type: ‘string’ },
{ name: ‘UserIdName’, type: ‘string’ },
{ name: ‘DateChanged’, type: ‘string’ },
{ name: ‘RV’, type: ‘string’ }]
};
var dataAdapter = new $.jqx.dataAdapter(source);$(“#jqxDetailsGrid”).jqxGrid(
{
width: 601,
height: 251,
//autoheight: true,
source: dataAdapter,
altrows: true,
//sortable: true,
selectionMode: “singlecell”,
editable: true,
columns: [
{ text: header, datafield: ‘KPIShortDescription’, width: 250, editable: false, cellsrenderer: cellsrenderer },
{ text: ‘Weighting factor’, datafield: ‘WeightingFactor’, width: 150, editable: false, cellsrenderer: cellsrenderer, cellsalign: ‘center’, align: ‘center’ },
{ text: ‘FY15’, datafield: ‘Value’, width: 200, validation: InputValidator, cellbeginedit: ReadOnlyValidation, cellsalign: ‘center’, cellsrenderer: CellsformatingPercent },
{ text: header, datafield: ‘AggregationMethod’, width: 250, editable: false, cellsrenderer: cellsrenderer, hidden: true },
{ text: header, datafield: ‘IsReadOnly’, width: 250, editable: false, cellsrenderer: cellsrenderer, hidden: true },
{ text: header, datafield: ‘KeyId’, width: 250, editable: false, cellsrenderer: cellsrenderer, hidden: true },
{ text: header, datafield: ‘ParentId’, width: 250, editable: false, cellsrenderer: cellsrenderer, hidden: true },
{ text: header, datafield: ‘TextPrecision’, width: 250, editable: false, cellsrenderer: cellsrenderer, hidden: true }]
});$(“#jqxDetailsGrid”).on(‘cellvaluechanged’, function (event) {
// event arguments.
var args = event.args;// row’s bound index.
var rowBoundIndex = args.rowindex;var row = $(“#jqxDetailsGrid”).jqxGrid(‘getrowdata’, rowBoundIndex);
if (row.LevelNo == 0 && row.KPICode.toLowerCase() == ‘md-0015’) {
ApplyToChilds(row);
}});
}function ApplyToChilds(row) {
var KeyId = row.KeyId;
var Nodes = treeGrid.jqxTreeGrid(‘getRow’, KeyId);for (var r = 0; r < Nodes.OriginalItems.length; r++)
if (Nodes.OriginalItems[r].KPICode.toLowerCase() == row.KPICode.toLowerCase()) {
Nodes.OriginalItems[r].Value = row.Value;}
treeGrid.jqxTreeGrid(‘beginUpdate’);
treeGrid.jqxTreeGrid(‘updateRow’, Nodes.KeyId, Nodes);
treeGrid.jqxTreeGrid(‘endUpdate’);
}Hi Mahir Al Rahman,
Memory leak will have if something which is used is not destroyed. I don’t see any code for calling “destroy” method for destroying a widget. If you just update data, you will not have any memory leaks due to the simple reason that the widget uses the same Array of data and simply updates the Array value and updates the DOM Node.
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.com/Dear Peter,
Thank you for replaying. True, i don’t use destroy in my code, because using the destroy on the treegrid will make me losing my data/all expanded nodes ( almost everything), populating a destroyed treegrid from the beginning will reset the treegrid.
I want to keep all behaviors AS IS.
Is there anything i can use?
/Mahir
Hi Mahir,
State Maintenance is unfortunately not available as a feature in this version of jqxTreeGrid. Simply make sure you call only what’s necessary and don’t call what is not necessary. For example, your function LoadTreeView creates TreeGrid, but what happens the next time you call it? It will not create a TreeGrid, but will re-set all properties again which will result in multiple unnecessary re-render operations. You also use “beginUpdate” and “endUpdate” but incorrectly. These should be used when you make many updates at once, but in your code you call these within a loop i.e the performance will degrade from that fact because each time you call endUpdate, the widget will be re-rendered i.e you will re-render that widget on each Loop iteration.
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.com/“If you just update data, you will not have any memory leaks due to the simple reason that the widget uses the same Array of data and simply updates the Array value and updates the DOM Node.”
Peter, you wrote this in your previous comments. My question now is, if i :
1-handle the array for aggregations and updates
2- destroy the treegrid on each update processI will still lose the state of the expanded nodes, that applies to the jqxTree i guess?
/Mahir
Hi Mahir,
Where did you see “destroy on each update” ? I wrote that you will have memory leak if something which is used is not destroyed. I suggest you to re-read my previous post and follow my suggestions there.
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.com/Hi Peter,
Seems like you misread my previous post or i didnt clarify enough. I apologize for that.
I wrote IF i handle the array (not the tree’s records, the array that the tree has been populated from) for aggregations and updates and then i destroy destroy the treegrid on each update process, will i still be facing the lose of expanded nodes state? since the dom removes by calling destroy
/Mahir
Hi Mahir,
If you know what’s updated use updateRow or setCellValue and you won’t lose expanded/collapse states.
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.com/Perfomance problem on:
1- UpdateRow (alone, without beginUpdate/endUpdate) inside and outside the loop
2- UpdateRow (with beginUpdate/endUpdate) inside and outside the loop
3- UpdateRow (without beginUpdate/endUpdate) inside and outside the loop
4- UpdateRow (with beginUpdate / endUpdate) inside and outside the loopHowever. i didnt test setcellvalue, i am gonna test that.
/Mahir
Hi Mahir,
I explained you why you have a performance problem. As you see in the provided demos, there isn’t performance problem even with thousands of records. If you wish, prepare and provide jsfiddle.net example which illustrates your issue.
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.com/ -
AuthorPosts
You must be logged in to reply to this topic.