OK- figured this out, mostly. Anthony's answer worked, but only after I
added session to the .accepts(...) args // and or used
form.process(...).accepted instead.
Working code below:
*Controller:*
*
*
def index():
form = FORM(INPUT(_name='name'))
if form.accepts(request.vars, session=session, formname='my_form'):
# OR if form.process(formname='my_form').accepted:
logger.debug(form.vars.name)
import time
time.sleep(1) # Wait a little to allow a double submission
response.flash = "Form accepted."
elif form.errors:
response.flash = str(form.errors)
else:
pass
return dict(form=form.process(formname='my_form'))
*
View:*
*
*
<form method="POST">
<input type="text" name="name">
<input type="submit" value="Double Submit Me">
<input type="hidden" name="_formname" value="my_form">
<input type="hidden" name="_formkey" value="{{=form.formkey}}">
</form>
Note however that using *{{=form.hidden_fields()}}* in the view does NOT
work for me (the form never gets accepted) even though the generated HTML
looks fine. I don't have an explanation for this-
On Tuesday, August 7, 2012 11:34:12 AM UTC-4, Anthony wrote:
>
> After calling form.accepts (or form.process), the generated formkey is
> stored in form.formkey. You can also use form.hidden_fields() to generate
> the _formname and _formkey hidden fields instead of creating them manually.
>
> def index():
> return dict(form=FORM(INPUT(_name='name')).process(formname='my_form'
> ))
>
> View:
>
> <form method="POST">
> <input type="text" name="name">
> <input type="submit" value="Double Submit Me">
> <input type="hidden" name="_formname" value="my_form">
> <input type="hidden" name="_formkey" value="{{=form.formkey}}">
> </form>
>
> or
>
> <form method="POST">
> <input type="text" name="name">
> <input type="submit" value="Double Submit Me">
> {{=form.hidden_fields()}}
> </form>
>
> Anthony
>
> On Tuesday, August 7, 2012 10:11:18 AM UTC-4, Yarin wrote:
>>
>> Sometimes I need to define my forms in the view, but still want to use as
>> much of web2py's form functionality as possible. In those cases I generally
>> define the form in the controller as well, with corresponding fields, and
>> then build a form in the view with the same formname.
>>
>> This works, except that I can't figure out how to make use of formkey to
>> prevent double posting in this scenario?
>>
>> *Controller:*
>>
>> def index():
>>
>> my_form = FORM(INPUT(_name='name'))
>>
>> if my_form.accepts(request.vars,formname='my_form'):
>>
>> logger.debug(my_form.vars.name)
>>
>> import time
>> time.sleep(1) # Wait a little to allow a double submission
>>
>> response.flash = "Form accepted."
>>
>> elif my_form.errors:
>> response.flash = str(my_form.errors)
>> else:
>> pass
>>
>> return dict()
>>
>>
>> *View:*
>>
>> {{extend 'layout.html'}}
>>
>> <form method="POST">
>> <input type="text" name="name">
>> <input type="submit" value="Double Submit Me">
>> <input type="hidden" name="_formname" value="my_form">
>> </form>
>>
>>
--