Forum OpenACS Development: new html form API

Collapse
Posted by Torben Brosten on
Hi,

I'm slow, easily distracted, and have a limited memory which makes me a poor excuse for a computer software engineer. Coincidentally it makes me a perfect candidate for creating an API for generating HTML forms in TCL that's useable by most anyone with a few minutes of TCL programming background..

Announcing a new html form API called qf_* for quick forms

The learning curve for this new way is low, because it depends on knowing html forms and basic tcl, not much else.

It's much easier to build web-based, single page applications using this.

The design criteria used to build it:

1. use simple tcl proc API based on form HTML
2. take less keystrokes to build a form than typing the form manually.
3. not have any design limitations to building dynamic forms for specialized inputs.
4. secure (automatically quotes user input, isolates form input to an array etc)
5. provide a means to easily enhance user experience via improved form feedback
6. integrate with acs templating features

It's in the spreadsheet package on CVS Head: spreadsheet/tcl/form-procs.tcl

An example contact form is at: spreadsheet/www/example-form.*

This is an early, beta release.

Your constructive feedback is welcome!

cheers,

Torben

Collapse
2: Re: new html form API (response to 1)
Posted by Dave Bauer on
Hi,

How does #5 work? What sort of imporved form feedback is available compared to the form validation in the form builder?

Thanks!

Collapse
3: Re: new html form API (response to 2)
Posted by Torben Brosten on
Hi Dave,

The form validation can be easily customized into scenarios as complex as needed using tcl within a consistent namespace and no specialized framework constraints (such as a meta language).

Collapse
4: Re: new html form API (response to 1)
Posted by Dave Bauer on
Hi,

Would you mind posting an example form's Tcl script? Thanks.

Collapse
5: Re: new html form API (response to 4)
Posted by Torben Brosten on

Sure, Dave, here's the one in CVS head:

http://fisheye.openacs.org/browse/OpenACS/openacs-4/packages/spreadsheet/www/example-form.tcl

The qf_* code is a small part of it:

# build form

qf_form action example-form id i99

qf_input type text value $input_array(full_name) name full_name label $title_array(full_name) id i967 size 40 maxlength 50

qf_append html "<br>"

qf_input type text value $input_array(email_address) name email_address label $title_array(email_address) id i968 size 40 maxlength 80

qf_append html "<br>"

qf_input type text value $input_array(subject) name subject label $title_array(subject) id i969 size 40 maxlength 80

qf_append html "<br>"

qf_textarea name message rows 30 cols 40 label $title_array(message) value $input_array(message)

qf_append html "<br>"

qf_append html "\ "

qf_append html "<a href=\"example-form\">Clear form</a>"

qf_append html "\ "

qf_input type hidden name validated value $validated

qf_close

set form_html \[qf_read \]

form_html is then passed to the adp template.

Collapse
6: Re: new html form API (response to 4)
Posted by Torben Brosten on

re-formating post for clarity (and an omission).


Sure, Dave, here's the one in CVS head:

http://fisheye.openacs.org/browse/OpenACS/openacs-4/packages/spreadsheet/www/example-form.tcl

The qf_* code is a small part of it:

# build form

qf_form action example-form id i99

qf_input type text value $input_array(full_name) name full_name label $title_array(full_name) id i967 size 40 maxlength 50

qf_append html "<br>"

qf_input type text value $input_array(email_address) name email_address label $title_array(email_address) id i968 size 40 maxlength 80

qf_append html "<br>"

qf_input type text value $input_array(subject) name subject label $title_array(subject) id i969 size 40 maxlength 80

qf_append html "<br>"

qf_textarea name message rows 30 cols 40 label $title_array(message) value $input_array(message)

qf_append html "<br>"

 qf_input type submit value $title_array(submit)

   qf_append html "&nbsp;"

   qf_input type reset value $title_array(reset)
   
qf_append html "&nbsp;"

qf_append html "<a href=\"example-form\">Clear form</a>"

qf_append html "&nbsp;"

qf_input type hidden name validated value $validated

qf_close

set form_html \[qf_read \]

form_html is then passed to the adp template.

Collapse
7: Re: new html form API (response to 4)
Posted by Torben Brosten on
The only weakness I find in it at this point is qf_* builds using html4 DTD without an option for strict XML. I'll add a parameter, with an option in the form tag to override locally.

Any other feature requests?

Collapse
8: Re: new html form API (response to 1)
Posted by Brian Fenton on
Congrats Torben,

it certainly looks easy to use for newbies. I think new features to OpenACS are always welcome.

best wishes
Brian

Collapse
9: Re: new html form API (response to 1)
Posted by Emmanuelle Raffenne on
Hi Torben,

I'm probably missing something but what are the benefits of building the form using the qf Tcl API rather than building it directly in HTML? Does the qf library provide customizable templates to render the form?

Collapse
10: Re: new html form API (response to 9)
Posted by Torben Brosten on
Hi Emmanuelle,

Yes, there are some conveniences using qf to build the form as well as the convenience of having form input contained in an array.

Attributes can be repeated automatically (except id, value, and name) invoking the proc qf_remember_attributes.

The procs qf_choice and qf_choices can be used to switch between input modes. qf_choices can switch between checkboxes and multiple select options by just changing the type. qf_choice can switch between radio buttons and select option by changing the type.

The label tag is automatically wrapped around an input tag that is supplied an id and label.

Multiple forms can be built at the same time. Each form is given a form_id when qf_form is invoked. The most recent form_id is used by default, so no need to use this level of complexity with one form.

values are automatically quoted to prevent breaking html interpretation. Unquote with ad_unquote

qf errors silently on the page (reporting error to log) for example if qf_form is not invoked first.

qf_close automatically adds form and fieldset close tags to all open forms.

attributes are checked against a list of allowed attributes specific to each tag. Currently, javascript attributes are not allowed. Since javascript has access to the page DOM, it seems cleaner for that code to reference via id/name from within the code block. To override, add the tag manually with qf_append.

These procs can help to generate clean html in other procs by separating the collection of data from the tag build. For example, when using qf_choices to help build an html widget, basically one sets up a query to build a list of lists, and then passes it to qf_choices. This has been an issue for me with ecommerce, where manually building the html in the middle of qf_form has resulted in some unexpected tag rendering due to code logic errors. Complete form widgets can be built as well. This may be a handy tool in dotLRN for helping build dynamic testing/survey apps without having to depend on someone with ad_form proficiency.

Regarding customizable templates

Since qf uses tag ids, CSS and Javascript are handled separately, helping to keep any templating and UI clean. qf doesn't supply a customizable template, other than the example-form.tcl mentioned previously. qf uses existing OpenACS templating in that it works for package/lib adp/tcl pairs. Each form is a function of it's page, so it's expected that forms are fairly unique in their build. Any templating would be building a page as a copy of another, just as is done with other adp/tcl pairs.

cheers,

Torben

Collapse
11: Re: new html form API (response to 1)
Posted by Torben Brosten on
Here's an example of qf_form in an app that builds the form on the fly, based on a set of parameters from the product, product variants, and some internal style parameters: http://birdswelcome.com/configurator?model=abf

I really appreciate how qf_* simplifies the coding of the form instead of requiring me to understand the abstractions of ad_form by tweaking a presentation to fit ad_form's limitations or implementation idiosyncrasies. Clearly there's a place for ad_form in general UI consistency, but when an app doesn't fit the ad_form paradigm, it's nice to have the flexible alternative of qf_*.

Collapse
12: Re: new html form API (response to 1)
Posted by Jim Lynch on
Hi Torbin,

Do the qf_* calls make use of the existing form builder, or is it completely independent?

-Jim

Collapse
13: Re: new html form API (response to 1)
Posted by Torben Brosten on
Hi Jim,

It's completely independent.

cheers,

Collapse
14: Re: new html form API (response to 1)
Posted by Torben Brosten on
That stated, one can incorporate existing validation code into form processing, or build more elaborate ones.

Take a look at the source tcl in the example above for a list of validation code currently available in OpenACS (let me know if I've missed any).

cheers,

Collapse
15: Re: new html form API (response to 1)
Posted by Jim Lynch on
Thanks Torbin...

Is it possible to build the same api as you're specifying so that instead of being independent, it uses and completely depends on the existing form builder code?

I'd be interested to use code I've written to extend the existing form builder without altering that code.

-Jim

Collapse
16: Re: new html form API (response to 1)
Posted by Torben Brosten on
Hi Jim,

It would probably be easier to add the functionality directly to form builder --if it is possible. I know others have made attempts at adding features, but I don't think the complete form spec is available yet.

Quiet frankly, I've never been able to implement dynamic form builder apps.. it's too many layers of abstraction for my pea-sized brain with its limited attention span.

The qf_ api allows me to convert simple html into a dynamic tcl framework, which provides as much complexity as is needed without the extra abstractions, and without being limited by the form builder api.

cheers,