Forum OpenACS Q&A: Collecting POST variables

Collapse
Posted by Jason B. Standing on
Hi there o wizened community!

I'm working on some "custom" TCL/ADP pages, and am reasonably comfortable with doing so, however I've hit a bit of a snag and need a pointer or two to become unstuck.

I'm dynamically generating a form which contains a list of select boxes - almost like a multiple choice questionnaire - and the bit I'm getting stuck on is how to then read the POST variables in order to process the data and get it into the database.

I'm not using any kind of formbuilder or similarsuch, because when I started this project I couldn't find sensible instructions, and we've now opted for an approach of generating the HTML with a bunch of string concatenation functions.

The (paraphrased) structure of the HTML would be thus:
<form ...>
  <select name="item1">
      <option value="1">X</option>
  </select>
  <select name="item2">
      <option value="1">X</option>
  </select>
  <select name="item3">
      <option value="2">Y</option>
  </select>
  ...
  <submit, etc.>
</form>

If it were ASP I'd iterate through the Controls collection of the Form, however I'm not sure how to do that in this scenario.

As it's been explained to me, any variable I wish to use in an insert statement has to appear in the page contract, but I don't see how that's possible with a dynamically generated control set ?

Can someone point me in the direction of some helpful documentation, or slap me about the head for missing something really obvious/stupid ?

Cheers,

Jason =)

Collapse
Posted by Dave Bauer on
I'd actually rewrite it to use form builder or ad_form

but if you want to just dynamically build the query part of ad_page_contract

see

https://openacs.org/api-doc/proc-view?proc=bug%5ftracker%3a%3aget%5fpage%5fvariables

as an example of a procedure that does that.

You can build the list and return it from a procedure in the ad_page_contract call as is done in bug-tracker.

Collapse
Posted by Steve Manning on
I do this by giving the controls an array name then passing in an array in the page contract something like this...

ADP
===
<form ...>
  <select name="item.1">
      <option value="1">X</option>
  </select>
  <select name="item.2">
      <option value="1">X</option>
  </select>
  <select name="item.3">
      <option value="2">Y</option>
  </select>
  ...
  <submit, etc.>
</form>

NB the fullstop between the item and number in the name, this is how arrays are passed in (or at least it works for me)

TCL
===

{item:array,optional} in the page contract

then reference each control by iterating throught the array

for {set n 0} {n < 10} {incr n} {
  set item_value $item($n)
}

Hope this helps.

    -Steve

Collapse
Posted by Jeff Lu on
You can also try to use the -extend function to dynamically build the form.

Then do something like this in your ad form

ad_form -name myform -form {
    {somekey:key}
    {sometextbox:text(text) {label "some textbox"}
}

Then inside the code logic you have for generating the select boxes you just extend the form.

if { $codelogic } {
    {selectitem:integer(select)
        {label "select item"}
        {options $my_option_list}
    }
} else {
    {otherselectitem:integer(select)
      {label "other select item"}
      {options $other_my_option_list}
    }
}

I hope this helps.

Collapse
Posted by Jeff Lu on
Erk. there is a syntax error on my post. this is the correct syntax.
I forgot to include the extend portion :P
Here is the revised code

ad_form -name myform -form {
{somekey:key}
{sometextbox:text(text) {label "some textbox"}
}

if { $codelogic } {
ad_form -extend -name myform {
{selectitem:integer(select)
{label "select item"}
{options $my_option_list}
}
}
} else {
ad_form -extend -name myform {
{otherselectitem:integer(select)
{label "other select item"}
{options $other_my_option_list}
}
}
}