Hello,
I've had this issue before, where a string which is passed as part of
request.vars somehow becomes a list when the form is submitted. The
way I got round it at the time was by doing:
if isinstance(thread_id, list):
thread_id = thread_id[0]
However, that just doesn't feel right, and will only work where the
value never changes (i.e. I can assume that all items in the list have
the same value so [0] is as good as any), and more to the point, it
doesn't address why this is happening in the first place.
I tried the suggestion in post 17355 of this mailing group which seems
to suggest explicitly passing the vars on submit by adding the
following to the submit button:
_action=URL(r=request,args=request.args)
However, that doesn't work either.
I've posted some code below where this is happening to the variable
"thread_id", if you look at the 8th & 9th line of function
addreplacementpage() you'll see that I test whether the variable is a
list or not, and it proves positive only when the form is submitted,
i.e. the function goes round the loop a second time (self-submitting
form).
Has anyone else experienced this or have a solution to the problem, or
even better: advice on how to figure out what's going on in these kind
of situations?
Also, feel free to bash the code, constructively...
regards,
Andy.
-------------
def addreplacement():
#Call this function from other pages, it will initialise the
PartLists and SelectedParts session
#variables if required, generate a thread_id and then redirect to
addreplacementpage function below.
#These two session variables store the partlist and currently-
selected-item-in-partlist(for delete/edit purposes)
#for the replacement currently being worked on (either newly
raised or amended)
#The 'thread_id' var is used to allow multiple replacements to be
edited within the same session,
#so for the replacement currently being edited use
session.PartLists[thread_id] to obtain prt list
#and session.SelectedParts[thread_id] to obtain selected part.
Complaint_Base_id = request.vars.record
title = 'Complaint Raised'
if not (Complaint_Base_id ):
return ComplaintSystem.__ShowSimplePage(globals(),
dict(message = "Record id was not supplied with request." ,
title=title))
thread_id = int(uuid.uuid4())
if not session.PartLists:
session.PartLists = dict()
session.PartLists[thread_id] = dict()
if not session.SelectedParts:
session.SelectedParts = dict()
session.SelectedParts[thread_id] = -1
redirect(URL(r=request, f='addreplacementpage',
vars={'record':Complaint_Base_id, 'thread_id':thread_id}))
def addreplacementpage():
#This must only ever be called by function 'addreplacement'
title = 'Complaint Raised'
Complaint_Base_id = request.vars.record
thread_id = request.vars.thread_id
assert(Complaint_Base_id )
assert(thread_id)
if isinstance(thread_id, list):
return 'its a list!!!!!'
response.view = 'Complaints/AddReplacement.html'
response.title = title
Table = db.Replacement
form = GenerateReplacementForm( thread_id = thread_id )
if form.accepts(request.vars, session):
FieldValues = dict()
for f in Table.fields:
if form.vars.has_key(f):
FieldValues[f] = form.vars[f]
FieldValues['Complaint_Base_id'] = Complaint_Base_id
ReplacementId = Table.insert(**FieldValues)
for key, value in session.PartLists[thread_id].items():
db.Replacement_Part.insert(Replacement_id=ReplacementId,
Row_Index=key, Part_Number=value[0], Description=value[1],
Cost=value[2], Quantity=value[3])
return ComplaintSystem.__ShowSimplePage(globals(),
dict(message='New record created', title='Record Created', links =
links))
return dict(form = form, id = Complaint_Base_id )
def GenerateReplacementForm( thread_id , Rec_ID = None):
Table = db.Replacement
Fields = list(db.Replacement.fields)
for i in ['Complaint_Base_id', 'Status', 'Date_Authorised',
'Project_Coordinator']:
Fields.remove(i)
if Rec_ID :
form = SQLFORM(Table, record = Rec_ID , showid=False, fields =
Fields)
else:
form = SQLFORM(Table, fields = Fields)
form.custom.submit = INPUT(_type="submit", _value="Submit",
_action=URL(r=request,args=request.args))
ajaxAddPart = "ajax('%s', %s, 'partfielderrors');ajax('%s',
%s,'target');" % \
(URL(r=request,f='validatepart'), PartFieldsString,
URL(r=request, f='addpart'), PartFieldsString)
innertable = TABLE(
TR(
TD(
TABLE(
TR(TD(B('Add Part:')), TD(INPUT(_type='hidden',
_id='thread_id', _name='thread_id', _value=thread_id)), TD()),
TR(
TD(LABEL('Part No')),
TD(LABEL('Description')), TD(LABEL('Cost')), TD(LABEL('Quantity'))),
TR(
TD(INPUT(_type="text", _id='partno',
_name='partno', _class='partnofield' )),
TD(INPUT(_type='text', _id='description',
_name='description', _class='descriptionfield' )),
TD(INPUT(_type='text', _id='cost',
_name='cost', _class='numericfield')),
TD(INPUT(_type='text', _id='quantity',
_name='quantity', _class='numericfield')))
)
)
),
TR(
TD(
TABLE(
TR(
TD(INPUT(_type='button', _value='Add part',
_onclick=ajaxAddPart)),
TD(DIV('', _id='partfielderrors',
_class='error' ))
)
)
)
),
_class='tablewithborder'
)
outtertable = TABLE(
TR(TD(B('Replacement Parts:'))),
TR(TD(DIV(__refreshtable(thread_id), _id='target'))),
TR(TD(innertable )),
_class='tablewithborder')
form[0][12].insert(1, TR(TD(), TD(outtertable)))
return form
def __refreshtable(thread_id):
if isinstance(thread_id,list):
thread_id = thread_id[0]
if session.PartLists and session.PartLists.has_key(thread_id):
partlist = session.PartLists[thread_id]
else:
partlist = dict()
if len(partlist.items()) > 0:
table = TABLE(TR(TD(INPUT(_type='hidden', _id='thread_id',
_value=thread_id)), TD(LABEL('Part No')), TD(LABEL('Description')),
TD(LABEL('Cost')), TD(LABEL('Quantity'))),
_class='tablewithinnerborder')
rowcnt = 0
sel_func = URL(r=request,f='selectpart')
ajaxRemovePart = "ajax('%s', ['thread_id'], 'target');" %
URL(r=request, f='removepart')
ajaxeditpart = "ajax('%s',['thread_id'],'target');" %
URL(r=request,f='editpart')
Total = 0.0
IndicesList = list(partlist .iterkeys())# use this so we have
parts listed in order they were added...
IndicesList.sort()
for key in IndicesList:
value = partlist[key]
rowcnt += 1
idstr = 'partselection%s' % key
fieldsString = "['%s', 'thread_id']" % idstr
cost = value[2]
quantity = value[3]
table.insert(rowcnt , TR(
TD(INPUT(_type='radio', _name='partselect', _id =
idstr , _value = key, _onclick="ajax('%s', %s);" %(sel_func ,
fieldsString))),
TD(INPUT(_type='text', _disabled=True,
_value=value[0], _class='partnofield' )),
TD(INPUT(_type='text', _disabled=True,
_value=value[1], _class='descriptionfield' )),
TD(INPUT(_type='text', _disabled=True, _value=cost ,
_class='numericfield')),
TD(INPUT(_type='text', _disabled=True,
_value=quantity , _class='numericfield'))
))
Total += quantity * cost
table.insert(rowcnt + 1, TR(
TD(),
TD(),
TD(LABEL('Total Replacement Cost:')),
TD(INPUT(_type='text', _disabled=True, _value=Total,
_class='numericfield')),
TD())
)
table.insert(rowcnt + 2, TR(
TD(),
TD(INPUT(_type='button', _value='Remove Selected',
_onclick=ajaxRemovePart )),
TD(INPUT(_type='button', _value='Edit Selected',
_onclick=ajaxeditpart )),
TD(INPUT(_type='hidden', _id='dummy')),
TD())
)
return table
else:
return '(No replacement parts)'