Form field defaults the second time through

93 views
Skip to first unread message

Dave S

unread,
Jan 19, 2017, 2:31:15 PM1/19/17
to web2py-users

I have a straight-forward controller function for entering the primary data:

def index():
    
"""
    """

    response
.flash = T("Hello World")
    form 
= SQLFORM(db.QuarterMaster)
    form
.vars.PostDate = str(request.now.year) + "-" + str(request.now.month) + "-" + str(request.now.day)
    
if form.process().accepted:
        form
.vars.PostDate = request.vars.PostDate
        response
.flash = T("Thank you!")
    
elif form.errors:
        response
.flash = T("Please correct the errors in the form")
    
else:
        response
.flash = T("Please fill out the form")
    
return dict(form=form)


The intial display of the form shows the current date correctly (give or take a leading 0), but after submission the PostDate field is empty.  I would like to have it default to what was used the previous time through, but it appears that value is dropped after the accepted branch.  What do I need to do?

It does not work to replace the top part with:

    form = SQLFORM(db.QuarterMaster)    if request.vars.PostDate:
      form.vars.PostDate = request.vars.PostDate
    else:
      form
.vars.PostDate = str(request.now.year) + "-" + str(request.now.month) + "-" + str(request.now.day)
    if form.process().accepted:
        # here was 
form.vars.PostDate = request.vars.PostDate

Thanks.

Dave
/dps

Armando Hernandez

unread,
Jan 20, 2017, 1:02:04 AM1/20/17
to web2py-users
Assuming PostDate is a field of type datetime Try this before calling SQLFORM
db.QuarterMaster.PostDate.default = request.now

If PostDate is a field of type date use
db.QuarterMaster.PostDate.default = request.now.date()


and remove all the

form.vars.PostDate assignments

Áureo Dias Neto

unread,
Jan 20, 2017, 5:10:31 AM1/20/17
to web...@googlegroups.com
Change

  if form.process().accepted:
        form.vars.PostDate = request.vars.PostDate
        response
.flash = T("Thank you!")

to

  if form.process(keepvalues = True).accepted:
         response.flash = T("Thank you!")




--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to the Google Groups "web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Val K

unread,
Jan 20, 2017, 12:23:37 PM1/20/17
to web...@googlegroups.com
form.vars appear only after form.process()  call (process() - filter/convert/format/validate request.post_vars to form.vars)
you have variants :
1. before form creation  - modify field.default
2. before form.process()  -  modify request.vars - request.post_vars.PostDate=... 
3. pass your own set of vars  -  form.process(vars=myvars)
4. use form.process( onvalidation=myvalidation_fun) to modify form.vars  after basic validation passed but before any db actions

Dave S

unread,
Jan 22, 2017, 4:48:45 AM1/22/17
to web2py-users


On Friday, January 20, 2017 at 9:23:37 AM UTC-8, Val K wrote:
form.vars appear only after form.process()  call (process() - filter/convert/format/validate request.vars to form.vars)
you have variants :
1. before form creation  - modify field.default
2. before form.process()  -  modify request.vars - request.vars.PostDate=... 
3. pass your own set of vars  -  form.process(vars=myvars)
4. use form.process( onvalidation=myvalidation_fun) to modify form.vars  after basic validation passed but before any db actions
 
 


But what about this passage in the book?

Pre-populating the form

It is always possible to pre-populate a form using the syntax:

1
form.vars.name = 'fieldvalue'
Statements like the one above must be inserted after the form declaration and before the form is accepted, whether or not the field ("name" in the example) is explicitly visualized in the form.

Val K

unread,
Jan 22, 2017, 5:50:16 AM1/22/17
to web2py-users

Pre-populating - means just default values  which will be overwritten during form.process(), i.e.  form.process() reads vars values only from request.post_vars  or from 'vars' arg  - form.process(vars = {...} ) and ignores  pre-sets like form.vars.name=... 


There was a mistake in my  post: instead  request.vars  must be request.post_vars -   I fixed this 

Dave S

unread,
Jan 22, 2017, 3:58:06 PM1/22/17
to web2py-users


On Sunday, January 22, 2017 at 2:50:16 AM UTC-8, Val K wrote:

Pre-populating - means just default values  which will be overwritten during form.process(), i.e.  form.process() reads vars values only from request.post_vars  or from 'vars' arg  - form.process(vars = {...} ) and ignores  pre-sets like form.vars.name=... 


There was a mistake in my  post: instead  request.vars  must be request.post_vars -   I fixed this 



But default is what I want!  If I didn't want to be able to change the value when filling out the form, I wouldn't even need to provide the field.

/dps

Val K

unread,
Jan 22, 2017, 5:56:07 PM1/22/17
to web2py-users
The problem is that one controller is used for generation and process form. it's like different modes 
pre-populating form by assignments  form.vars.name=...   could be used only for the request form, when form is submitted these assignments have no effect.
if you want to change anything  in the form after it was processed, you have to use  DOM-parsing ( something like  form[0].element('input', _name='...')['_value'] = ... )

Use keepvalues=True or  db.table.field.default  as suggested above (it does the  pre-populating during form.process())
There is brute force variant  -   self-redirection :  if form.process().accepted: ... session.flash='OK';  redirect(URL())  - but don't forget about args/vars/user_signature  if it matters

Dave S

unread,
Jan 22, 2017, 8:11:59 PM1/22/17
to web2py-users
On Sunday, January 22, 2017 at 2:56:07 PM UTC-8, Val K wrote:
The problem is that one controller is used for generation and process form. it's like different modes 
pre-populating form by assignments  form.vars.name=...   could be used only for the request form, when form is submitted these assignments have no effect.
if you want to change anything  in the form after it was processed, you have to use  DOM-parsing ( something like  form[0].element('input', _name='...')['_value'] = ... )

Use keepvalues=True or  db.table.field.default  as suggested above (it does the  pre-populating during form.process())
There is brute force variant  -   self-redirection :  if form.process().accepted: ... session.flash='OK';  redirect(URL())  - but don't forget about args/vars/user_signature  if it matters



Okay, I guess I was expecting submission to result in a fresh form creation, but it takes the self-redirection to acheive that, eh?

Val K

unread,
Jan 23, 2017, 11:18:17 AM1/23/17
to web...@googlegroups.com
yes, self-redirection restart controller in 'request fresh form' mode, but usually your have to re-pass to URL() args/vars which don't have relation to the form to provide expecting behaviour - just keep in mind this.   

--
You received this message because you are subscribed to a topic in the Google Groups "web2py-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/web2py/hT-z8wbGr38/unsubscribe.
To unsubscribe from this group and all its topics, send an email to web2py+unsubscribe@googlegroups.com.

Dave S

unread,
Jan 26, 2017, 5:13:42 AM1/26/17
to web2py-users
Thanks.  This seems to do what I want.

/dps
 

Dave S

unread,
Jan 26, 2017, 5:16:55 AM1/26/17
to web2py-users
On Sunday, January 22, 2017 at 2:56:07 PM UTC-8, Val K wrote:
The problem is that one controller is used for generation and process form. it's like different modes 
pre-populating form by assignments  form.vars.name=...   could be used only for the request form, when form is submitted these assignments have no effect.
if you want to change anything  in the form after it was processed, you have to use  DOM-parsing ( something like  form[0].element('input', _name='...')['_value'] = ... )

I didn't get that to work, doing it server-side .


Use keepvalues=True or  db.table.field.default  as suggested above (it does the  pre-populating during form.process())

keepvalues keeps too much :-/  (that is, it keeps all the field values).  The field default suggestion is working for me it seems.
 
There is brute force variant  -   self-redirection :  if form.process().accepted: ... session.flash='OK';  redirect(URL())  - but don't forget about args/vars/user_signature  if it matters

I haven't tried this one yet, but I probably will for completeness.

Dave S

unread,
Feb 1, 2017, 4:15:04 AM2/1/17
to web2py-users
I've actually modified it to:

    import datetime
    response
.flash = T("Hello World")
   
if request.post_vars.PostDate:
     
try:
        db
.QuarterMaster.PostDate.default = datetime.datetime.strptime(request.post_vars.PostDate, "%Y-%m-%d")
     
except ValueError:
       
pass
   
else:
        db
.QuarterMaster.PostDate.default = request.now.date()
   
# str(request.now.year) + "-" + str("%02d" % (request.now.month)) + "-" + str("%02d" % (request.now.day))
    form
= SQLFORM(db.QuarterMaster)
   
if form.process().accepted:

        response
.flash = T("Thank you!")
   
elif form.errors:
        response
.flash = T("Please correct the errors in the form")
   
else:
        response
.flash = T("Please fill out the form")
   
return dict(form=form)


because I'm allowing the data entry staff (me) to catch up on older (written) records.

I have yet to try the redirect technique, but I do intend to open that envelope, as well.

/dps

Reply all
Reply to author
Forward
0 new messages