RE: multimodal labels and trees too far away for XForms? [was: Re: Deploying (accessible) XForms today?]

Mark,

> Handling trees has been discussed at several meetings and the 
> discussion has not reached any conclusion as yet.
> 
> Mikko Honkala has implemented a tree control in X-Smiles, 
> which I for one have found extremely useful. I believe some 
> other XForms implementers have the tree control too.

formsPlayer doesn't have a generic tree control that drills down into an XML
tree, but we do have a tree widget that is rendered when
@appearance="compact" on a xf:select and xf:select1. Levels of the tree are
set by xf:choices.


> Whilst the form control is useful there are some on the WG 
> who would prefer a more generally applicable approach to 
> handling arbitrary depth in XML documents, along the lines of 
> giving repeat another axis.

Since that's me you're referring to :) I've attached below the comments I
made back in January. They should be read in conjunction with the proposal
that Mikko just posted. The main point I'm making is that pretty much all of
the functionality that is being proposed with xf:tree can be achieved by
adding a @recurse attribute.

That said, I also raised some issues with the xf:tree control as is--the
inconsistent use of @ref, the nodeindex() function returning a node, whilst
index() returns an integer, and so on--so it's not just an either/or, and if
we move towards xf:tree we should still try to make it more consistent.


> Personally I would like a general mechanism for handling 
> depth that is not tied to a particular form control (like 
> repeat), along with the convenience of the tree control, 
> which is clearly a generally useful way of representing and 
> interacting with depth.

My proposal is actually about having an attribute that works with @nodeset
and anything that uses templates. At the moment templates are used in
xf:repeat and xf:itemset, but can also be used with anything that supports
the repeat attributes. Are you thinking of other controls not covered by
this category that could make use of 'depth'.


> I personally have a very pressing need for some handling of 
> depth in XML documents, so would be very happy to see it move 
> up the agenda again.

Yes.

Here's my original post:

--- BEGINS ---

From: Mark Birbeck <mark.birbeck@x-port.net>
Date: Thu, 26 Jan 2006 12:10:10 -0000
Message-ID: <B4415802-E49F-4230-A611-9BC25ADDA5AE@s15.mail.x-port.net>
To: <w3c-forms@w3c.org>

Hi all,

I'm afraid I still disagree with the use of a tree widget, and find it
inconsistent with much of XForms.

First, the use of @ref is inconsistent with other uses in the rest of
XForms. When used in form controls, the control becomes *bound* to the node,
and some value is placed into the node as a result of some action in the
control.

Second, nodeindex() returns an actual node, rather than an index, which is
inconsistent with index(). (Nothing wrong with the function, but I'd like to
see its name changed.)

Third, we don't have a notion of filtering anywhere. I'm not completely
against it, but if we were to add this, it should be an attribute across the
board. However, the only reason you need to filter, is because you have the
notion of "a root node and all its children"--as I've shown below, I think
we should really be dealing with "a nodeset processed hierarchically", then
we can filter in one expression, as we already do.

Fourth, the idea of 'expanding' and 'collapsing' nodes is too specific, I
feel. It implies functionality at a level of detail that we do not do
elsewhere in XForms.

I also think it is asking for trouble to introduce something so 'large',
since we then have to go through and sort out all of the possible problem
areas--does the index change after xf:insert, for example? I think we can
get the required functionality, but by building on existing features.


RECURSIVE
If you put aside the functionality of the control (that we should *not* be
defining), and the use of an index to find a node (which we can define in
other ways) the unique feature of xf:tree is that nodes should be processed
recursively, and not in a flat list. My view is that this is the key feature
that should be brought out and made explicit, and I'd like to propose a way
to do this.

First, we need to allow @nodeset to return non-homogeneous collections. (I
believe we may have already done this.)

Second, we add an attribute to xf:repeat (and to xf:itemset) to indicate
whether we want to make the repeat hierarchical:

  <xf:repeat nodeset="*" recurse="true">
    <template />
  </xf:repeat>

(Ideally this is 'true()' rather than 'true', but that is a detail.)

Third...we're done!


PROCESSING
Processing of this attribute would be as follows. When the repeat is used
'flat' (i.e., the current behaviour) we get the following when 'unrolling'
this xf:repeat (using Nick's data, and pretending that we have a xf:group
wrapping everything to get us to the top of the instance data):

  <xf:group ref="/folder">
    <template />
  </xf:group>

When it is used recursively we get something like this:

  <xf:group ref="/folder">
    <template />

    <xf:repeat nodeset="*" recurse="true">
      <template />
    </xf:repeat>
  </xf:group>

The details may need working on, but the key point is that it is exactly the
same as for a 'normal' repeat, except that the xf:repeat *itself* has been
added after an instance of the repeat template. (Actually, we really need be
able to put it *inside* the <template />, and have some control over
*where*, but that is something we can come back to.)

To continue, this would be further unrolled to this:

  <xf:group ref="/folder">
    <template />

    <xf:group ref="folder">
      <template />

      <xf:repeat nodeset="*" recurse="true">
        <template />
      </xf:repeat>
    </xf:group>
  </xf:group>

Which further unrolls to this (!):

  <xf:group ref="/folder">
    <template />

    <xf:group ref="folder">
      <template />

      <xf:group ref="folder">
        <xf:repeat nodeset="*" recurse="true">
          <template />
        </xf:repeat>
      </xf:group>

      <xf:group ref="file[1]">
        <template />
      </xf:group>

      <xf:group ref="file[2]">
        <template />
      </xf:group>

      <xf:repeat nodeset="*" recurse="true">
        <template />
      </xf:repeat>
    </xf:group>
  </xf:group>

And if you haven't gone bonkers yet...it finally unrolls to this:

  <xf:group ref="/folder">
    <template />

    <xf:group ref="folder">
      <template />

      <xf:group ref="folder">
        <xf:group ref="folder">
          <template />
        </xf:group>

        <xf:group ref="file[1]">
          <template />
        </xf:group>
      </xf:group>

      <xf:group ref="file[1]">
        <template />
      </xf:group>

      <xf:group ref="file[2]">
        <template />
      </xf:group>
    </xf:group>
  </xf:group>

This is exactly the hierarchy that you want from xf:tree.

So, to recap, the key point is that we want some way to obtain recursive
processing of xf:repeats (and the same technique should work for xf:itemset,
too), and I think that is best achieved with an additional attribute.

In passing, I don't see a reason for using the attribute in other places
that @nodeset is used, but there may be some. We can already make all folder
elements readonly, for example:

  <xf:bind nodeset="//folder" readonly="true()" />


INDEX()
Since we are now dealing with xf:repeat and indexes, rather than a node, as
in xf:tree, then we would need to add a new function to indicate the depth
we're at, and possibly an optional second parameter to index() to find the
current index at a particular depth.


FLEXIBILITY
Note by the way that this is far more flexible than xf:tree, since anything
can be placed in the template of the xf:repeat--images, labels, full
controls, nested forms, etc. It also gives you more control over the items.
For example, to process folder elements differently to file elements, all we
have to do is this:

  <xf:repeat nodeset="folder" recurse="true">
    <xf:repeat nodeset="file">
      <img src="file.gif" />
      <xf:output ref="@name">
        <xf:hint ref="../@description" />
      </xf:output>
    </xf:repeat>

    <img src="folder.gif" />
    <xf:output ref="@name" />
  </xf:repeat>

Which expands to this:

  <xf:group ref="folder">
    <!-- template -->
    <xf:repeat nodeset="file">
      <img src="file.gif" />
      <xf:output ref="@name">
        <xf:hint ref="../@description" />
      </xf:output>
    </xf:repeat>
    <img src="folder.gif" />
    <xf:output ref="@name" />

    <!-- now add the repeat again -->
    <xf:repeat nodeset="folder" recurse="true">
      <xf:repeat nodeset="file">
        <img src="file.gif" />
        <xf:output ref="@name">
          <xf:hint ref="../@description" />
        </xf:output>
      </xf:repeat>

      <img src="folder.gif" />
      <xf:output ref="@name" />
    </xf:repeat>
  </xf:group>

There are other things that need to be added to this (to cope with expanding
and collapsing, for example, you'd put xf:switch and xf:case at each level,
but would therefore need to be able to position the nested xf:repeat within
<template />), but I think we can easily add those later. My main point for
now is that I don't think we should be doing xf:tree, especially when we can
provide the same functionality by extending current features (which is
always going to be easier to document).

Regards,

Mark


Mark Birbeck
CEO
x-port.net Ltd.

e: Mark.Birbeck@x-port.net
t: +44 (0) 20 7689 9232
b: http://internet-apps.blogspot.com/
w: http://www.formsPlayer.com/

Download our XForms processor from
http://www.formsPlayer.com/

--- ENDS ---

Received on Tuesday, 9 May 2006 10:09:20 UTC