[Zope] How to make a ZPT-based form that calls itself?

J Cameron Cooper zope-l at jcameroncooper.com
Wed May 11 16:26:47 EDT 2005


Ken Winter wrote:
> Hi Zopers -
> 
> I'm trying to make a ZPT-based HTML form that:
> 
> 1. Displays the records in a MySQL 'Person' table;
> 2. Offers a field for updating this table (in my simple test example, it
> accepts the Id of a Person to delete);
> 3. When you push its 'Submit' button, updates the database; and then
> 4. Automatically redisplays itself, showing the updated 'Person' records.
> 
> After a lot of help from the folks on various Zope lists, I've made it
> through steps 1-3, but I'm stuck on step 4 and I can't find an example or
> tutorial telling me how to do it.
> 
> The relevant code snippets are:
> 
> The ZPT's body...
> 
> <table width="100%" height="100%" border="0" cellpadding="6"
> cellspacing="0">
>   <tr> 
>     <td width="1084" height="531" align="left" valign="top"><font
> color="#000000" face="Verdana, Arial, Helvetica, sans-serif"><!--
> InstanceBeginEditable name="Base" -->
>       <h1> People (deletion test)</h1>
>       <table tal:repeat="row here/dbobs/read_all_people" width="100%"
> border="0" cellspacing="0" cellpadding="0"><font face="Verdana, Arial,
> Helvetica, sans-serif">
>         <tr> 
>           <td width="44%" tal:content="string:${row/person_id} -
> ${row/first_name} ${row/middle_names} ${row/last_name}">Filler</td>
>           <td width="56%">&nbsp;</td>
>         </tr>
>       </table>
>       <p></p>
>       <form action="dbobs/delete_person_py" method="post"
> name="delete_form">
>         <p>Id of Person To Delete: 
>           <input type="text" name="person_id:int" />
>         </p>
>         <p> 
>           <input name="do_delete" type="submit" id="do_delete" value="Delete
> this Person" />
>         </p>
>       </form>
>       <p>The &quot;Ids&quot; are the numbers in front of each person's
> name.</p>
>       <p><a href="deltest.htm">Refresh This Page</a></p>
>       <p tal:replace="python:here.dbobs.test1('MyParamValue')">Junk</p>	
>       <!-- InstanceEndEditable --></font></td>
>   </tr>
> </table>
> 
> ...The one-line Python script "delete_person_py" that the form's action
> attribute calls...
> 
> container.delete_person(person_id=context.REQUEST.get('person_id'))
> 
> ...The Z SQL method delete_person(person_id) that the Python script calls...
> 
> delete from person where <dtml-sqltest person_id op=eq type=int>
> 
> ...And a URL to the test page in its current incarnation...
> 
> http://dhat.vega.zettai.net/clients/ridhwan/dhr3/deltest.htm 
> 
> What's wrong with this page is that you have to hit the "Refresh This Page"
> link to get it to do what I want it to do automatically.
> 
> I suspect that what I'm missing is some basic HTML knowledge.  But whatever
> it is, I'd appreciate your help in suggesting the missing piece.

You submit to a script, going that url, and the script is responsible 
for providing the output of the page.

Since you write no output, you see no action in your browser. Some 
browsers may display a blank page, which probably would have been more 
helpful to you.

You want your script to do something. It might print out some text to 
form HTML, but that's nasty. It usually will either (a) call some other 
object, like a page template, to provide output, or (b) do a redirect.

Case A:
   return context.some_page()

Case B:
   context.REQUEST.RESPONSE.redirect('some_page')

In your case, since this is a destructive method, you probably want do a 
redirect, back to your listing.

A more advanced and flexible technique is to use FormController. With 
that, you specify by configuration if you want redirect or traverse and 
where to go based on the results of the script (success, failure, some 
other state.)

		--jcc
-- 
"Building Websites with Plone"
http://plonebook.packtpub.com/


More information about the Zope mailing list