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>
>>
>>

-- 



Reply via email to