Does anyone have a suggestion for a best practice way to dynamically generate multiple forms to one page from the database?

17 views
Skip to first unread message

jlegler

unread,
Jan 23, 2009, 5:16:53 PM1/23/09
to web2py Web Framework
I am creating a tool that has a custom built form on the top of a page
that, when submitted, creates an entry in the database and then
displays a new partially filled in custom built form in a list of
forms below. All of the partially filled in forms display and need to
be able to be filled out and submitted individually. The problem I am
running into is that those forms are dynamically generated and i am
not sure how to manually set _formname dynamically. No matter what I
do they all have the same formname and I don't know how to change
that. Does anyone have any suggestions on the best way to approach
this issue with web2py? Is there a better way to tackle this
problem? The formkey seems to be generated based on the table name
and I can't change that obviously. I feel like there should be a
relatively easy way to accomplish this but I can't find it anywhere in
the book. Any help would be appreciated. Thanks so much.

Robin B

unread,
Jan 23, 2009, 5:22:53 PM1/23/09
to web2py Web Framework
class FORM(DIV):
...
def accepts
(self,vars,session=None,formname='default',keepvalues=False):

Try the formname='name' of accepts.

Robin

Wes James

unread,
Jan 23, 2009, 5:31:16 PM1/23/09
to web...@googlegroups.com
with t2:

In controller:

def page1()
form1=t2.update(...)
form2=t2.update(...)
form3=t2.update(...)

return dict(form1=form1,form2=form2,form3=form3)

in view page1.html:

{{=form1}}
{{=form2}}
{{=form3}}


will show each form with its own submit button

but you will only be able to submit one form at at time

-wj

Markus Gritsch

unread,
Jan 23, 2009, 5:32:50 PM1/23/09
to web...@googlegroups.com
On Fri, Jan 23, 2009 at 11:22 PM, Robin B <rob...@gmail.com> wrote:
>
> class FORM(DIV):
> ...
> def accepts
> (self,vars,session=None,formname='default',keepvalues=False):
>
> Try the formname='name' of accepts.

The Book says on page 163
"Moreover,when multiple forms are present on the same page the
mechanism for preventing double submission breaks and you must omit
the session argument when calling the accepts method."

Is this still true? From the code in html.py it seems, that
preventing double submission also works for multiple forms on a page.
One just has to set the formname of each form, and pass the session to
accepts(). Correct?

Markus

jlegler

unread,
Jan 23, 2009, 5:40:24 PM1/23/09
to web2py Web Framework
I had tried that and thought that perhaps I was using it wrong. Here
is an example of it not working. I am probably doing something wrong
but I can't seem to find it. I am dubious of the code in my model now
so I have included it as well. I don't really understand how the
formkey is generated so it seems likely that I have made a mistake
somewhere in there. In the example you'll notice that I tried to
define the formname as 'new_function_test'; however, when it is
rendered to html it goes back to 'function_test' which is the table
name. Thank again for looking at it and I apologize for my horrible
looking code.

### In Controller ###
def test_case():
form = SQLFORM(db.function_test)
form.accepts(request.vars, session, formname='new_function_test')
create_form = FORM(TABLE(THEAD(TR('Functionality', 'Task',
'Expected Result', 'Submit',
_class='header')),
(TR(TEXTAREA(_name='functionality',
_class='functionality'),
TEXTAREA(_name='task',
_class='task'),
TEXTAREA(_name='expected_result',
_class='expected_result'),
INPUT(_type='radio',
_onChange='create_test.submit
()',
_value = '1'))),
_class='function_tests',
_cellspacing='0'),
custom(db.function_test),
hidden={'test_status':'Not Run',
'test_case':request.args[0],
'modified_on':now,
'created_on':now},
_name='create_test')
if form.accepts(request.vars, formname='function_test'):
response.flash='New Test Added.'
elif form.errors:
for i in form.errors:
response.flash='ERROR: %s can not be empty.\n' % i

### In Model ###
def custom(table):
"""
Allows me to build custom tables instead of the built in ones by
returning
a table with two hidden fields; one with the formname and one with
the
formkey.
"""
import uuid
formkey=session['_formkey[%s]' % table]=str(uuid.uuid4())
return TD(INPUT(_name='_formname', _value=str(table),
_type='hidden'),
INPUT(_name='_formkey', _value=formkey,
_type='hidden'))

### This is what was rendered ###
<form action="" enctype="multipart/form-data" method="post"
name="create_test">
<table cellspacing="0" class="function_tests">
<thead>
<tr class="header">
<td>Functionality</td>
<td>Task</td>
<td>Expected Result</td>
<td>Submit</td>
</tr>
</thead>
<tr>
<td>
<textarea class="functionality" cols="40" name="functionality"
rows="10"></textarea>
</td>
<td>
<textarea class="task" cols="40" name="task" rows="10"></textarea>
</td>
<td>
<textarea class="expected_result" cols="40" name="expected_result"
rows="10"></textarea>
</td>
<td>
<input onchange="create_test.submit()" type="radio" value="1" />
</td>
</tr>
</table>
<td>
<input name="_formname" type="hidden" value="function_test" />
<input name="_formkey" type="hidden"
value="680cc5d9-6c45-4199-9953-0ba1a7a695a4" />
</td>
<input name="modified_on" type="hidden" value="2009-01-23 14:31:28" /
>
<input name="test_status" type="hidden" value="Not Run" />
<input name="created_on" type="hidden" value="2009-01-23 14:31:28" />
<input name="test_case" type="hidden" value="1" />
</form>

jlegler

unread,
Jan 23, 2009, 5:42:24 PM1/23/09
to web2py Web Framework
The problem with this is I have to know how many forms I will be
sending back. I am dynamically generating them based on entries in
the database so I never get a chance to statically define them in the
controller.

jlegler

unread,
Jan 23, 2009, 5:44:06 PM1/23/09
to web2py Web Framework
Ugh, sorry everyone. I didn't realize that it wasn't keeping track of
the thread for me so I deleted the original emails in my responses. I
will not do that in the future.

jlegler

unread,
Jan 23, 2009, 5:47:50 PM1/23/09
to web2py Web Framework
Markus, That is how I understood it as well; however, something I am
doing is making the formname change not take. I am under the
impression that if I am able to set the formname, I will be able to
keep the session since the formname will be unique. I can't get the
formname change to stick though so the point is kind of moot right
now.

On Jan 23, 2:32 pm, Markus Gritsch <m.grit...@gmail.com> wrote:

jlegler

unread,
Jan 23, 2009, 6:27:51 PM1/23/09
to web2py Web Framework
Okay, now I am getting the following error:

SyntaxError: user is tampering with form

I printed request.vars and I see an entry for every table in my
database with its own unique key. It looks as though I am just
renaming the key associated with that table and not creating a unique
one. This is not the way to solve this issue. I am not sure where to
go from here. I am probably doing this the wrong way so if anyone has
any suggestions on how to dynamically generate forms on the same page
that I can submit individually I would love to hear ideas. Thanks so
much.
Reply all
Reply to author
Forward
0 new messages