Drawer component


(think socks, not crayons)

Here’s a component that I made for another project, but decided to do it as a standalone project. A Directory-compatible, Vaadin 6.2-requiring jar is, naturally included.

The idea of the Drawer is to hide infrequently used information, while keeping it at hands at all times. My particular use case is to provide past events other information that might be occasionally interesting, but I don’t want them to clutter the UI by default. GWT has a very similar component by the name DisclosurePanel. Unfortunately, I couldn’t rig it to work with Vaadin directly, so I decided to write my own from scratch.

A live demo can, as usual, be found at
http://henrik.virtuallypreinstalled.com/Drawer
, and the sources are available in
incubator SVN
. As promised, there’s also a ready-made
jar
, for your convenience.

Once you have added the jar to your application’s classpath, you need to recompile your application’s widgetset. You also need to add the line “@include url(‘…/drawer/drawer.css’);” to your application’s theme css. After that, you’re set.

A word of caution: though IE gives it a good try, it fails to render the component correctly. It’s tested to work beautifully on firefox and safari.

wow! Not if we only could have IE compatibility … ;)

Ah, yes. IE. The epitome of developer anguish. I’d love to add IE compatibility, but I’m afraid I don’t have IE readily available for development. And even if I had, I probably wouldn’t know how to jiggle the pieces together.

Any help getting IE to the straight and narrow is accepted and much appreciated. It is, after all, open source :slight_smile:

The Drawer is now updated to version 1.1.

Now you don’t need to manually include the Drawer’s theme, it’s included automatically. The Drawer is also now correctly using variables and properties (see
http://wolfie.github.com/2009/12/06/now-i-know.html
for more info). I also fixed a bug, thanks to Risto for informing me.

As appropriate, the repository includes
an updated jar file
.

The drawer has got a minor update:

  • It’s now formatted for Java 5 and the jar contains only the sources. This makes it work in Java 5 projects, too.
  • The package name has changed from “com.vaadin.incubator.drawer” to “org.vaadin.henrik.drawer”
  • The SVN repository URL is now http://dev.vaadin.com/svn/contrib/Drawer

The maintenance information is also now being moved to
http://vaadin.com/web/henrik/wiki/-/wiki/Main/Drawer

Do you think this will become part of the 6.3 release or will it remain contrib-only?

Would the PopupPanel be the “official way” to do this sort of thing for now? I don’t have IE 6 around anymore so I don’t know if PopupPanel works on that beast or not either.

I have a few bits that were GWT DisclosurePanel before, so your Drawer certainly seems like a nice replacement.

I haven’t heard that it would be a part of any planned release, so I think it’s destined to be contrib-only for the foreseeable future, unfortunately.

I’ve just starting use Drawer 1.1.3 with Vaadin 6.3 nightly in a Form, and I see an oddity that I’m not sure how to fix. This happens on both FF 3.5.7 and IE 8.

My Form (using a BeanItem data source) is driven by a Table (like the tutorial).

When I click on an item in the table, it populates the Form. I happen to have 5 TwinColSelect boxes in a VerticalLayout used for the Drawer.

Like the Tutorial, I have an Edit button (allows changes) and a Cancel button (all fields are read-only).

What I found is that if the Drawer is closed, when I toggle Edit-Cancel, the Drawer will still open/close, but it won’t have my TwinColSelect boxes visible at all.

If the Drawer is open, I can toggle between Edit/Cancel modes and it works as expected, showing the TwinColSelect boxes in both editable and read-only modes.

When the user clicks Cancel in edit mode, I essentially do discard() and setReadOnly(true) that calls setVisible() on the various buttons as well as the super.setReadOnly(true). The Edit button just calls setReadOnly(true). I don’t do any changes specifically to the Drawer, but presume the super.setReadOnly is changing the drawer’s state.

The Drawer appears to work as expected when I first click on a new item in the Table; that is, the Drawer opens and closes and shows the TwinColSelects. But after that, if I close the drawer and then change from Edit to Cancel, the Drawer will appear empty (it actually opens and shows a little space, but no select boxes).

Any thoughts on what I might need to do to fix this?

It appears that the DOM elements are there, too, even when they won’t display after the Drawer is opened.

Here’s the HTML captured from firebug in FF:

<div class="v-drawer-content" style="height: 28px; width: 952px;">
  <div style="overflow: hidden; width: 952px; height: 28px;" class="v-verticallayout">
    <div style="margin: 0px; overflow: hidden; width: 952px; height: 28px;">
      <div style="overflow: hidden; height: 0px; width: 952px; padding-left: 0px; padding-top: 0px;">
        <div class="v-caption" style="width: 952px; margin-left: 0px;">
          <div class="v-captiontext">LIST PERMISSION:</div>
          <div style="overflow: hidden; clear: both; width: 0pt; height: 0pt;"></div>
        </div>
        <div style="float: left; margin-left: 0px;">
          <div class="v-select-twincol v-readonly" style="width: 60em; position: relative;">
            <select tabindex="0" class="v-select-twincol-options" size="5" style="width: 42%;" multiple="" disabled="">
              <option value="3">Group3</option>
            </select>
            <div class="v-select-twincol-buttons" style="width: 15%;">
              <div tabindex="0" class="v-button v-disabled" role="button">
                <span class="v-button-wrap">
                  <span class="v-button-caption">&gt;&gt;</span>
                </span>
              </div>
             <div class="v-select-twincol-deco">
               <span></span>
             </div>
             <div tabindex="0" class="v-button v-disabled" role="button">
               <span class="v-button-wrap">
                 <span class="v-button-caption">&lt;&lt;</span>
               </span>
             </div>
           </div>
           <select tabindex="0" class="v-select-twincol-selections" size="5" style="width: 42%;" multiple="" disabled="">
             <option value="1">SuperGroup</option>
           </select>
         </div>
       </div>
     </div>

I don’t know if it’s the overflow:hidden or not, but it seems like many of the

elements are not visible even though the Drawer has been opened.

It seems there’s some sort of interaction between making the Form readonly and the Drawer’s needs to make it’s components appear/disappear too.

First of all, thanks for trying the component out. Secondly, I’m sorry that you have troubles with it (and that I replied only now). But I’m very glad you took the time to report your problems with such detail (a rare treat, indeed).

This seems like a curious problem and I have no direct guess what would be the culprit. There can be some occasions where the contained item is like one pixel larger than what is calculated by the drawer, making it wrap “beneath” the drawer, and the overflow: hidden makes it simply disappear.

Unfortunately I don’t know when I have the time to give this problem a look-see. With any luck, I might have the time to build a test case for this at the beginning of next week.

Are you kidding? Thank you! I like what I see so far, and aside from this mystery (damn those testers since I hadn’t even noticed).

I do know that the Form does readonly settings and edit changes, and the drawer makes this visible/invisible, so I’m guessing there’s some interplay that goes awry. I have noted it happens on all my browsers (FF 3.5, IE8, Chrome, Safari).

I can try to help out, but being a somewhat novice vaadin user (we’re still just investigating it, now trying to ckeditor integration before we take the leap, but I confess to love what I’ve seen so far), I’m not sure how easily I can help. Let me know… Thanks for your consideration and time. The code we have is AGPL, so if reading that code would help, let me know since it’s possible we’re doing something else wrong. But the Drawer more or less works as expected, so it’s only this odd case that shows the rendering problem.

Hi guys,

I just thought I’d chime in with this:
#3609

Could your problem be something like that?

/Jonatan

It does sound like a similar problem, but the bug report says it was fixed in 6.2. I’m using 6.3 nightly and presume that it would be there as well. But it could be something like that since when the Drawer is closed and the Form changes the state from readonly/editable, the issue seems to crop up.

I figured maybe a short video clip showing the problem might help explain it:


http://www.youtube.com/watch?v=fupHolCu3Mg

Thanks…

Thanks for the video! I’m sad to say that I have been too busy (i.e. lazy) to take a look at that problem. And when I haven’t been busy (i.e. lazy), I’ve simply forgot all about this.

I’ll take a look at it later today. This all sounds pretty weird, and sounds like Jonatan might actually be onto something. If it indeed is a visibility-related problem, there’s only so much I can do.

There’s one workaround that I might suggest meanwhile, and see what it does: when you make the form read-only, wrap the call with an open/close call. So, something like this:

drawer.setDrawerOpen(true); // ugh, I already regret that method name...
form.setReadOnly(true);
drawer.setDrawerOpen(false); // ..."The Club of Tautology Club"

No worries, that’s the unfortunate side effect with sharing code: no good deed goes unpunished :smiley:

I gave that workaround a try, but it had no effect. In some ways, it’s not really related to being read-only, per se, since if the Drawer is already read-only, but is open, putting it into “edit” mode will make it appear, and then putting it into read-only mode will be fine.

The real problem is when the mode changes while it’s closed.

I tried:

    	boolean drawerIsOpen = drawer.isDrawerOpen();
    	if ( ! drawerIsOpen ) {
    		drawer.setDrawerOpen(true);
    	}
    	super.setReadOnly(readOnly);
    	if ( ! drawerIsOpen ) {
    		drawer.setDrawerOpen(false);
    	}

This had no positive effect, nor did doing it based on the ‘readOnly’:

    	if ( readOnly ) {
    		drawer.setDrawerOpen(true);
    	}
    	super.setReadOnly(readOnly);
    	if ( readOnly ) {
    		drawer.setDrawerOpen(false);
    	}

This was in some ways worse because it forced the drawer to be closed on read-only, which forces the bug to appear. Without out, you can switch to read-only mode fine as long as the drawer was open.

No worries… if I weren’t so lazy I’d dig out the specs on doing widget debugging and give it a try. I am using 6.3+GWT 2.0, so I know it’s possible to debug the widgets like I did when I was doing pure GWT 2 coding, but I don’t recall all that’s needed to make that work in a Vaadin environment.

Thanks for your help and widget, and hopefully it’ll get resolved one of these days. If I get more info, I’ll pass it along.

I have now the Drawer in front of me, and I can replicate your problem. It seems to have something to do with modifying the contents of the drawer in pretty much any way while it is closed. E.g. I have a VL in a drawer. If i add a component (in my case, a Label) while the drawer is closed, trying to open it, doesn’t open it at all. Adding another component while it (tries) to be open, will reveal the contents, correctly with two new Labels.

It appears that this has something to do with Vaadin calculating heights wrong on modified, hidden, components. This can be seen by studying the DOM, and noticing that the containing layout (VerticalLayout) gets a height of 0px. This doesn’t help at all even if you call drawer.setDrawerHeight(300). The drawer expands to 300 pixels, but the containing layout is still 0px, again, made evident by FireBug.

That said, I don’t know if there’s much the Drawer, or me for that matter, can do about this. I’ll try to look at this a bit more, but it might be business for the Vaadin-department…

Thanks for checking further. I hope it’s something the Vaadin team can take a look at. I know that I’m not really modifying the Drawer contents other than switching between read-only and edit mode in my Form.

It is interesting because I start in Edit mode with the Drawer closed. And it opens/closes fine. But once the Form goes read-only, if the Drawer remain open, all’s good when I switch back and forth between read-only and edit modes. But if the Drawer is closed when I make the read-only/edit mode switch, it comes up blank whenever it’s opened. Then if it’s in the empty open mode, changing read-only/edit makes it appear again as expected in the right mode.

So, when I first edit a bean in my table view so that it’s selected in the form view, I put the form into edit mode and the drawer is closed.

Here’s what it shows for that drawer div to my first TwinColSelect div

<div class="v-drawer-content" style="height: 0px; width: 872px; display: none;">
<div style="overflow: hidden; width: 872px; height: 503px;" class="v-verticallayout">
<div style="margin: 0px; overflow: hidden; width: 872px; height: 503px;">
<div style="overflow: hidden; height: 95px; width: 872px; padding-left: 0px; padding-top: 0px;">
<div class="v-caption" style="width: 872px; margin-left: 0px;">
<div class="v-captiontext">LIST PERMISSION</div>
<div style="overflow: hidden; clear: both; width: 0pt; height: 0pt;"></div></div>
<div style="float: left; margin-left: 0px;">
<div class="v-select-twincol" style="width: 60em; position: relative;">

Then I open the drawer, and I’ve noted the first time I open it, I usually get a flash like the whole page is repainted, but when I close/open the drawer after that, it no longer flashes until I select a new bean from the table. At any rate, when it’s open, here’s what firebug shows:

<div class="v-drawer-content" style="height: 503px; width: 855px;">
<div style="overflow: hidden; width: 855px; height: 503px;" class="v-verticallayout">
<div style="margin: 0px; overflow: hidden; width: 855px; height: 503px;">
<div style="overflow: hidden; height: 95px; width: 855px; padding-left: 0px; padding-top: 0px;">
<div class="v-caption" style="width: 855px; margin-left: 0px;">
<div class="v-captiontext">LIST PERMISSION</div>
<div style="overflow: hidden; clear: both; width: 0pt; height: 0pt;"></div></div>
<div style="float: left; margin-left: 0px;">
<div class="v-select-twincol" style="width: 60em; position: relative;">

I have a new height/width and the display:none is gone. And it looks good.

Then I close it again, and display:none is back and the height goes back to zero, which I presume is fine:

<div class="v-drawer-content" style="height: 0px; width: 855px; display: none;">
<div style="overflow: hidden; width: 855px; height: 503px;" class="v-verticallayout">
<div style="margin: 0px; overflow: hidden; width: 855px; height: 503px;">
<div style="overflow: hidden; height: 95px; width: 855px; padding-left: 0px; padding-top: 0px;">
<div class="v-caption" style="width: 855px; margin-left: 0px;">
<div class="v-captiontext">LIST PERMISSION</div>
<div style="overflow: hidden; clear: both; width: 0pt; height: 0pt;"></div></div>
<div style="float: left; margin-left: 0px;">
<div class="v-select-twincol" style="width: 60em; position: relative;">

Now, while closed, I change the edit mode to read-only mode (note that the direction of the mode switch makes no difference), and it look this still, which seems reasonable since it’s still closed, but note that the second div for the verticallayout now has dropped the height from 503px to just 28px:

<div class="v-drawer-content" style="height: 0px; width: 855px; display: none;">
<div style="overflow: hidden; width: 855px; height: 28px;" class="v-verticallayout">
<div style="margin: 0px; overflow: hidden; width: 855px; height: 28px;">
<div style="overflow: hidden; height: 0px; width: 855px; padding-left: 0px; padding-top: 0px;">
<div class="v-caption" style="width: 855px; margin-left: 0px;">
<div class="v-captiontext">LIST PERMISSION</div>
<div style="overflow: hidden; clear: both; width: 0pt; height: 0pt;"></div></div>
<div style="float: left; margin-left: 0px;">
<div class="v-select-twincol" style="width: 60em; position: relative;">

So now when I re-open the drawer, the contents are not really shown (but you can tell it’s opened some) and it shows that oddly small height of only 28 with ‘display:none’ removed:

<div class="v-drawer-content" style="height: 28px; width: 855px;">
<div style="overflow: hidden; width: 855px; height: 28px;" class="v-verticallayout">
<div style="margin: 0px; overflow: hidden; width: 855px; height: 28px;">
<div style="overflow: hidden; height: 0px; width: 855px; padding-left: 0px; padding-top: 0px;">
<div class="v-caption" style="width: 855px; margin-left: 0px;">
<div class="v-captiontext">LIST PERMISSION</div>
<div style="overflow: hidden; clear: both; width: 0pt; height: 0pt;"></div></div>
<div style="float: left; margin-left: 0px;">
<div class="v-select-twincol" style="width: 60em; position: relative;">

So perhaps this is a bug in the vertical layout somehow? I am running 6.3 nightly and I just updated to 20100223 version and of course it still happens.

Last night Artur helped me out and identified the culprit, which I’m greatly thankful for. Good news: It is a bug-of-sorts in the Drawer, so it should be fixable. Bad news: I have to fix it now :slight_smile:

The problem is that, as you noticed, I made the drawer contents invisible by setting “display: none”. Well, actually GWT did that for me, but anyways. This is a no-no, apparently. It has something to do with Vaadin’s client-side dimension calculation assuming correct location in the DOM, and “display: none” breaks that assumption.

I already got a somewhat working version by explicitly using “visibility: hidden” instead, but, for some weird reason, this breaks some other magic features in the Drawer. I’ll be spending this day fixing the Drawer, and hopefully have a patched-up version before I go home today.

That was suspiciously quickly fixed.

1.1.4 is now out with the bug apparently fixed. Updated Jar found at
http://dev.vaadin.com/browser/contrib/Drawer
.

Thank you David for your excellent debugging help; hope this fixes your issues.