Announcement

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

    Paged TreeGrid-Nodes hides and show while opening a node

    Hi there,
    I'm currently testing SmartClient_v100p_2015-04-27_Pro, and I found a visual bug using paged TreeGrids.
    Sorry for reporting another paged-treegrid related issue.

    I'm trying to use all features of the treegrid, so now in order to reduce the count of the datasource-requests the datasource can also return open nodes and the children of the nodes simultaneously. The code example below and the used datasource are only for reproducibility. It isn't our real backend, but it does the job to report the issues, which I have detected using the paged-datasource in our application.
    To not interfere with the bugfixing of the other thread i have copied the datasource, to enable the "canReturnOpenSubfolder"-feature combined with the childCount.

    What the example does:
    It returns for the root-node all childNodes with all their childNodes.
    Using a paged TeeGrid also the childCount-property is set for each node.
    In the initial-server-respone there are all "root-x" and their child-nodes "root-x-y" returned. The nodes "root-x-y" have the childCount-Property set, so the tree does already know how many childnodes will be gathered by the datasource, if the user tries to open "root-x-y".

    The problem like shown below in the gif is, that opening a "root-x-y" nodes results in hiding all nodes, which are below that node. After the loading is finished and the childnodes of "root-x-y" are displayed all childnodes are displayed again.
    This is not really visible if you are testing on localhost. In the example a delay in line 86 is mandatory! Increasing the delay makes the effect more visible. Because the paged TreeGrid is only used if you have a large tree, a delay while requesting the child-nodes is natural.


    Because I have already set the childCount, the tree should not hide the nodes below.
    It's reproducable with the latest nightly build SmartClient_v100p_2015-04-27_Pro and all current browsers (IE, Chrome, Firefox).

    This is the code to reproduce:
    Code:
    isc.VLayout.create({
    	"ID" : "rootLayout_5",
    	"width" : "100%",
    	"height" : "100%",
    	"autoDraw" : true,
    	"hideUsingDisplayNone" : false,
    	"leaveScrollbarGap" : false,
    	"members" :
    	[
    		isc.TreeGrid.create({
    			"ID" : "theTreeGrid",
    			"width" : "100%",
    			"height" : "100%",
    			"selectionType" : "multiple",
    			"canEdit" : false,
    			"showFilterEditor" : false,
    			dataSource : isc.DataSource.create({
    				"fields" :
    				[{
    						"name" : "treeGridGeneratedIndex",
    						"primaryKey" : true,
    						"hidden" : true,
    						"canView" : false
    					}, {
    						"name" : "nameField",
    						"title" : "Reason",
    						"type" : "text"
    					}, {
    						"name" : "parentId",
    						"rootValue" : "root",
    						"foreignKey" : "treeGridGeneratedIndex",
    						"hidden" : true
    					}
    				],
    				"dataFormat" : "json",
    				"dataURL" : "http://devset.de/treegrid2.php",
    				"transformRequest" : requestTransformer,
    				"transformResponse" : responseTransformer,
    				"recordXPath" : "\/resultData",
    				useHttpProxy : false
    			}),
    			dataProperties : {
    				openProperty : "isOpen",
    				childrenProperty : "children",
    				canReturnOpenFolders: true,
    				progressiveLoading : false
    			},
    			"autoFetchData" : true,
    			"dataPageSize" : 50,
    			"dataFetchMode" : "paged",
    			"selectionProperty" : "isSelected",
    			"fields" :
    			[{
    					"name" : "nameField",
    					"title" : "Reason",
    					"type" : "text",
    					"canEdit" : true,
    					"canSort" : true
    				}, {
    					"name" : "lastField",
    					"title" : "Name",
    					"type" : "text",
    					"canEdit" : true,
    					"canSort" : true
    				}, {
    					"name" : "randomField",
    					"title" : "random",
    					"type" : "text",
    					"canEdit" : true,
    					"canSort" : true
    				}
    			],
    			"selectionProperty" : "isSelected",
    			"members" :
    			[]
    		})
    	]
    });
    function requestTransformer(dataSourceRequest) {
    	var operationType = {
    		operationType : dataSourceRequest.operationType
    	};
    	if (dataSourceRequest.operationType == "fetch") {
    		var params = {
    			delay: 300,
    			sortBy : dataSourceRequest.sortBy,
    			start : dataSourceRequest.startRow,
    			end : dataSourceRequest.endRow
    		};
    	}
    	return isc.addProperties({}, operationType, dataSourceRequest.data, params);
    }
    function responseTransformer(dataSourceResponse, dataSourceRequest, jsonData) {
    	if (dataSourceRequest.operationType == "fetch") {
    		dataSourceResponse.totalRows = jsonData.totalRows;
    		dataSourceResponse.endRow = jsonData.endRow;
    		dataSourceResponse.startRow = jsonData.startRow;
    	};
    }
    Best Regards
    Last edited by SimonF; 27 Apr 2015, 01:20.

    #2
    Besides the first issue, there seems to be a second, where the [+]-signs are being hidden if you resort by the first field.

    See here:


    Same example as shown above.
    Reproducable in all current versions of Chrome, IE, Firefox with the latest nightly SmartClient_v100p_2015-04-27_Pro.

    Comment


      #3
      Issue still persists in latest nightly SmartClient_v100p_2015-04-30_Pro.

      Any fix in sight?
      At the current stage with vanishing open-icons and flickering nodes when opening a folder, the paged treegrid is not usable.

      best

      Comment


        #4
        You've submitted a bunch of requests related to the TreeGrid, many of them likely interrelated. We're currently still focusing on internal issues that were brought up by your "open node fetching" sample. The first issue in this thread looks like it may be affected by some of the changes (or requirements we doc) from the other thread. If that's true, we'll want to make sure the doc'd requirements are final first.

        Issue #2 from this thread looks like it may be independent so we'll take a look at that now.

        Comment


          #5
          We've made a fix for SC 10.0p and newer to address the sorting problem you observed. It will be in tomorrow's nightly build.

          Comment


            #6
            Thanks for the information.

            I tested it against the latest nightly SmartClient_v100p_2015-05-05_Pro and the "vanishing open icon"-bug after sorting seems to be fixed.

            Also the second issue seems to be fixed. After clicking the open-icon the loading cursor appears and after loading the nodes they are displayed


            Hopefully this fix was intentionally without being mentioned ;-)

            Best Regards

            Comment


              #7
              Hi,
              sadly i found another "bug" in combination with the treegrid, latest nightly (SmartClient_v100p_2015-05-05_Pro) and all browsers.

              Even if the datasource adds the childCount in every node, it seems that the treegrid doesn't consider them whil drawing the scroll-bar.
              After scrolling down, the scoll-bar gets smaller, but the number of childs is given in the initial request (included the isOpen-attribute)


              Maybe this thread has now some similaritys to the other thread of me here, but here i'm using another datasource.

              This is the code for reproduction
              Code:
              isc.VLayout.create({
              	"ID" : "rootLayout_5",
              	"width" : "100%",
              	"height" : "100%",
              	"autoDraw" : true,
              	"hideUsingDisplayNone" : false,
              	"leaveScrollbarGap" : false,
              	"members" :
              	[
              		isc.TreeGrid.create({
              			"ID" : "theTreeGrid",
              			"width" : "100%",
              			"height" : "100%",
              			"selectionType" : "multiple",
              			"canEdit" : false,
              			"showFilterEditor" : false,
              			dataSource : isc.DataSource.create({
              				"fields" :
              				[{
              						"name" : "treeGridGeneratedIndex",
              						"primaryKey" : true,
              						"hidden" : true,
              						"canView" : false
              					}, {
              						"name" : "nameField",
              						"title" : "Reason",
              						"type" : "text"
              					}, {
              						"name" : "parentId",
              						"rootValue" : "root",
              						"foreignKey" : "treeGridGeneratedIndex",
              						"hidden" : true
              					}
              				],
              				"dataFormat" : "json",
              				"dataURL" : "http://devset.de/treegrid2.php",
              				"transformRequest" : requestTransformer,
              				"transformResponse" : responseTransformer,
              				"recordXPath" : "\/resultData",
              				useHttpProxy : false
              			}),
              			dataProperties : {
              				openProperty : "isOpen",
              				childrenProperty : "children",
              				canReturnOpenFolders: true,
              				progressiveLoading : false
              			},
              			"autoFetchData" : true,
              			"dataPageSize" : 50,
              			"dataFetchMode" : "paged",
              			"selectionProperty" : "isSelected",
              			"fields" :
              			[{
              					"name" : "nameField",
              					"title" : "Reason",
              					"type" : "text",
              					"canEdit" : true,
              					"canSort" : true
              				}, {
              					"name" : "lastField",
              					"title" : "Name",
              					"type" : "text",
              					"canEdit" : true,
              					"canSort" : true
              				}, {
              					"name" : "randomField",
              					"title" : "random",
              					"type" : "text",
              					"canEdit" : true,
              					"canSort" : true
              				}
              			],
              			"selectionProperty" : "isSelected",
              			"members" :
              			[]
              		})
              	]
              });
              function requestTransformer(dataSourceRequest) {
              	var operationType = {
              		operationType : dataSourceRequest.operationType
              	};
              	if (dataSourceRequest.operationType == "fetch") {
              		var params = {
              			delay: 300,
              			sortBy : dataSourceRequest.sortBy,
              			start : dataSourceRequest.startRow,
              			end : dataSourceRequest.endRow
              		};
              	}
              	return isc.addProperties({}, operationType, dataSourceRequest.data, params);
              }
              function responseTransformer(dataSourceResponse, dataSourceRequest, jsonData) {
              	if (dataSourceRequest.operationType == "fetch") {
              		dataSourceResponse.totalRows = jsonData.totalRows;
              		dataSourceResponse.endRow = jsonData.endRow;
              		dataSourceResponse.startRow = jsonData.startRow;
              	};
              }
              Best

              Comment


                #8
                Hi there,
                it seems opening a treenode with the mouse (post from yesterday) is fixed, but if I open a folder-node through a button, working with openFolder, the issue persists. Maybe this was the cause, why it wasn't mentioned.

                It's needed because the user could have the possibility to open multiple nodes, which have the same category, through a button.

                See here:


                Code for reproduction:
                Code:
                isc.VLayout.create({
                	"ID" : "rootLayout_5",
                	"width" : "100%",
                	"height" : "100%",
                	"autoDraw" : true,
                	"hideUsingDisplayNone" : false,
                	"leaveScrollbarGap" : false,
                	"members" :
                	[
                		isc.Button.create({
                			title: "open node 'root-1-3'",
                			width: 200,
                			click:function(){
                				theTreeGrid.data.openFolder(theTreeGrid.data.findById("root-1-3"));
                			}}
                		),
                		isc.Button.create({
                			title: "open node 'root-1-6'",
                			width: 200,
                			click:function(){
                				theTreeGrid.data.openFolder(theTreeGrid.data.findById("root-1-6"));
                			}}
                		),
                		isc.TreeGrid.create({
                			"ID" : "theTreeGrid",
                			"width" : "100%",
                			"height" : "100%",
                			"selectionType" : "multiple",
                			"canEdit" : false,
                			"showFilterEditor" : false,
                			dataSource : isc.DataSource.create({
                				"fields" :
                				[{
                						"name" : "treeGridGeneratedIndex",
                						"primaryKey" : true,
                						"hidden" : true,
                						"canView" : false
                					}, {
                						"name" : "nameField",
                						"title" : "Reason",
                						"type" : "text"
                					}, {
                						"name" : "parentId",
                						"rootValue" : "root",
                						"foreignKey" : "treeGridGeneratedIndex",
                						"hidden" : true
                					}
                				],
                				"dataFormat" : "json",
                				"dataURL" : "http://devset.de/treegrid2.php",
                				"transformRequest" : requestTransformer,
                				"transformResponse" : responseTransformer,
                				"recordXPath" : "\/resultData",
                				useHttpProxy : false
                			}),
                			dataProperties : {
                				openProperty : "isOpen",
                				childrenProperty : "children",
                				canReturnOpenFolders: true,
                				progressiveLoading : false
                			},
                			"autoFetchData" : true,
                			"dataPageSize" : 50,
                			"dataFetchMode" : "paged",
                			"selectionProperty" : "isSelected",
                			"fields" :
                			[{
                					"name" : "nameField",
                					"title" : "Reason",
                					"type" : "text",
                					"canEdit" : true,
                					"canSort" : true
                				}, {
                					"name" : "lastField",
                					"title" : "Name",
                					"type" : "text",
                					"canEdit" : true,
                					"canSort" : true
                				}, {
                					"name" : "randomField",
                					"title" : "random",
                					"type" : "text",
                					"canEdit" : true,
                					"canSort" : true
                				}
                			],
                			"selectionProperty" : "isSelected",
                			"members" :
                			[]
                		})
                	]
                });
                function requestTransformer(dataSourceRequest) {
                	var operationType = {
                		operationType : dataSourceRequest.operationType
                	};
                	if (dataSourceRequest.operationType == "fetch") {
                		var params = {
                			delay: 300,
                			sortBy : dataSourceRequest.sortBy,
                			start : dataSourceRequest.startRow,
                			end : dataSourceRequest.endRow
                		};
                	}
                	return isc.addProperties({}, operationType, dataSourceRequest.data, params);
                }
                function responseTransformer(dataSourceResponse, dataSourceRequest, jsonData) {
                	if (dataSourceRequest.operationType == "fetch") {
                		dataSourceResponse.totalRows = jsonData.totalRows;
                		dataSourceResponse.endRow = jsonData.endRow;
                		dataSourceResponse.startRow = jsonData.startRow;
                	};
                }
                Best

                Comment


                  #9
                  We'll look into this. However, it appears that you're returning nodes marked as leaves (isFolder: false) that have a childCount > 0. That doesn't seem valid. Can you fix that in future samples you submit?

                  Comment


                    #10
                    Thanks for the hint, it's fixed for further debugging. I only have started the datasource to reproduce one bug, so it has grown over the time. Not pretty and surely could have some bugs like this, but it works for reproduction - most of the time ;-)

                    To summarize there are 2 issues here left:
                    #1 Scrolling through the treegrid has the effect that the scroll-bar gets smaller.
                    #2 Opening a folder with the mouse works without hiding the nodes below. Openin a folder with "openFolder" doesn't work and has the same bug as the mouse at the beginning.

                    Best regards

                    Comment


                      #11
                      For #1:
                      When you return a node with a childCount but no actual children, that node is not considered loaded, so there are no rows reserved for its children in the grid. Thus, it's normal for the scrollbar to get smaller as you scroll and more rows are added to the grid due to fetches firing.

                      For #2:
                      This is not a bug per se - the blank space you see represents rows marked as loading, reserved based on the page size. However, we're currently considering whether we can make any improvement that might lead to a better user experience.

                      Finally, we'd like to request that you not return any nodes as open that have a childCount > 0 but no children specified. We consider that an invalid configuration. (This is OK for a closed node.)

                      Comment


                        #12
                        Just for clarification on issue #2, can you describe what you'd like to see happen in this case? Were you expecting to see no visible change until the fetch returns?

                        Comment


                          #13
                          To #1:
                          You're right. After thinking about it again, there is no way of knowing the height, of the whole tree. So after a specific size of the tree there has to be some recalculation for the sidebar.
                          However there could be some calculations, where the recalculation would not be needed. If the childCount is set to opened nodes, without having any children set, there is the information about how tall the tree would be after the first datasource-call. This is what i have thought and why i have set the childCount even if the children of the nodes were not set.
                          At this point I don't understand, why there is the need to "hide" this information to smartclient even if i already have the informations how many children there will be loaded.

                          For: #2
                          For me it makes no sense, to intercept the tree-hiding for the mouseclick, but not for the api-usage.
                          I was expecting, that the behaviour using a button, would be the same as the mouseclick. That the nodes below are not hidden, and after the request is done the nodes are added to the tree. So, the same behaviour as it is if you open the node with the mouse.
                          Sure there is no need to set the cursor to wait ;-)

                          For: Request
                          I have also changed this datasource to only set the childCount if the folder is closed, or if the folder has any children set.

                          For my interest:
                          I haven't tested it out, but is it possible to return children of children in the datasource?
                          By now i have tested if a root-node "root" and the children "root-x" I can also return the children of root-x (root-x-y).
                          Is it also possible to return the children of root-x-y in the same request?
                          I think I haven't read if it's really possible to return such a construct and it's maybe faster to ask this, before I test this out.

                          Best regards

                          Comment


                            #14
                            #1 It's true that if the childCount is known before a node is opened, and it hasn't changed since the user received it, and that node has no open children underneath it, then if all nodes that are currently loading children are all in this exact special state, the scrollbar could be sized accurately for the duration of the network turnaround. We don't currently plan to address this transient, cosmetic edge case that would only come up when the server volunteers extra information not required by the protocol.

                            #2 We'll revisit this.

                            Yes, you can return children of children, to any depth. This is covered in the Tree DataBinding overview.

                            Comment


                              #15
                              For #2, the two situations are identical except that for the programmatic open, a redraw is occurring as the fetch goes out that's not happening when it's done via an opener click.

                              We may be able to provide a way to do the programmatic open without a redraw, but rest assured that that's the only real difference between the two.

                              Comment

                              Working...
                              X