Pass Form elements to External Method
This How-to applies to: Any version.
This is a quick how-to showing the steps used to pass data into a form from the file system and pass request.form elements to an External Method for processing. (Note: Be sure to click the links, as they point to key pieces of information)
Rationale: In creating a form, there was a lot of information already available in an existing spreadsheet for many users (but not registered, my site doesn't have that). I wanted to pre-populate the form with the data I had previously gathered. Then, if there were updates, I wanted the updated data to replace the existing data in the file. (Updating is not implemented here)
Solution: I created a multipage form with the first page requesting an email, then if the email existed in my file, the form fields were pre-populated with the data from the file (NOTE: data is stored in a simple tab separated file, a cron job updates the old file with the new file but that will be fixed soon).
Steps:
- Install a multi-page form per the instructions here
- Install two Scripts (Python) in the form folder with the ZMI. The first script is for your setup, the second for saving scriptSetUp:
-
Now we need to set up the External Method to handle the data requests. (also see here)
- Be sure to call your scripts in the second page of your form using the TALES expressions. This is also explained in the multi-page form tutorial, but basically you need to set the Form Setup Script to: "here/scriptSetup" and the After Validation Script to "here/scriptSave"
- That's basically it! Now you have data from your files system to the forms, and you have passed the request.form elements back to your file system, so you can play around with them however you like!
request = container.REQUEST
RESPONSE = request.RESPONSE
#call external method to get existing data which is returned in last
last=context.getExistingData()
try: # This is where we will try to pre-populate the form fields
key=request.form['reg-email']
request.form.setdefault('reg-lastname', last[key][0])
request.form.setdefault('reg-firstname', last[key][1])
request.form.setdefault('reg-address', last[key][2])
except KeyError:
pass
scriptSave:
request = container.REQUESTRESPONSE = request.RESPONSE
#Not sure this is the best approach, but couldn't figure out how to deal with request.form.items() in my external method
val = request.form.values() #These are the values in the form fields
kys = request.form.keys() #This is the keys, note that these two are tuples, and they are sorted (see the external method below)
#call external method to save existing data to file system
context.saveNewData(context, kys, val)
def getExistingData(self, *datfile):
""" Reads existing registration data, returns dictionary which will be used to
prepopulate the forms.
"""
import csv
if not datfile:
datafile = open("reg-data.csv","r")
else:
datafile = datfile
last = {}
rdr = csv.DictReader(datafile)
for row in rdr:
last[row["reg-email"]] = [row["reg-last"],row["reg-first"],row["reg-address"]]
return last
saveNewData Method:
def saveNewData(self, ky, val):
""" Uses data from the request.form dictionary to populate the existing text file. Currently does not save the attachments!
"""
import csv
mydata=dict(zip(ky,val)) #Create a dictionary from the passed key,value tuples (probably not necessary if you could pass items)
dFile = open("reg-newdata.csv","a")
writer=csv.DictWriter(dFile,["reg-email","reg-firstname","reg-lastname","reg-address"], \ restval="000",extrasaction='ignore',delimiter='\t')
writer.writerow(mydata)
dFile.close()
return
Notes
This is written as a result of numerous requests to the Plone users group. I hope the information here helps newbies. It's not terribly sophisticated, but is intended to explain how to pass the request.form elements off the file system so they can be used there.
see also:
-
Overriding Field Defaults Dynamically
- PloneFormGen allows you to supply dynamic field defaults by specifying a TALES expression in the Default Expression field of the overrides fieldset (sub-form). This how-to explains what that means, and offers a few examples.
-
Create a Multi-Page Form
- You can create a multi-page form as a chain of form folders.