Re: forms-lite and data models

Hi John,

Most of my comments on this subject were on a thread on the internal
XForms WG list, so I hope you don't mind if I paste them in here!
(Saves on typing...)

> Notwithstanding Forms Tiny, the need for dot-dot in calculates and such is a pain
> already for XForms, and Forms Tiny doesn't fix that.  So, to me, mipcontext a good
> thing, not a last resort.

We sort of agree--in my internal post, I said:

  (Now, I've never liked the way evaluation context works in XForms, but
  my feeling is that we're way too far down the line to do anything
  about that--but whilst I wouldn't argue for any changes to evaluation
  context, I would strongly argue that it should be consistent across
  all uses of the mark-up.)

So I'm with you that the way that XForms currently does it "is a
pain", but it's a minor thing, and once people have it down, it's not
so bad. I'm suggesting that we don't introduce additional mechanisms.


> However, I believe we found a problem with the flat space bind idea at the last face to
> face, so I thought we already chose not to go in that direction.  I believe the problem was
> that it broke down when you tried to do calculate, though it is nice up to that point.

I don't think it did break down. The only objection to my proposal was
that Erik though it may affect some future proposal for XPath
variables--I explained in another thread why I think that we can and
should solve that today. Also, I don't think I explained my proposal
very well, so I'll do that here. (But being lazy, I'm just going to
paste from the same post on the internal list--the one I mentioned
earlier):

--- STARTS ---
  Anyway, on to my suggestion. The first step is to say that @name is
  equivalent to @bind, which is pretty easy:

   <input type="text" name="item-count" />
   <input type="text" name="item-price" />

  We'd need to say that our lazy authoring extends to bind statements,
  and perhaps some other stuff, but in short, we're saying that the
  above HForms is equivalent to:

   <xf:instance>
     <instanceData xmlns="">
       <item-count />
       <item-price />
     </instanceData>
   </xf:instance>

   <xf:bind id="item-count" nodeset="item-count" />
   <xf:bind id="item-price" nodeset="item-price" />

   <xf:input bind="item-count">
     <xf:label />
   </xf:input>
   <xf:input bind="item-price">
     <xf:label />
   </xf:input>

  The second step is then to allow the use of these 'named nodesets' via
  XPath variables:

   <output value="$item-count * $item-price" />

  My feeling is that this is actually quite readable to HTML authors,
  and does not require any knowledge of XPath or XPath variables--we're
  merely saying that if you want to use the underlying value of a node
  you prefix it with '$'. Note that this is quite a lot simpler than
  using "../" as well as being easier than the Web Forms 2.0 approach
  [1]:

   <output name="result" onforminput="value = a.value * b.value">0</output>

  which is procedural, and will not cope with this:

   <input type="radio" name="gender" value="male">Male</input>
   <input type="radio" name="gender" value="female">Female</input>

   <output onforminput="value = 'You are ' + gender.value />

  (A function is required to get the current value of 'gender'.)

  An MVC (and declarative) solution copes with it easily:

   <output value="concat('You are ', $gender)" />

  One of the other reasons I thought that the bind/variables approach
  was worth considering is that if you move forward and look at things
  like readonly, required and relevance, it seems that we have to be
  careful about blurring the model and view 'layers'. If we simply say
  that this:

   <input type="text" name="item-count" required="true" />

  is equivalent to:

   <xf:instance>
     <instanceData xmlns="">
       <item-count />
     </instanceData>
   </xf:instance>

   <xf:bind id="item-count" nodeset="item-count" required="true()" />

   <xf:input bind="item-count">
     <xf:label />
   </xf:input>

  then we have said that it's the data in the model that is required,
  not this particular control. That's not a bad way to approach it, but
  I think it might give us problems in the future, and it seems to me
  that although we all like the MVC approach, we should be aware that
  this architecture does not preclude the view itself from having more
  functionality.

  So, I think it would be better to bring in bind when expressing
  explicitly model-layer rules:

   <form ...>
     <bind id="item-count" required="true()" />

     <input type="text" name="item-count" />
     .
     .
     .
     <input type="text" name="item-count" />
   </form>

  Now it's clear that it's the data in the model that is required. I'd
  see that as different to something like a formatting pattern, that
  might be expressed something like this:

   <form ...>
     <bind id="price" required="true()" />

     <input type="text" name="price" pattern="#,###.##" />
   </form>

  This is clearly a job for the 'view' and the model doesn't need to
  know anything about this.
--- ENDS ---

In my view this is *extremely* advantageous; by using the 'flat space'
provided by named bind statements (or XPath variables), a large number
of XPath statements become very easy to express in a way that 'looks'
much like JavaScript. This is significant because it means that
authors are getting the benefits of MVC immediately--the data they are
manipulating is in the model, not the view, hence the difference
between my proposal:

   <output value="concat('You are ', $gender)" />

and that of proposals that use script and eval(), and therefore need
to inspect many controls to work out the 'value' of some data:

   <output onforminput="value = 'You are ' + goGetTheValue('gender')" />


Anyway, returning to *this* email, you asked:

> To be concrete, how would the bind idea work if you have, say,
>
> <input name="A" ...
> <input name="B" ...
> <input name="C"  calculate="power(A*A+B*B, 0.5)" ...
>
> This simple case seems to break because the calculate contains an XPath, so things
> like "A" and "B" match nodes, not the nodesets of binds with the matching IDs.
>
> Is it true that your bind idea would produce this result?
>
> <bind id="A" nodeset="whoKnowsA" />
> <bind id="B" nodeset="whoKnowsB" />
> <bind id="C" nodeset="whoKnowsC" calculate="power(A*A+B*B, 0.5)"/>
>
> If so, the clearly the calculate doesn't work.

That's true--it doesn't work because of the evaluation context. But
the proposal would be:

  <input name="C"  calculate="power($A * $A + $B * $B, 0.5)" ...

(Note that I'm using <output value="..." ... /> in my examples,
because to me that is the most common use-case--the desire to put
display data that is derived form other data. Of course there will be
situations where you want to *submit* a calculated value, so <input
calculate="..." /> has its place, but that places additional data into
the model, whilst <output value="..." ... /> just sets up some data in
the view.)

Other reasons that I think this proposal is worth serious
consideration, is that it does not change the use of @name in HTML. I
think that's important, since we're trying to provide an
'interpretation' of HForms, seen through the prism of an XForms
processor--we're not trying to redefine HTML. By using @name to
represent a hook that gives access to a 'named bind statement', we
leave open the possibility of the author who has learned more XForms
using XPath via the @ref attribute:

  <input ref="/a/b/c" ...

Regards,

Mark

-- 
Mark Birbeck
CEO
x-port.net Ltd.

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

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

Received on Thursday, 26 October 2006 11:42:19 UTC