Harking back to an ancient thread, I think I have finally tracked down
what I think is a grey area in checkbox processing.
The "book" says: (When a form is accepted) "If the keepvalues is set
to True the form is pre-populated with the previously inserted
values." It doesn't say, specifically what should happen when the
form is used to update a record but the inference (I think) is to keep
the updated values.
However, when a record is updated and a boolean field originally set
to True is changed to False the record is updated correctly but the
form is re-displayed with the checkbox checked when it should be
unchecked.
I believe that the problem occurs because of the difference between
determining a) if the user has checked the box and b) whether to
check the box in the form to be displayed.
a) SQLFORM.accepts() sets fields[fieldname]=True if there is a
request.var of the correct name == 'on' (lower case)
b) INPUT._postprocessing() set _checked='checked' if value exists and
is len(value)!=0
However, if the original value is True and the form box in unchecked
then value=='ON' (upper-case - from the original form component) and
tho' accepts() correctly translates this as False, _postpostprocessing
() translates this as True and checks the box.
The solution is to amend the _postprocessing() check from:
"if self['value']:"
to
"if self['value'] and self['value']=='on':" # lower case
For those interested enough to want to test the above, read on.
Test model:
db.define_table('bloke', SQLField('name','string'), SQLField
('married','boolean'))
Test controller:
def index():
form=SQLFORM(db.bloke)
if form.accepts(request.vars):
response.flash='OK'
records=SQLTABLE(db().select(db.bloke.ALL),linkto=URL
(r=request,f='update'))
return dict(form=form,records=records)
def update():
record=db(db.bloke.id==request.vars.id).select(db.bloke.ALL)[0]
form=SQLFORM(db.bloke,record)
if form.accepts(request.vars,keepvalues=True):
response.flash='OK'
records=SQLTABLE(db().select(db.bloke.ALL))
return dict(form=form,records=records)
Use the default view.
Test cases for 'married' boolean field (pre-patch):
false to false - OK
false to true - OK
true to true - OK
true to false - record ok but form displays true - re-display form to
get box and record in-line
Following patch, all cases perform correctly. For regression
purposes, when keepvalues=False, after submit (assuming valid), the
form should display the original form value. For create, 'married'
should be False/unchecked as no default is specified. For update,
'married' should be the original value of the record being updated,
i.e. the value when the record is first displayed in the form
irrespective of subsequent changes.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"web2py Web Framework" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/web2py?hl=en
-~----------~----~----~----~------~----~------~--~---