tree.getSelectedItemId() unexpectedly returns 0 for new node

Hi,

Firstly let me start by saying congratulations on an awesomely wholistic and standalone toolset :sunglasses: . I have a home project which for one aspect will need quite a dynamic and responsive UI and DHTMLx is just the thing. I was very happy to have found something so well written, low on dependencies and quite well documented. Thanks for releasing the GPL version as well - without it, I wouldn’t be using DHTMLx and so would not be able to recommend it, which I may well do at work now (for commercial licence).

Unfortunately, however I’ve come across a problem I’ve not been able to resolve on my own. I’ve consulted all the documentation, forums and site search to no avail.

I’m using the GPL version 4.0.

My objective is simply to use a toolbar control to add items of different types to a tree and have that synchronized back to the PHP/MySQL server with a fair bit of UserData (from a form I plan to add later).

When testing some early code, I realized that if I create a new node A and then create a new node B under A, B is lost. That is, when I refresh the HTML page, node B is not in the tree anymore. When I look at the MySQL table data, the specification_parent_id attribute is 0. From debugging in Chrome, I can see that tree.getSelectedItemId() unexpectedly returns 0 when this code is executed during the creation of node B.

Am I doing something wrong :blush: or have I found a bug :nerd: ?

Any help much appreciated. Code samples follow.

Page Code (Tester.html)

<!DOCTYPE HTML>
<html>

<head>
    <title>DHTMLx Tree Tester</title>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <link rel="stylesheet" type="text/css" href="dhtmlx/codebase/dhtmlx.css"/>
    <style>
        /* it's important to set width/height to 100% for full-screen init */
        html, body {
            width: 100%;      /*provides the correct work of a full-screen layout*/
            height: 100%;     /*provides the correct work of a full-screen layout*/
            overflow: hidden; /*hides the default body's space*/
            margin: 0px;      /*hides the body's scrolls*/
        }
    </style>
    <script src="dhtmlx/codebase/dhtmlx.js"></script>
    <script>

	window.ExtractorTreeRootId=12345; // This line is done by PHP usually
	
    function doOnLoad() {
		dhtmlx.image_path='dhtmlx/codebase/imgs/';

		///////////////////////////////////////////////////////////////////////
		// Setup Layout
		var main_layout = new dhtmlXLayoutObject(document.body, '1C');
		var a = main_layout.cells('a');
		a.setText('Tree Problem Demonstration');

		///////////////////////////////////////////////////////////////////////
		// Setup Tree
		var tree = a.attachTree(window.ExtractorTreeRootId);
		tree.setImagePath('dhtmlx/codebase/imgs/dhxtree_'+window.skin+'/');
		tree.loadXML('ExtractorDesignerTreeData.php?id='+window.ExtractorTreeRootId, function(){
			tree.openItem(window.ExtractorTreeRootId);
			tree.selectItem(window.ExtractorTreeRootId);
			tree.setItemCloseable(window.ExtractorTreeRootId,false);
		});
		tree_dp = new dataProcessor('ExtractorDesignerTreeData.php');
		tree_dp.init(tree);
		tree.attachEvent("onSelect", function(id){
			status.setText('You selected Tree item id:'+id);
		});
		
		///////////////////////////////////////////////////////////////////////
		// Setup Toolbar
		var toolbar = a.attachToolbar();
		toolbar.setIconsPath('dhtmlx/codebase/imgs/');
		toolbar.loadStruct('TesterToolbar.xml', function(){});
		toolbar.attachEvent("onClick", function(id){
			var currentNodeId = tree.getSelectedItemId();
			var newNodeId = (new Date()).getTime();
			tree_dp.setUpdateMode("off");
			
			switch (id) {
				case "new_url":
					tree.insertNewChild(currentNodeId,newNodeId,"New URL",0,"world_link.png","world_link.png","world_link.png","SELECT");
					tree.setUserData(newNodeId,'img0',"world_link.png");
					tree.setUserData(newNodeId,'specification_id',newNodeId);
					//Nodes turn red when I do this, so I figure that's not a good idea, as its handled by the DataProcessor?
					//--> tree.setUserData(newNodeId,'specification_parent_id',currentNodeId);
					break;
				case "button_delete":
					if (currentNodeId != 0) {
						tree.deleteChildItems(currentNodeId);
						tree.deleteItem(currentNodeId, true);
					}
					break;
				}
				
			tree_dp.sendData();
			tree_dp.setUpdateMode("cell"); /*enable auto update for dataprocessor again*/
			status.setText('You clicked toolbar button:'+id);
		});
	
		///////////////////////////////////////////////////////////////////////
		// Setup Status Bar
		var status = a.attachStatusBar();
		status.setText('Loaded.');
    }
    </script>

</head>

<body onload="doOnLoad()"></body>

</html>

Toolbar code (TesterToolbar.xml)

<toolbar> <item id="new" type="buttonSelect" img="blue-document--arrow.png" text="New Extractor" title="New Extractor Entity"> <item type="button" id="new_url" text="URL" img="world_link.png" /> </item> <item type="button" id="button_delete" text="Delete" img="cross.png" /> </toolbar>

ExtractorDesignerTreeData.php:

[code]<?php
require(“…/dbDetails.php”);
require(“dhtmlxConnector/codebase/tree_connector.php”);
require(“dhtmlxConnector/codebase/db_pdo.php”);

$db=new PDO(“mysql:host=$DBHost;dbname=$DBName”, $DBUser, $DBPassword);

$treeConn = new TreeConnector($db,“PDO”);
$treeConn->render_table(“extractor_specification”,“specification_id”,“specification_name,specification_id,specification_InputUrlPattern,specification_ContentSelectorType,specification_ContentSelector,specification_OutputDestination,img0”,“”,“specification_parent_id”);
?>[/code]

MySQL Table Structure:


Table Data:


Before Refresh:

After Refresh:

:blush: Oops … 2 things:

I’ve accidentally added BeforeRefresh.png twice. AfterRefresh.PNG is here:

Also, to be a bit more specific:

From debugging in Chrome, I can see that tree.getSelectedItemId() unexpectedly returns 0 on line 53 inside the toolbar’s onClick event for the creation of node B.

Additional screenshot of what I’m getting in Chrome Debugger:


Hello,

Thank you for your kind words about our library :slight_smile:

Nodes turn red when I do this, so I figure that’s not a good idea, as its handled by the DataProcessor?

Please make sure that php script that processes DataProcessor requests returns a correct xml. In case of “insert” request, xml should be like so:

<data> <action type='insert' sid='request_id' tid='response_id'/> </data>

Where sid is an id that is sent via DP request, tid is an id that you save in database. If these ids are different, tree will automatically set the new item id.

Here are details about this:

docs.dhtmlx.com/tree__simultaneo … orhandling

Hi,
I’m starting to pull hair out here :slight_smile:

Okay so I’ve isolated the behaviour down to the files in the attached ZIP file.

As you implied, I’m getting a tid=“0”, so this is likely why getSelectedItem() returns zero in my code.

I cannot however, for the life of me, figure out why 0 is always being returned. I’ve looked through everything I can think of - database schema, server side PHP connector code, client side code…

I’ve zipped and attached all my code that demonstrates this issue. To get this working you should simply have to:

  1. Stand up a MySQL instance
  2. Update dbDetails.php
  3. Create the table in your database according to enclosed file: DefectDemo.sql

I’d certainly appreciate any help you could give, as this is starting to become taxing! No matter what happens, I seem to get XML response:

<?xml version='1.0' ?><data><action type='inserted' sid='1422683575332' tid='0' ></action></data>

Then I check the server side log:

====================================
Log started, 31/01/2015 06:52:55
====================================

DataProcessor object initialized
1422683575332_tr_id => 1422683575332
1422683575332_tr_pid => 1
1422683575332_tr_order => 1
1422683575332_tr_text => New URL
1422683575332_!nativeeditor_status => inserted
1422683575332_id => 1422683575332
1422683575332_other_data => Additional User Data
ids => 1422683575332

Row data [1422683575332]
tr_id => 1422683575332
parent_id => 1
tr_order => 1
name => New URL
!nativeeditor_status => inserted
id => 1422683575332
other_data => Additional User Data

INSERT INTO defect_demo(name,id,other_data,parent_id) VALUES ('New URL','1422683575332','Additional User Data','1')

Edit operation finished
0 => action:inserted; sid:1422683575332; tid:0;

Done in 0.014976024627686s

possible_defect.zip (3.03 KB)

Change id column in the DB from

`id` varchar(15) NOT NULL,

to

 `id` int(11) NOT NULL AUTO_INCREMENT,

The key point - id field must generate new value automatically.

Also, you need not this record in DB ( it is never used )

('0', 'Super Root', '', ''),