
'xlistbox' is a multiple listbox (or extended listbox, or hierarchical
list) webclass. It consists of several listboxes that depend on each-other
hierarchically, so that when the selection changes in one of them, the
content of the list that depends on it is refreshed to reflect the change.
It is used like this:

      <WebObject Class="xlistbox" Name="office"
              mainlist="true"
              sublist="department" 
              onchange="alert(this.options[this.slectedIndex].text)" />

      <WebObject Class="xlistbox" Name="department"
              sublist="users"
              onchange="alert(this.options[this.slectedIndex].text)" />

      <WebObject Class="xlistbox" Name="user"
              onchange="alert(this.options[this.slectedIndex].text)" />

The 'mainlist' attribute, when it is true, tells that this is the first
list in the group and it is not dependent of any other list. Its default
value is 'false'.

The 'sublist' attribute tells which is the list that depends on this one,
i.e. the list that is refreshed when the selection of this list is changed.
The last list of the group has no 'sublist' attribute.

The 'onchange' attribute contains the JS code that should be executed when
the content of the list changes. It is optional (can be ommitted).

Each xlistbox is connected with a recordset whith ID "xlistbox::obj_name".
The fields of these recordsets are (id, label) for the main xlistbox of
the group, and (master_id, id, label) for the other lists of the group.
E.g.:
    <Recordset ID="xlistbox::office">
      <Query>
        SELECT off_id AS id, name AS label  
        FROM offices
      </Query>
    </Recordset>

    <Recordset ID="xlistbox::department">
      <Query>
        SELECT off_id AS master_id, dept_id AS id, name AS label 
        FROM departments
      </Query>
    </Recordset>

    <Recordset ID="xlistbox::user">
      <Query>
        SELECT department AS master_id, user_id AS id, username AS label 
        FROM users
      </Query>
    </Recordset>

'master_id' must be the same as the 'id' of the list above. When the
selection of the list above is changed, then the list is refilled with
all the items of the recordset that have master_id equal to the selected
id of the list above.

There can be any number of lists in a group. It is limited only by 
performance reasons, e.g. if there are 4 or 5 lists in a group, then
the size of the data that is retrived from DB and immbeded in JS code
may be too big and it may increase the size of the page.

When there is only the main list, it behaves just like a 'listbox', and in
this case it would be better to use a 'listbox' object instead of a
'xlistbox' object, since it is more efficient.

If you want to init the lists with some values, you can add this JS code
after the </form> is closed:
    <script type="text/javascript" language="javascript">
    //<![CDATA[
      var form = document.userdata;
      xlistbox_select(form.office, '{{office}}');
      fill_sublist(form.department, '{{office}}', '{{department}}');
      fill_sublist(form.user, '{{department}}', '{{user}}');
    //]]>
    </script>
The mainlist usually doesn't need to be initialized, because it is
initialized itself, but if it doesn't then it can be initialized
using:  xlistbox_select(mainlist, id). The sublists can be initialized
using:  fill_sublist(sublist, master_id, id).

Note: saveFormData() (of a 'formWebObj' webbox) doesn't work very well
      with 'xlistbox' webobjects. Usually it collects all the data of
      the form, transmits them and then redistributes them in the form,
      so that they are not lost, even though they are not saved in DB.
      For 'xlistbox' webobjects it can save and redisplay only the value
      of the mainlist.
