Richlistbox Tricks for your Add-on

I've been messing around with richlistboxes a bit and I learned a couple of things, so I thought I would share.

The first thing I learned is that richlistboxes don't participate in layout the same way as a listbox, particularly in a (edit: tabbed panel in a dialog) dialog. If you dynamically add items to them, they will push other items off the dialog. (edit: Rows attribute should have never been in the richlistbox docs - I removed it)There's a "rows" attribute on the richlistbox that would seem to be for this, but it doesn't work. Most people probably just end up setting max-height or explicit height and width, but I don't like that. Here's what I came up with.

If you are going to dynamically add items to the listbox, set it to flex and then query the width and height during window load and explicitly set the width and height to be those values:

  var listbox = document.getElementById("myrichlistbox");
  var listboxStyle = window.getComputedStyle(listbox, null);
  var width = parseInt(listboxStyle.getPropertyValue("width"));
  var height = parseInt(listboxStyle.getPropertyValue("height"));
  listbox.setAttribute("width", width);
  listbox.setAttribute("height", height);

If you are adding items in the XUL using a template or being explicit, hide the richlistbox and put a vbox in its place. Then during load, query the size of the vbox, set those sizes to the rich listbox and hide the vbox/show the richlistbox.

The second thing I learned is that headers don't work properly in richlistboxes. Like me, you probably placed headers at the top of your richlistbox the same way you would for a listbox thinking, "It's a listbox, so listbox headers should work."But you might have noticed that when you scroll your richlistbox, the headers scroll away. Working around this was a little trickier. Come to find out, richlistboxes don't support headers properly. To fix it, I found the one place in Firefox that uses a richlistbox and has a header - the Applications tab in preferences. Here's the code:

<richlistbox>
  <listheader style="border: 0; padding: 0; -moz-appearance: none;">
    <treecol value="First Header"/>
    <treecol value="Second Header"/>
  </listheader>
</richlistbox>

The style stuff looks ugly, but it's to make it appear properly on Linux.

I hope these tips will save my fellow add-on developers some work.

8 Responses to “Richlistbox Tricks for your Add-on”

  1. Dave Townsend August 5, 2011 at 12:23 pm #

    Strange, just setting flex on the listbox makes it fit the size of the window just fine for me

  2. Mike Kaply August 5, 2011 at 4:15 pm #

    It's more complicated than I thought. I attached a better testcase to the bug.

    It has to do with richlistboxes in tabpanels.

  3. Jeff Walden August 5, 2011 at 10:13 pm #

    You should use an explicit radix when calling parseInt -- less guesswork (of a sort) for the engine, and clearer to the reader.

  4. Neil Rashbrook August 6, 2011 at 5:31 am #

    Why not use .boxObject.width/height instead?

    SeaMonkey worked around the richlistbox header issue by using a real listbox for its application preferences.

    • Mike Kaply August 6, 2011 at 9:55 am #

      > Why not use .boxObject.width/height instead?

      Because I didn't think about that. I'm sure there are 10 different ways to get width and height on a an object. :)

  5. Tom January 16, 2013 at 3:01 am #

    This works like a charm, except that it returns this error:

    Error: TypeError: tree.columns is undefined
    Source File: chrome://global/content/bindings/tree.xml
    Line: 1367

    • Tom January 16, 2013 at 3:50 am #

      I forgot to add that in order to generate this error, you need to click on the column header. It seems assumes it will be inside a complete XUL tree structure in order to render the little control that allows you to toggle individual columns on and off.

    • Mike Kaply May 15, 2013 at 1:10 pm #

      Thanks for the comment.

      This happens with the Firefox implementation that I copied as well:

      https://bugzilla.mozilla.org/show_bug.cgi?id=502367

      I tried to handle the onclick, but it doesn't fix it. I'll look at fixing in Firefox.

Leave a Reply:

Gravatar Image