Opened 12 years ago

Closed 11 years ago

Last modified 4 years ago

#5672 closed defect (fixed)

StackContainer/TabContainer: pane can't contain independently sized layout widgets

Reported by: bill Owned by: bill
Priority: high Milestone: 1.3
Component: Dijit Version: 1.0
Keywords: Cc: Nathan Toone
Blocked By: Blocking:

Description (last modified by bill)

A StackContainer/TabContainer can have arbitrary layout widgets as children, such as TabContainer, and it will render correctly. However, if the StackContainer's child is a ContentPane, and that ContentPane contains various layout widget where the size is set on the layout widgets (rather than inherited from the ContentPane), they will not render correctly. Example (untested) code:

<div dojoType="dijit.Layout.StackContainer" style="height: 500px;">
   <div dojoType="dijit.layout.ContentPane" > ... </div>
   <div dojoType="dijit.layout.ContentPane" > 
             ... random text ...
             <div dojoType="dijit.layout.TabContainer" style="height: 200px;"> ... </div>
             ... random text ...
    </div>
</div>

The problem is that the inner TabContainer needs to visible in order to render. Should probably be using position: absolute, visibility: hidden rather than display: none; to hide the panes.

See also #5546.

Change History (17)

comment:1 Changed 12 years ago by bill

Description: modified (diff)

comment:2 Changed 12 years ago by alex

Milestone: 2.01.3

Milestone 2.0 deleted

comment:3 Changed 11 years ago by bill

Description: modified (diff)

See #6678 for more discussion and possible patch.

comment:4 Changed 11 years ago by bill

See also #6686 for possible patch.

comment:5 Changed 11 years ago by bill

Fixing this might also fix #5553.

comment:6 Changed 11 years ago by bill

See patch to this problem in #8172.

comment:7 Changed 11 years ago by Nathan Toone

Cc: Nathan Toone added

so - we may want to flip the patch from #8172 (if we use it) - and have prerender be true by default. It would be nice, however, to have the old behavior available - in case existing code breaks when using position:relative on the stack container.

comment:8 Changed 11 years ago by bill

Owner: set to bill
Status: newassigned

I'm just going to check it in with prerender as the only option, so we have less testing to do. We can add in both options later if necessary.

comment:9 Changed 11 years ago by bill

Resolution: fixed
Status: assignedclosed

Fixed in [15962]: For TabContainer?, StackContainer?, and AccordionContainer?, render unselected panes offscreen rather than making them display:none. This allows the panes to contain multiple embedded layout widgets (as opposed to a single layout widget which is sized the same as the ContentPane?).

IE6 was problematic; had to hack the CSS to not using visibility:hidden, and to revert to display:none for doLayout=false mode).

Fixes #5672, #5673 !strict.

comment:10 Changed 11 years ago by bill

Also [15942]: Due to [15962], ContentPane? now needs to check if it's been hidden via the dijitHidden class. Refs #5672, #5673 !strict.

comment:11 Changed 11 years ago by bill

Resolution: fixed
Status: closedreopened

Turns out the current solution is bad because fields in the the off-screen panes still get focus when you tab. The obvious solution is to use visibility:hidden on the "hidden" panes but that causes problems on IE6, specifically stuff just becomes permanently invisible.

comment:12 Changed 11 years ago by bill

The problems with IE and visibility:hidden can be seen on nested tabs in test_TabContainer.html and test_!TabContainer_noLayout.html. They involve tab labels and/or tab containers remaining invisible when they should be shown, and visibility:hidden nodes taking up space even though they are position:absolute.

So, can't use visibility:hidden on IE. The other options are:

  1. hide StackContainer children via display:none on IE and visibility:hidden on other browsers. On IE, layout widgets listen to onresize event on this.domNode, which fires the first time the node becomes visible. Then listener calls resize().

This works in general but fails in corner cases: if a ContentPane contains a BorderContainer, and the ContentPane is shown, then hidden, then a child is added to the BorderContainer... when the ContentPane is shown again the BorderContainer won't get any notification and thus won't relayout.

  1. First render all widgets on page, then hide StackContainer children with display:none. Works in general although will fail in corner cases, like programatically adding widgets after the page has rendered, in this layout:
    TabContainer
      ContentPane (selected tab)
      BorderContainer (hidden)  (add child here)
    
  1. for all browsers, use display:none to hide StackContainer children, same as the 1.2 release. Make ContentPane call resize() on all direct descendants when it becomes visible (not just first time it becomes visible, for same reason as listed in (1) above).
  1. make ContentPane a _Container, as suggested in #7819... I originally rejected this ticket but it seems more appealing now, as it would let us avoid sizing of embedded widgets until the ContentPane is shown.

ContentPane.startup() and ContentPane._setContent() would each need to call resize() on all the children... because that's what layout widgets expect.

I'm looking to do (3) and then maybe (4) afterwards.

comment:13 Changed 11 years ago by bill

(In [15971]) Fixes #8024 !strict: if BorderContainer? is initialized in a hidden div (like an unselected tab) then abort resizing, to avoid getting an exception. The TabContainer? etc. will have to call resize() on me later (to notify me that I am now visible and should do layout).

Also refs #5672.

comment:14 Changed 11 years ago by bill

Resolution: fixed
Status: reopenedclosed

(In [15972]) Rollback changes to pre-render panes off screen, as it caused too many problem in IE6. Rather, when a hidden ContentPane is shown, it will now call resize() on all layout widgets that it contains, so that they can correctly layout.

Fixes #5672 !strict.

comment:15 Changed 11 years ago by bill

Implement (4) in [15926]

comment:16 Changed 11 years ago by Nathan Toone

Looks like (4) was actually implemented in [15974] - not [15926]

comment:17 Changed 4 years ago by Bill Keese <bill@…>

In 534157f1ce7473697bd3587d7b39248f50d0ac9e/dijit:

Error: Processor CommitTicketReference failed
Unsupported version control system "git": Can't find an appropriate component, maybe the corresponding plugin was not enabled? 
Note: See TracTickets for help on using tickets.