Forum OpenACS Q&A: How to get the form data of a multi-value checkbox?

When I use a form to submit a multivalue checkbox, I only get the
lastest value from the checked checkbox. how to get all the values?
please help me
If you are using the openACS database api, use this in your form action script:
ad_page_contract {
   your_variable:multiple
}
this will create a list called your_variable containing the values you passed.
Alternatively, you need to copy-and-hack set_the_usual_form_variables to degrade from a scalar into a list when it encounters multiple values.  The reason you only see the last value is because set_the_usual_form_variables just runs down the form vars list setting variables and values to the key-value pair and overwriting previous ones.

But obviously, if you can use Rolf's suggestion, go with that.

Wouldn't it be easier to just give each checkbox a unique name?  Maybe I am not understanding what he means by "multivalue checkbox."
>ad_page_contract

Well, ad_page_variables is available in OpenACS 3.2 and provides similar functionality, at least for this problem. ad_page_contract provides much greater functionality and is available in OpenACS 4.

>Wouldn't it be easier to just give each checkbox a unique name?

No, it would actually be a bit harder since you would have to write the code contained in ad_page_variables yourself.

What I hear you saying is if you had a list of employees, you would name each of the checkboxes something like emp-<id> (emp-123, etc). The page you were posting to would then look through all the form variables for those which name matched the above pattern and make a list of those id's. This is functionaly equivalent to naming them all emp_id and putting the id in the value of that form variable. But the point is, why not just use the abstraction already available to you? Besides, ad_page_variables provides some nice functionality while encouraging you to document your pages consistently.

Try an array. In OpenACS4, you can use this on the form:

1002 <input type=checkbox name=item.1002 value=1> 
1005 <input type=checkbox name=item.1005 value=1>

Then on the form processing page, using ad_page_contract:

ad_page_contract { } {

  item:array

} 
<form action="formdata.tcl">
  ...
  I will get data from database and use the checkox below to delete it in my formdata.tcl
  <input type="checkbox" name="id" value="id1">
  <input type="checkbox" name="id" value="id2">
  <input type="checkbox" name="id" value="id3">
  <input type="checkbox" name="id" value="id4">
  ...
</form>

suppose I click the checkbox with value id1,id2 and id4
in asp or jsp script, I can get the value of id as:
"id1, id2, id4"
but in formdata.tcl
with that set_the_usual_form_variables proc call,
I get a viable id with value "id4"
I want to get all the id list as:
{id1 id2 id4}
but how can I do?

Point your current form to http://zmbh.com/discussion/show-form. This should list the vars that are available to you.

href=http://zmbh.com/discussion/show-form.txt has the code used.

ad_page_variables {
 {mytestvar -multiple-list}
}

will work with the strange side effect of putting the first value into the list twice.
never mind about the weird side effect.  that was caused by
something in my test script and not by ad_page_variables
Collapse
11: Thanks all! (response to 1)
Posted by Alan Hu on
I have worked it out!
Thank David Walker's sample page.
Collapse
12: Re: Thanks all! (response to 11)
Posted by James Bennin on
I have read your post and I am dealing with similar issues.  I have a adp that use the form tag.  When the submit button is clicked, I want all the options that user selects (from a list of checkboxes) to be stored in a database table (using "insert into......")  How did you do that?  Could you step me through or send me a sample of you tcl code?

Thank you

Collapse
13: Re: Thanks all! (response to 12)
Posted by Jade Rubick on
In the first page:

Then you have the checkboxes be the same name as each other, but different values.

In the second page:

Specify that the variable is a multiple in the ad_page_contract.

Then foreach var multiple_variable_name {
  db_dml statement_name "insert into foo ..."
}

Collapse
Posted by James Bennin on
Thank you so much.  It is working great now!