Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    treeGrid question

    hi, i have a code that creates a treeGrid (see below) the fetch associated to the treeGrid dataSource is returning xml (see below). my problem is that the info is presented in the treeGrid, but when i click on the last treeGrid node appears again (after the last node) all the nodes and, if i click on the last (new) node this occurs again...

    <?xml version="1.0" encoding="utf-8" ?>
    <NewDataSet>
    <Table>
    <au_id>1</au_id>
    <au_lname>a</au_lname>
    <au_fname>b</au_fname>
    <address>1</address>
    </Table>
    <Table>
    <au_id>2</au_id>
    <au_lname>a</au_lname>
    <au_fname>b</au_fname>
    <address>1</address>
    </Table>
    <Table>
    <au_id>3</au_id>
    <au_lname>a</au_lname>
    <au_fname>b</au_fname>
    <address>1</address>
    </Table>
    <Table>
    <au_id>4</au_id>
    <au_lname>a</au_lname>
    <au_fname>b</au_fname>
    <address>2</address>
    </Table>
    <Table>
    <au_id>5</au_id>
    <au_lname>a</au_lname>
    <au_fname>b</au_fname>
    <address>2</address>
    </Table>
    <Table>
    <au_id>6</au_id>
    <au_lname>a</au_lname>
    <au_fname>b</au_fname>
    <address>4</address>
    </Table>
    </NewDataSet>

    the code is:



    isc.DataSource.create({
    transformRequest : function (dsRequest) {
    return isc.addProperties({}, dsRequest.oldValues,dsRequest.data);
    }, ID:"contacts",
    dataFormat:"xml",
    recordXPath:"//Table",
    //dataURL:'http://192.168.1.9/Webservice2/service2.asmx/executeQuery?sSql=%20',
    fields:{
    au_id:{name:"au_id", primaryKey:true}, // primary key is necessary for removeData
    au_lname:{name:"au_lname"},
    au_fname:{name:"au_fname"},
    address:{name:"address", rootValue:"1",foreignKey:"contacts.au_id"}
    },
    operationBindings:
    [
    {
    operationType:"fetch",
    dataFormat:"xml",
    recordXPath:"//Table",
    dataURL:"http://192.168.1.9/Webservice2/service2.asmx/executeQuery"
    },
    {
    operationType:"add",
    dataFormat:"xml",
    recordXPath:"//Table",
    dataURL:"http://192.168.1.9/Webservice2/service2.asmx/insert"
    },
    {
    operationType:"remove",
    dataFormat:"xml",
    recordXPath:"//Table",
    dataURL:"http://192.168.1.9/Webservice2/service2.asmx/remove"
    },
    {
    operationType:"update",
    dataFormat:"xml",
    recordXPath:"//Table",
    dataURL:"http://192.168.1.9/Webservice2/service2.asmx/update"
    }
    ]

    });



    isc.TreeGrid.create({
    ID: "employeeTree",
    width: 500,
    height: 400,
    nodeIcon:"icons/16/person.png",
    folderIcon:"icons/16/person.png",
    showOpenIcons:false,
    showDropIcons:false,
    closedIconSuffix:"",

    dataSource:"contacts",
    autoFetchData: false,


    data: isc.Tree.create({


    modelType: "parent",
    rootValue: "1",
    nameProperty: "au_lname",
    idField: "au_id",
    parentIdField: "address"
    })

    });

    //employeeTree.getData().openAll();
    employeeTree.fetchData({sSql:'x'});

    thanks

    #2
    Hi Alex
    What's happening is that every time a folder is opened by the user it's sending a request for new data to the server (to load it's children), and the server is responding with the same data that's already been loaded, so the tree is getting loaded into the node as its children, and when a child node of the newly loaded (duplicate) tree is opened, the same thing happens again.

    Essentially when your server code receives fetch requests, it needs to respond with appropriate set of children (the sub-tree) basesd on the request parameters (EG [fetch operation data URL]?address=5).

    Alternatively, if the data described below is the complete set of data, you can mark leaves that have no children as not being folders using the Tree.isFolderProperty (defaults to "isFolder", so you can set isFolder:false on nodes known to have no children).

    I hope this helps
    Please let us know if you need more info

    Thanks
    Isomorphic Software

    Comment


      #3
      Thanks for your reply. i want to make a question:
      ¿ there is a way to suppress this 'load on demand' behavior of the treeGrid ?
      i want to populate this widget using explicit (manual) calls to treeGrid.fetchData.

      Thanks

      Comment


        #4
        treeGrid.loadDataOnDemand

        Hi Alex
        Yes there actually is a property that will simply suppress the "load on demand" behavior - it is not documented publicly in the 5.5.1 release, but is present and should work, and will be documented in future releases.

        Try setting "TreeGrid.loadDataOnDemand:false" on the TreeGrid.
        In this case the TreeGrid assumes that it receives the entire tree from the server on its initial fetch, so any nodes that did not report children initially are assumed to have none.

        Thanks
        Isomorphic Software

        Comment


          #5
          hi,
          that's exactly that i need.
          Thanks.

          Comment


            #6
            child node URL

            Hi,

            When you say:

            ---
            Essentially when your server code receives fetch requests, it needs to respond with appropriate set of children (the sub-tree) basesd on the request parameters (EG [fetch operation data URL]?address=5).
            ---

            1. Where do I specify this URL for getting child nodes?
            2. How do send it the parameter?

            Thanks,
            Mike

            Comment


              #7
              1. the URL is the dataSource.dataURL (although there are other ways to set it more specifically: operationBinding.dataURL per operationType, or dsRequest.actionURL per request)

              2. the parameter is automatic. The ResultTree created by a call to TreeGrid.fetchData() specifies it as dsRequest.data. Then a DataSource with dataProtocol "getParams" will turn it into a URL parameter.

              Comment


                #8
                Right now I have 2 datasources, each linked to a separate PHP script. Is this the right approach for parent / child relationships?

                When TreeGrid.fetchData executes, how does it know I want to read from the child table? There's only one dataURL attribute, which I already have set to read from the parent table.

                Thanks,
                Mike

                Comment


                  #9
                  With two DataSources you can fetch the "children" of the selected record into a second grid via fetchRelatedData(). A TreeGrid on the other hand expects a single DataSource, because even if records come from different tables, the TreeGrid can only display the set of fields they have in common.

                  You can use a single DataSource to fetch from multiple URLs by changing the dsRequest.actionURL on the fly, on a per-request basis, via an override to DataSource.transformRequest().
                  Last edited by Isomorphic; 9 Apr 2008, 11:03.

                  Comment


                    #10
                    The "per-request" basis, I assume, is which tree level I'm trying to expand? How do I trap for that? Can you show any sample code? Is there like a "level=1, level=2, level=3" parameter somewhere?

                    Thanks again,
                    Mike

                    Comment


                      #11
                      Note the original reply should have said "transformRequest", not "transformResponse" and has been corrected.

                      To figure out what level is being loaded, look at dsRequest.data, which will contain the id of the parentNode as automatically passed by the ResultTree. Note that the entire parentNode is also made available as dsRequest.parentNode.

                      Comment


                        #12
                        I got it working, finally.

                        Here's my SmartClient code:

                        Code:
                        isc.TreeGrid.create({
                            ID:"customerTree",
                            dataSource:"customerListDS",
                            showHeader:false,
                            leaveScrollbarGap:false,
                            animateFolders:true,
                            canAcceptDroppedRecords:false,
                            canReparentNodes:false,
                            selectionType:"single",
                            animateRowsMaxTime:750
                        });
                        
                        // Set the customer fields for the datasource below
                        var customerFields = [
                        	{name:"my_name"},
                        	{name:"my_id", primaryKey:true},
                        	{name:"my_parent_id", foreignKey:"customerListDS.my_id", rootValue:'customer0'}
                        ];
                        
                        isc.DataSource.create({
                            ID: "customerListDS",
                        	dataFormat:"json",
                            dataURL:"/gbs/json/customerList.php",
                            fields: customerFields
                        });

                        And here's the PHP:

                        Code:
                        <?php
                        
                        require ($_SERVER["DOCUMENT_ROOT"]."/gbs/shared/database.php");
                        
                        open_db();
                        
                        $customerList = array();
                        
                        $my_parent_id = mysql_real_escape_string($_REQUEST['my_parent_id']);
                        
                        // Trim the word 'customer'
                        if ($my_parent_id != '') {
                        	$my_parent_id = substr($my_parent_id,8);
                        }
                        
                        if ($my_parent_id == '' Or $my_parent_id == '0') {
                        
                        	$query = "SELECT * FROM customers";
                        	$query .= " ORDER BY customers_name";
                        	
                        	$result = mysql_query($query) or die('Class table query failed: ' . mysql_error());
                        
                        	while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
                        	
                        		$treeRow = array();
                        	
                        		// Set up a generic tree record
                        		$treeRow['my_name'] = $row['customers_name'];
                        		$treeRow['my_id'] = 'customer' . $row['customers_id'];
                        		$treeRow['my_parent_id'] = 'customer0';
                        		
                        		$customerList[] = $treeRow;
                        	}
                        
                        } else {
                        	
                        	$query = "SELECT * FROM projects";
                        	$query .= " WHERE projects_customers_id = $my_parent_id";
                        	$query .= " ORDER BY projects_name";
                        	
                        	$result = mysql_query($query) or die('Class table query failed: ' . mysql_error());
                        
                        	while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
                        	
                        		$treeRow = array();
                        	
                        		// Set up a generic tree record
                        		$treeRow['my_name'] = $row['projects_name'];
                        		$treeRow['my_id'] = 'project' . $row['projects_id'];
                        		$treeRow['my_parent_id'] = 'customer' . $row['projects_customers_id'];
                        		
                        		$customerList[] = $treeRow;
                        	}
                        
                        }
                        
                        mysql_free_result($result);
                        
                        close_db();
                        
                        echo json_encode($customerList);
                        
                        ?>

                        As you can see, I'm building a lot of the "intelligence" into the PHP (if you can call it that ;), rather than in the JavaScript, primarily because I don't know the SmartClient method well enough yet.

                        The "ah HA" moment for me came when I realized I needed to create a GENERIC tree record, and populate it with data from either table. (Rather than separate field names from each table).

                        The PHP is code gets more complicated this way, since I can't just dump the recordset into JSON.

                        Once I understand how to manipulate the dataURL in the SmartClient code, I'll redo the PHP, to make it simpler.

                        Any suggestions would be appreciated!

                        Thanks for your help.

                        Mike

                        Comment


                          #13
                          This GUI is amazing, by the way. (Even though I'm just scratching the surface.)

                          I originally saw it running the QuickBooks Time Tracker site. Intuit has done some impressive things with it.

                          Is the TreeGrid one of the more complicated objects? I'm hoping everything else will be a little easier. I feel like I picked the hardest one to start with!

                          Thanks again.

                          Mike

                          Comment


                            #14
                            Thanks for posting that solution Mike, that's quite likely to help others.

                            Yes you did happen to pick a hard starting point (feeding two tables with unrelated columns to one TreeGrid), unless you care to tackle the CubeGrid.

                            Intuit's TimeTracker is very cool - we particular like the Tree/ComboBox autocomplete interaction on the customer/serviceItem field - but the next release is at a whole 'nother level.

                            Comment

                            Working...
                            X