Forum OpenACS Development: ad_form all over the place?

Posted by Michael Hinds on
I'm not overly keen on ad_form. I think it's perfect for knocking together admin screens and the like, but I don't see a need to use it everywhere, and I definitely wouldn't bother going back to old code and porting it.
Posted by Dave Bauer on
ad_form just exposes the Form Builder APIs through an interface that helps to manage state, etc. It is not necessary to use ad_form, but forms should use the form builder wherever possible. In fact, I can't think of a time when the form builder or ad_form shouldn't be used. The form builder integrates with the templating system and allows for conisistent form design, which changes to layout and presentation made in one place.
Posted by Roberto Mello on
I can think of one place where it's hard to use ad_form: on forms where you need fine control over the appearance.

I don't know if there's a way to tell ad_form to use a different form template (instead of the standard.adp) though.

But for everything else, ad_form (and the form builder) are great.


Posted by Benjamin Bytheway on
There is an easy way to use different form layouts, and it's the same whether you use the form builder or ad_form, because it's done in the .adp file.

You define which form layout you want to use with the "style" attribute of the <formtemplate> tag.  For example:

<formtemplate id="my_form" style="plain">

The templates which implement the different styles are stored in:


Posted by Roberto Mello on

I didn't word what I meant right. I knew about the formtemplate tag. What I meant was without having to grok through the bunches of things that happen there.

Have you tried editing one of the form templates to get it to do something differently? I wouldn't say that it is easy, but it could be made to be.


Posted by Don Baccus on
As Dave makes clear, ad_form is just a wrapper around the ATS form builder, one that manages state for you and in general leads to simpler and easier-to-read code than direct use of the form builder.

It makes it very easy to write self-submit forms and to combine new content/edit content forms.  The first point's important because errors in forms (rather than "you messed up, hit 'back'") is user-friendly.  The second is important because you only have to maintain one block of form generation code, which guarantees consistency between "new" and "edit" data forms.

So the question is: do you want to be able to consistently modify the look and feel of forms throughout the system by changing a small set of shared templates, or would you rather change the look and feel of all forms on a site the ACS 3 way, by tediously editing hand-generated HTML on a large set of pages?

I vote for using the ATS and ad_form so I can change the look and feel by modifying a small set of templates.

And why would one only want to be able to change the look and feel of admin screens simply?  I'd say just the opposite - admin screens can be plain, ugly and hard to customize but user input forms need to be morphable to a site-designers vision of a consistent look and feel for a given site.

As far as rewriting old code ... if the code uses the form builder directly, no, we haven't bothered. When I've touched existing code for other reasons I have at times flipped the code to use ad_form because it only takes a few minutes and doing things like complex validation checks is simpler in ad_form than when you use the form builder directly.

Posted by Tom Jackson on

ad_form supports and encourges mixing markup with tcl code. This makes changes to the look of the form, or the editing of the tcl file more difficult, increasing maintainance costs. Hopefully if the datasources don't change, you should be able to employ an html crew to maintain a site, but with ad_form you will probably need your tcl programmer to do the job.

Although it might be thought that having input of content and editing handled by the same form/tcl page, in actual practice I doubt it would be generally helpful. Remembering maintainance of current code, it is much easier to track down bugs if pages have a single function. In the event that the enter and edit pages become significantly different, the maintainer has to somehow perform a 'cojoined twin' type separation. I'm trying to imagine tracking down bugs by looking at the error log. What was the state of the form when the error occured on that page? Even with single function pages, errors that occur when users, not developers, visit a page can be baffling.

ad_form can't be used on a form where more than one object is being edited/input/deleted. This severely limits the usefulness of ad_form. These are things that simple html forms, and ad_page_contact handle with ease.

I think ad_form is more useful with admin pages, as there will probably be less mucking with the look of pages over time. However admin pages are more likely to have complex needs for displaying and editing data. Also, if absolute speed in churning out a UI is important, I think it could help quite a bit.

Of course the main problem is that I don't seem to be able to wrap my simple mind around the idea of ad_form. Maybe if the documentation would explain what vars are set and available in the adp page, based on the different parts of ad_form present in the tcl page, I could figure it out. If core packages are going to use ad_form this kind of documentation would be very important for future maintainers. Asking new blood to maintain a package using ad_form is quite a stretch.

Posted by Dave Bauer on

I am not sure what you are referring to with mixing tcl and markup using ad_form.

I rewrote the admin pages for the simple-survey to survey package using ad_form. I removed all the HTML from the tcl files. I also eliminated several pages, and generally improved the user interface.

I need to repeat the benefit Don mentioned which you get when using ad_form or the form builder directly, inline error messages. This user interface improvement alone makes it worth using the toolkit features to process forms.

Posted by Don Baccus on
HuH?  ad_form supports what the form builder supports.  So, let's talk about the form builder, not ad_form.  ad_form does none of the things you suggest.  The semantics are all form builder semantics, nothing more.

You can, if you want, build your custom look-and-feel form using form templating tags rather than use a standard template.  These go into the .adp file and, just like as is true with the rest of the template system, look like augmented HTML.  For input forms that have to meet a particular look and feel that can't be generalized in a template that's shared by many forms in the system, that's the way to go.

It is simply untrue that the form builder - or ad_form - can't handle pages where more than one object is being edited or input.  ad_form's key management stuff (one of the few things it brings to the table that doesn't exist in the form builder per se) can't be used - you have to do that yourself.  But if you don't use ad_form you also have to do it yourself.  The bottom line, though, is that it can be done.

And indeed most of the forms I've built with ad_form do handle more than one object - a content item and its associated content revision.  Two, not one, objects, in the same form.

I've also used it in the homework package where we link two objects together (homework and correction files) with no problem.

As far as getting your head around it ... it helps a *lot* if you understand how the form builder itself works, because after all ad_form is first and foremost a wrapper that simplifies the use of the form builder.

Of course ... no one is forcing you to use the form builder.

I have practical experience with this at Greenpeace, where I was able to shrink several thousands of lines of hand-built HTML that built forms into literally less than a 100 lines of .adp code in a shared form template.  And the Tcl code shrunk by 3/4 to boot.  Now that was extremely poorly written code I was replacing but I doubt you're going to convince the GP people that going back to hand-built forms written in pure HTML is an improvement.

Curiously previous discussion has developed the theme that automatic form building using type metadata to feed the template system's form builder would be adequate for admin forms but in general forms built by hand (but using the form builder/ad_form) would be necessary for more generalized forms.

Posted by Don Baccus on
Although it might be thought that having input of content and editing handled by the same form/tcl page, in actual practice I doubt it would be generally helpful. Remembering maintainance of current code, it is much easier to track down bugs if pages have a single function.
Those of us using the form builder haven't found this to be true. Typically there are two differences between a form to edit data and to add new data
  • the database operations (insert vs. update) however when using the CR this can be masked - my CR ad_form pages generally have a single "on_submit" clause.
  • Data needs to be filled in from the DB in the edit case

For those cases where you do have to do different operations when adding new data vs. editing existing data, I think the two separate clauses "edit_data" and "new_data" are quite clear.

On the other hand, there are generally at least two things in common, and it is nice to not have to maintain two separate chunks of code for them

  • The form elements and layout itself - it is nice to be able to guarantee consistency
  • validation of data - it is crucial that data validation being semantically identical for pages that edit existing and add new data

The form builder paradigm encourages this code sharing, and ad_form simplifies the associated state management.

Posted by Tom Jackson on

Don, having used the form builder procs, I can state that ad_form appears to greatly simplify the situation.

When I said that ad_form supports and encourages mixing markup with tcl code, I was referring to the -html arguments to both ad_form and each individual form element. The example given in the documentation also uses these arguments. It seems pretty clear to me that the form builder generates html, and the use is encouraged by every example I have seen. Maybe instead of showing examples of default behavior, some examples of using the vars generated with ad_form in an adp page would help explain the situation.

The default behavior makes it more difficult to read and edit the tcl file, or understand what the adp will generate without reading the tcl file. The example, or examples, should other important details as well:

  • If you have a select list, how can you generate this by a db select so that you don't hard code the option values in the tcl file? What about the display name for the options?
  • How can you select from the db, or include on the adp page the "you screwed up" hint for the confirm form? If I change the hint, I want to do it maybe in one place in the db, or be able to include it in the adp file so future maintainers don't have to edit the tcl file.
  • How can I change the -html values other than editing the tcl file? If I can change something in the db and then select that for use in ad_form that would be great.

    The bottom line is I would like to avoid editing the tcl file to change the look. Once you hard code what the form html is going to be, you replace editing 100 adp templates with editing a 100 tcl files.

    Unfortunately when ad_form is used in core packages, every developer is forced to know how it works. Future maintainers are going to have to know it well. Explaining how ad_form works in a forum post isn't documentation, it is an indication of a lack of documentation. The fact that Don, Dave and a few other people can explain it and use it doesn't mean that it is documented.

    Dave, I did a checkout of simple-survey, but didn't find any use of ad_form. How can I obtain this package with the changes you are talking about?

    Finally, I've said it before wrt ad_form, it must be useful, otherwise the folks who are using it wouldn't be. Maybe I just need to fastforward to Thursday, drink a beer and mellow out.

  • Collapse
    Posted by Don Baccus on
    Every item you point out is a form builder issue, not an ad_form issue. I'm not trying to belittle them as issues, just trying to clarify the fact that these questions have nothing to do with ad_form per se.

    A question, though ... if I have a column in a database table that's (say) 50 characters wide ... do I want a designer changing the size of the input widget to 100 characters? Or 3 characters? Isn't this exactly the kind of thing I as a programmer want to control?

    select lists can certainly be pulled from the database, and you can do so for label names too (necessary for localized packages) however undoubtably this could all be made simpler still. I'm the last to suggest that ad_form is in its final form, people have been adding stuff to it steadily.

    Regarding documentation, have you read Jon's? If so and you find it lacking communicate with him, I'm sure he'll add to it. Of course we do need to integrate this with the distributed docs, my point is that documentation's not being ignored. Jon volunteered to do it months ago, has done some, and surely is open to suggestions for improvements.

    Unfortunately the underlying form builder itself is poorly documented, too, and getting that straightened out is yet another documentation issue.

    I do think that, yes, people expecting to work on core packages are going to have to learn the templating system including the form builder/ad_form way of building forms.

    Posted by Jon Griffin on
    My doc is accurate, but there are some additions that could be made.

    As usual the problem is time. I will try to add some of the things that I now know as well as some things Dave B has done in the near future.

    Posted by Tilmann Singer on
    Tom, isn't the fact that you can switch off the form builders html generation by inserting your own html inside the <formtemplate></formtemplate> tags exactly what you need?

    I had to deal a few times with forms that were pre-produced by designers in a way that would not be automatically producable because they were not really systematic, so I just replaced their <form> tag with <formtemplate>, and their <input foo="x" bar="y"> with <formwidget foo="x" bar="y"> and after that I was able to benefit from input validation and all other functionalities of ad_form, while maintaining exactly the look that the designers intended. That obviously has the drawback that when you do changes to the fields you also need to edit the adp file but this is of course inavoidable.

    You also need to add <formerror> tags for positioning the "wrong input" error messages near the fields that caused them, and it becomes a little tricky when you want to only display certain formatting tags in case of an error (e.g. <font color="red">Wrong Input</font>), but it's certainly possible.

    Posted by Tom Jackson on

    I get the points about validation and the goal of making forms more user friendly by presenting the same form with errors clearly marked. It seems helpful for code re-use to use some kind of self-submit page.

    Since it is obvious that I don't know how to effectively use ad_form or the underlying form builder in every situation, I would like to start some kind of database of examples for myself. I'm not interested in the default behavior of either of these two APIs, since that seems documented already. What I want to figure out is how do more tricky situations. If anyone has examples they would like to share, please email them to me.