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.

Please note: I reserve the right to delete comments that are offensive or off-topic.

Leave a Reply

Your email address will not be published. Required fields are marked *

10 thoughts on “Richlistbox Tricks for your Add-on

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

    It has to do with richlistboxes in tabpanels.

    • > 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. 🙂

  2. 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