Forum OpenACS Development: ad_form again

Collapse
Posted by Lars Pind on
Added this to the documentation for ad_form:
Important note about how ad_form works: ad_form operates in two modes:
  1. Declaring the form
  2. Executing the form
Through the -extend switch, you can declare the form in multiple steps, adding elements. But as soon as you add an action block (on_submit, after_submit, new_data, edit_data, etc.), ad_form will consider the form complete, and execute the form, meaning validating element values, and executing the action blocks. The execution will happen automatically the first time you call ad_form with an action block, and after that point, you cannot -extend the form later. Also, if you don't supply any action blocks at all, the form will never be considered finished, and thus validation will not get executed. Instead, you will get an error when the form is rendered.

Bottom line:

  1. You must always have at least one action block, even if it's just -on_submit { }.
  2. You cannot extend the form after you've supplied any action block.
I also added a check to form::render that checks if this is an unfinished ad_form, i.e. an ad_form that doesn't have an action block, and if so throws an error.

This helps people not shoot themselves in the foot, when they add validation and don't understand why it never executes, when the reason it never executes is that the form doesn't have an action block (because it doesn't need it).

This means that all forms will have to have an action block, even if just a dummy one, and will breaks forms that don't, but after discussion, we think this is safer. If there's a general uprising, however, we'll gladly revert. it's a very small change.

The longer-term fix, I think, is to explicitly break ad_form into two parts:

  • ad_form_declare
  • ad_form_execute
One of the things you can't do today is to use -extend to add a new action block, because as soon as ad_form sees the first action block, it chooses to fire. I think explicitly making the distinction above would make it easier for people to figure out what's happening.

/Lars

Collapse
2: Re: ad_form again (response to 1)
Posted by Don Baccus on
I think this change is fine ... originally ad_form didn't come close to covering all of the execution possibilities covered by the form builder but now that we have so many on-this after-that options that most cases should be easy enough to handle within an ad_form declaration.

As far as splitting it into two ... offhand I have no strong feeling one way or the other.

Collapse
3: Re: ad_form again (response to 2)
Posted by Mark Aufflick on
I have recently implemented a (hacky) subset of ad_form in perl/Mason and did exactly the two stage thing Lars suggests. Not only does it actually make the proc logic simpler, it makes the whole process much more transparent to the developer.

Whole the whole benefit of ad_form is that it's magic does so much for you, sometimes there can be too much magic ;)

Collapse
4: Re: ad_form again (response to 1)
Posted by Malte Sussdorff on
How much effort is the breakup into two procs, who can do it and what would be the upgrade steps involved? Can the split be done automatically or are we forced to split this in every single page where we use ad_form?
Collapse
5: Re: ad_form again (response to 1)
Posted by Dave Bauer on
Malte,

I think it would be possible to write the new procedures (maybe more than two) and then write ad_form to call those procedures. This way its backwards compatible.

Collapse
6: Re: ad_form again (response to 5)
Posted by Lars Pind on
Dave,

Right on, it would even be quite easy to do.

Feel free to do so on HEAD.

/Lars