Announcement

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

    Width of listgrid in a hidden tab

    Hey guys,

    I’m working on a tabset which includes listgrids and is beside a treegrid. After creating all components, I need to know the widths of all listgrids.
    Herefor I collect the widths of all listgrids with listGrid.getWidth().
    When doing so, I noticed different widths of listgrids, which have are equal sized.

    This only seems to happen, when a listgrid is inside a layout which is set as pane of a tab.
    After selecting this tab, the width will be answered corretly.
    When having a tab which has a listgrid as pane directly, this issue doesn’t occur.

    To reproduce the issue I built the following example

    Code:
    isc.VLayout.create({
    	"ID" : "rootLayout",
    	"width" : "100%",
    	"height" : "100%",
    	"members" : [isc.Button.create({
    			"title" : "Width of all listgrid",
    			"width" : 200,
    			"action" : function () {
    				isc.say(
    					"Width of first listgrid: " + firstListGrid.getWidth() +
    					"<br>Width of second listgrid: " + secondListGrid.getWidth() +
    					"<br>Width of third listgrid: " + thirdListGrid.getWidth())
    			}
    		}),
    		isc.HLayout.create({
    			"width" : "100%",
    			"height" : "100%",
    			"members" : [isc.TreeGrid.create({
    					"width" : "30%",
    					"height" : "100%"
    				}),
    				isc.TabSet.create({
    					"width" : "70%",
    					"height" : "100%",
    					tabs :
    					[{
    							"title" : "first",
    							"pane" : isc.Layout.create({
    								"width" : "100%",
    								"members" : [isc.ListGrid.create({
    										"ID" : "firstListGrid",
    										"width" : "100%",
    										"fields" : [{
    												"title" : "first"
    											}
    										]
    									})]
    							})
    						}, {
    							"title" : "second",
    							"pane" : isc.Layout.create({
    								"width" : "100%",
    								"members" : [isc.ListGrid.create({
    										"ID" : "secondListGrid",
    										"width" : "100%",
    										"fields" : [{
    												"title" : "second"
    											}
    										]
    									})]
    							})
    						}, {
    							"title" : "third",
    							"pane" : isc.ListGrid.create({
    								"ID" : "thirdListGrid",
    								"width" : "100%",
    								"fields" : [{
    										"title" : "third"
    									}
    								]
    							})
    						}
    					]
    				})]
    		})]
    })
    This issue is reproducible with the current SmartClient nighly ( v10.0p_2015-03-11) and all current browser versions (Firefox, Chrome and IE)

    Best Regards

    #2
    This is basically a result of the fact that a TabSet doesn't actually add the pane (and descendents) of hidden tabs to itself as a child until it is necessary to do so (until the user switches to the tab in question), so a size expressed as a percentage will be considered a percentage of whatever the initial parent - currently the page.

    We wouldn't consider this a bug (though we do see how it could have confused things in your app). Regardless, the fix is probably to look at the size of the container itself if the ListGrid has a percentage size, or wait until the tab is shown.

    Regards
    Isomorphic Software

    Comment


      #3
      Hey guys,

      thanks for your response.

      I tried to implement a workaround to get the correct widths of components in tabs.
      Herefor I need to know, if a width is already set or still a percentage.
      By using getWidth() or directly read the attribute width, I will always get a real (pixel)width. Also I found no alternative to detect, whether a component has a real or percentage width.
      Is there a way to find out if the width is a percentage or a real value?

      Further to calculate the width of a component, I need to iterate over all parents up a component whose width is a real value and calculate the width of all these components.
      If this happens once, thats the same behaviour like it would happen in your framework. But when having to calculate several widths of the same hierarchy, I would have to recalculate the same widths over and over again, which is obviously inefficient and redundant.
      So if this operation would happen in your framework, the calculated widths could be saved and further be used to draw the component (if nothing changed).

      There’s another unclairity of mine.
      You said, the tab doesn’t add the pane and descendents of a hidden tab to itself as a child. Wouldn’t this imply, that the pane of a tab also provides a wrong width?
      Looking at my previously provided example and its third tab, this doesn’t seem to be the fact. So the pane seems to calculate the width without ever been rendered, does it?
      Wouldn’t it be possible to do so for its descendents(childs) when calling getWidth()?

      Best Regards

      Comment


        #4
        Probably the best thing to do here is to clarify exactly what you are trying to achieve and why.

        The "100%" string can be retrieved prior to draw by calling 'getWidthAsString()', but it seems like you're going through a lot of complicated permutations to try to determine an expected pixel size based on this percentage width. One of the strengths of SmartGWT is of course that you can specify sizes as either pixel or percentage values and rely on a lot of sophisticated handling for sizing and positioning of widgets in the framework, without the need to write complicated bespoke sizing code yourself in most cases.

        If we can understand at a high level what you're trying to do, we can probably steer you in a better direction making use of framework features.

        Regards
        Isomorphic Software

        Comment


          #5
          Hey guys,

          I’m trying to implement percentual viewstates.
          Therefore I replace all real values with percentual values when saving the changed viewstate. This works fine, because it only happens, when the user changes the listgrid, so the listgrid is always visible and has its correct size.

          The other way round is more problematic.
          When building a view, I’d like to initialize all listgrids with the saved percentual viewstate by using setViewState(). This happens right after building the view and works fine, except in the provided case of the previous example.
          The problem here is, this approach implies that I have to calculate the real values with the given percentual values and the widths of the correct listgrids. So when getting a wrong width (e. g. too large like in my given example) the viewstate will be reproduced wrong and misses the point.

          I also considered to use the visibilityChanged event, but doing so brings along other issues. I would need to remember for each listgrid, if I already set the viewstate, which seems to be quite “dirty”. The more important issue with this approach is, that there would be loads of unnecessary events (e.g. all listgrids got initilaized with the viewstate and the user switches tabs).

          So either it should be possible to get and set the viewstate with percentage widths or the width of the listgrids should be calculated correctly so the workaround for setting the viewstate after creating the view can work.
          By now neither the percentage width in viewstate nor the workaround for setting viewstate after creation of the view works. The first doesn’t work because of this and this. The other works in most cases but in the described screnario in this thread not.

          Best Regards

          Comment


            #6
            It seems like your primary goal here is to store, and later apply field widths, which include percentage widths for some fields, for a listGrid - and this isn't supported in the viewState system.

            We could add support for this to the viewState system (the cleanest solution) but it would be a Feature Sponsorship - it's not a feature we currently have a plan to add as it has not been heavily requested and we don't consider it a bug.

            Your workaround of using the actual specified width of the ListGrid to calculate your own percent sizes for fields seems like it ought to be workable - but you're facing the problem that prior to draw we haven't necessarily resolved the percent-specified size to a pixel size and if the parent hierarchy isn't the same as the final hierarchy in the grid, you could get a misreported size.

            Actually we revisited this case to see if we could answer this question:
            There’s another unclairity of mine.
            You said, the tab doesn’t add the pane and descendents of a hidden tab to itself as a child. Wouldn’t this imply, that the pane of a tab also provides a wrong width?
            Looking at my previously provided example and its third tab, this doesn’t seem to be the fact. So the pane seems to calculate the width without ever been rendered, does it?
            And realized there is actually a flaw in the test case. You have autoDraw set to true, so the widgets are all getting drawn at the top level as soon as they are created.

            If you modify the sample to have a call to isc.setAutoDraw(false); at the top, and an explicit call to 'draw()' or 'show()' on just the top level layout, the problem goes away. Note that you should test this in a standalone file, not in the feature explorer as that does various things when creating its components which won't match a "real app".

            This may just be enough information to get things working for you, but fundamentally we can't guarantee that the reported pixel width of an undrawn component will be correct if it was specified as a percentage, since the resolving from percent to pixel value is done lazily when required.

            Therefore, your safest solution for determining the explicit pixel width for the listGrid as a whole (assuming we don't just add support for storing out percent field widths as part of a ListGrid's viewstate), would be to add a visibility changed or draw handler, at which time the percentage size will have been resolved to px.

            Comment

            Working...
            X