[whatwg] Incremental rendering of forms

On Thu, 26 Aug 2004, [ISO-8859-1] Olav Junker Kj?r wrote:
> > 
> > Similar things for, e.g., looking up product part numbers while 
> > filling up a bigger form.
> 
> This is a nice use case, and something that WF2 should indeed try to 
> make possible in a natural way.
> 
> If I understand correctly, you are thinking of something like this:
> 
> Enter address:  [_________]
> Enter postcode: [____] [Lookup]
> [Send]
> 
> When you click "lookup", the address is sent to a postcode-lookup-server 
> which finds one or more possible postcodes, which (without a page 
> reload) is filled into (or presented as a datalist for) the postcode 
> field. When you click "send", address and postcode are submitted to a 
> server, which is different than the postcode-lookup-server.

Yes. The main (one-form) way to implement this in WF2 is:

   <form action="post.cgi" method="post">
    <label> Enter address: <input name="address"> </label>
    <label> Enter postcode: <input name="postcode">
     <input type="submit" name="lookup" value="Lookup"
            action="lookup.cgi" replace="values">
    </label>
    <input type="submit" value="Send">
   </form>

...where post.cgi checks to see if "lookup" is in the list of variables, 
and if it is, does a lookup then returns the form as a new page (that's 
the fallback behaviour), and lookup.cgi does a lookup and returns a 
<formdata> page that updates the form on the fly.


> There is several issues here. First is obviously makes sense to think of 
> this as two different forms, since they submit different data to 
> different servers and the results is handled differently.

It can indeed also be implemented as two forms, using the onreceived 
event handler instead of using replace="values" (this requires 
JavaScript, and would typically only be used for much more complex cases 
where the data isn't being placed directly into a form):

   <form action="lookup.cgi" method="get" id="lookup"></form>
   <form action="post.cgi" method="post" id="post">
    <label> Enter address: <input name="address"> </label>
    <label> Enter postcode:
       <input name="postcode">
       <input type="hidden" name="lpostcode" form="lookup">
       <input type="submit" name="lookup" form="lookup" value="Lookup"
              onsubmit="lpostcode.value = document.forms.post.postcode.value">
              onreceived="document.forms.post.address.value =
                 event.receivedDocument.documentElement.firstChild.data">
    </label>
    <input type="submit" value="Send">
   </form>

...where post.cgi does the same trick for backwards compatibility 
(checking for the presence of "lookup" and sending back a whole new form 
if it is there, with the fields filled in); but lookup.cgi just returns a 
single XML document with one element containing as its contents the 
address as a text string.


> A complication is that the address field is really part of both forms. 

Yeah; in the two-form case above, I handle this by copying the value over 
when the second form is submitted.


> If we want the postcode returned from the lookup-server to fill into the 
> postcode field, this could be done by replace=data, but (if I understand 
> the spec correctly) only if the postcode field is part of the *same* 
> form.

Yes (that's the first example above).


> OTOH it will not work either if we have just a single form and 
> different action-URI's on the buttons, since the validation constraints 
> are different - postcode is required for one server and not the other.

That's a very good point.

XForms handles this case by disabling the requirements before submission:

   http://xformsinstitute.com/essentials/browse/ch10s03.php#ch10-14-fm2xml

...(and doesn't even provide built-in support for it).


One option would be to make the "form" attribute into a space-separated 
list, and say that elements belong to all the forms that are given in the 
list. This would require some pretty big changes to the DOM, but it would 
work pretty well I think.

Another option would be to provide a declarative way of saying "this 
hidden input control's value should just be taken from that control over 
there when you submit", which is easier to define but feels like more of a 
kludge and is a bit harder to use. However, it does allow us to do things 
like this, maybe:

   <label>x = <input type="number" id="theta"></label>
   <form action="sin.php">
    <input type="hidden" control="theta"
           min="-180" max="180" required="required">
    <input type="submit" value="sin(x)">
   </form>
   <form action="cos.php">
    <input type="hidden" control="theta"
           min="0" max="360" required="required">
    <input type="submit" value="cos(x)">
   </form>

...which could be interesting. Basically, when you validate a 
type="hidden" control, you take the control that its control="" attribute 
points to, and use its type and value with the constraints defined on the 
type="hidden" control to find the validity of the hidden control, and if 
you need to complain to the user, you do so using the original (not 
hidden) control. There are problems, though, like what happens if the two 
controls have mutually exclusive constraints, and how do you derive the UI 
since there might be multiple conflicting constraints (as in the example 
above, in fact).


I'm preferring the "multiple form" idea here, but really a better idea 
all round would be best.


> Anyway, it's not because I'm opposed to the form-attribute in principle, 
> it's just that I have a strange feeling that the requests for this 
> feature is hiding some other not fully understood requirement.

That's possible.

-- 
Ian Hickson               U+1047E                )\._.,--....,'``.    fL
http://ln.hixie.ch/       U+263A                /,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'

Received on Sunday, 29 August 2004 12:25:20 UTC