Forum OpenACS Development: Forms/Metadata Part Two
Below is a table with the arguments for form elements and possible data to populate them.
Element Current Data Proposed Data widget datatypes.widget datatype acs_attributes.datatype html attributes.html options ??? value acs_attribute.default_value values acs_attribute.default_values (multi value) validate datatypes.validate (multi value) optional acs_attributes.min_n_values/max_n_valuesShould validate/widget be part of the datatype or attribute?
I'm for making datatypes acs_objects. This does a couple of things. First it allows access control which might be needed for some kinds of RAD tools. It also adds a parent/child relation to the datatypes. This is usefull in a number of ways. Create a few types such as number, string and long_string. If I want to collect animals I can create a datatype called animals with a parent of string. I don't really need a new widget or validate routines. If I like dogs I create a new type dogs and make its parent animals. I still don't need new validate routines. Now if I only want pure breed dogs I can create datatype called purebreed with a parent of dogs. Next I create a table of valid types and validate against that. The widget can also change to a select list. If the user has write access to the datatype they could add a new breed. Finally this allows finding all the animals or dogs in the system.
Multiple values per attributes
The current datamodel is incomplete when it comes to multi value storage for one attribute, but html forms allow this. The min_n_values/max_n_values imply you can store more than one value per attribute but the data model but it's not clear what happens if you set max greater than 1. I think the way to do this is add a new storage type called generic_multi and create a table like:
key field_id object_id v_object_id v_number v_varchar v_clob key is a primary key field_id/object_id are unique v_object_id must be an object_idThis would require a new set of acs_object apis like get_multiattribute, set_multiattribute and delete_multiattribute. This allows some kind of typed storage as well as objects to be stored inside objects.
Multifield validation is a problem also. On my current project I do single field automatically and multifield with custom code. This works pretty well but I don't do much multifield validation.
My point is more that it's not necessarily a good idea to presume a single widget for a given field will be adequate. Certainly for a basic "one size fits all" rapid prototype the generic interface it will be ok but cms has something almost exactly like this already (with the added bonus of the ability to populate widget params from the db or evaled tcl code) and it is not up to the job for real forms either.
Also, on one to many I suspect it would be better to just create tables for the 1-N types rather than a table with a union of all possible data types in it. there is a table field in the acs_attributes table already for that purpose.
Addresses are a good example because I think it's possible to have one datamodel to store most addresses, but you need multiple user interfaces depending on local or user preferences. In my case I need to collect US and Canada addresses. Some people need to enter either. Some people only want to enter US and don't want a country box. Some want ZIP+4 others want full state names and still others want the two character states.
If you build a address object with a generic data model then build a US address object with a supertype of address then you should be able to override the state attribute with an enum list of the 50 US states but still store the data in the generic tables.
How the whole UI works is a different problem because you would want an address widget to display/collect the data. It might be possible in some cases to rework the UI based on the datatype but in the general case I think you would need custom widgets for most datatypes.
I don't really see this as way to auto generate all forms and save code. I actually like the ad_page_contract model with pluggable filers and call address_widget to get the html form, but users like the ever forward, error by the input box model of the form templates. This has been a constant battle for me so I started moving to form templates but it seems like the pieces don't quite fit together. Just looking thru the code it seems only a few packages use the form templates, what feedback to other people have about the press back to fix your errors interface? Of couse I just hit back to fix some mistakes and my browser presented me with a black form.
That will be our preferred way to build forms "by hand." To get a very simplistic overview in a real package checkout the "populate" package in the contrib part of the OpenACS 4.6.1 tarball.
And of course the track being discussed here is to move forward another step, automatic form generation and handling where possible. I'm not going to butt into that discussion at the moment (haven't played enough with the existing CMS form stuff to feel comfortable talking about its pluses/minuses), just wanted to emphasize that ad_form, with its ad_page_contract declarative flavor, is what we want people to use if possible rather than call the form builder "by hand". It's easier and more readable when the form handling you're implementing fits what it can do and it's being extended on a regular basis to cover cases it can't currently.