|
Cookbook /
UpdateFormSummary: Easily create forms to display, add, and update records in a MySQL table.
Version: 1.3
Prerequisites: MySQL database
Status: in active use at permaculturecollaborative.us
Maintainer: Ben Stallings
Categories: Content Management System Add-Ons, System Tools
Questions answered by this recipe
DescriptionUpdateForm builds on the syntax and functionality of the forms.php script included with PmWiki to allow a form to display a specified record from a database. (The record may be specified by a link from another page, for example by SelectQuery.) If the information is altered and the form submitted, the record will be updated in the database. If no record is specified, a new record will be created when the form is submitted. No custom code must be written; just create a wiki form for each table you want to work with, and you've got an instant front-end interface for that table. Better yet, the forms automatically recognize when they're being used to update a user's own information, so the user's ID doesn't need to be specified; it's taken from the session variable instead. The script automatically recognizes whether you're using UserAuth or AuthUser and defines the username accordingly. (Thanks to Helge Larsen for this fix!) Skip down to the examples Installation
define ('DB_SERVER', 'db1.example.com');
define ('DB_NAME', 'my_database');
define ('DB_USER', 'my_username');
define ('DB_PASS', 'my_password');
NotesThe syntax is the same as for (:input:) forms, but the word "input" is changed to "update", and some additional parameters are used. Input and Update tags can be mixed and matched within a single form; for example, you can use an (:update select:) within an input form to create a drop-down menu, or an (:input text:) within an update form if you don't want to retreive that field from the database. (:update end:) produces exactly the same output as (:input end:), namely </form>. Required Parameters of the (:update form:) tag
Optional Parameters of the (:update form:) tag
Optional Parameters in Form Elements
Drop-down menusDrop-down menus can be generated, using another query to supply the list of values. This is extremely useful even outside of an UpdateForm; for example, you can use a drop-down inside a traditional (:input:) form to set the parameters for a SelectQuery. Required parameters:
Simple example: <select name='cat'> <option value='tabby'>tabby</option> <option value='persian'>persian</option> ... </select> Optional parameters:
Complex Example: <select name='widget_id'> <option value=''>Select your widget</option> <option value='00305023.82F'>Egyptian Rat Screw</option> <option value='00025325.52Q'>Fibble Extender</option> <option value='8535937X.42X'>Glabbish</option> </select> TextareasUnlike an (:input textarea:), an (:update textarea:) can have a value -- either specified by the database record or explicitly as ExamplesHere's an example form, with linebreaks inserted for readability: (:update form table=members fields=memberid,personid,startdate,member_type,dues_paid, payment_id,hours_pledged,notes required=personid,startdate,expiredate,type null=dues_paid default=hours_pledged where=memberid redirect=Members/List:) ||border=0 ||! Member Name:(:update hidden memberid:)||(:update select personid label="CONCAT(lastname,', ',firstname)" from=people where="lastname IS NOT NULL" order=lastname,firstname null="Select a person" tabindex=1:) || ||! Start Date:||(:update text startdate size=10 mask=####-##-##:) (YYYY-MM-DD) || ||! Type:||(:update radio member_type household:)Household\\ (:update radio member_type student:)Student\\ (:update radio member_type supporting:)Supporting || ||! Dues Paid:||(:update checkbox dues_paid 1:) || ||! Payment ID:||(:update text payment_id size=20:) || ||! Hours Pledged:||(:update text hours_pledged value=5 size=3 mask=###:) || ||! Notes:||(:update textarea notes rows=3 cols=30:) || (:update submit value="Submit Changes":) (:update end:) If the above form is loaded with a memberid specified (for example by a SelectQuery), it will automatically pull up that member's information and display it -- even the radio buttons will display the stored information -- and any changes submitted will be stored in the database. If no memberid is specified, the form will be blank and a new membership record can be inserted (assuming that memberid is an auto-increment field).
The Now suppose we want to let the users update their own e-mail addresses. Just set $UpdateUserId = 'user_id' (near the top of the updateform.php file), and write a form like the one below. The current wiki user's own information will be displayed in the form, and no user will be able to modify any other user's information. (:updateform table=people fields=email where=user_id:) E-mail address: (:update text email:) (:update submit:)(:update end:) Note that this form does not include the peopleid field, which we saw in the previous example was the primary key for this table. Leaving the primary key field out of the form entirely is the best way to ensure that it doesn't get changed or compromised. Pitfalls to watch out for:
Release Notes
2006-05-14 version 1.0 posted. 2006-07-19 version 1.1: minor bug fix; 'default', 'null', and 'redirect' parameters added. Thanks to Helge Larsen for his contributions!! 2006-07-20 added null values for select boxes (drop-down menus) 2006-07-29 minor bug fixes, added timestamp capability. 2006-08-28 version 1.2: numerous bug fixes, input masks, deletion, automatic tabindexing. 2006-02-08 version 1.3: provides user-query functionality to SelectQuery. Future PlansThe DataQuery recipe, in combination with ZAP, is designed to replace UpdateForm. Once the DataPlates recipe is completed (spring 2007), that combination should be even easier to use than UpdateForm (whereas now it is harder). Comments2006-12-19 by GhostRider? Hi, I was trying to use updateform on test site, and probably hit a bug. Test url was like: http://blablah/~testuser/pmwiki.php(approve links). After creating a really simple form on page http://blahblah/~testuser/pmwiki.php/Main/Submit(approve links), 'submit' button was trying to submit data on http://blahblah/Main/Submit(approve links). I dig a bit in code, and found out the following code which is doing that nasty thing:
# (:update form:)
SDVA($UpdateTags['form'], array(
':args' => array('action', 'method', 'table', 'fields', 'required', 'where', 'tabindex'),
':html' => "<form \$UpdateFormArgs>",
'action' => '/'.$pagename,
'method' => 'post'));
action seems wrong, as it is supposed to IMHO be:
It fixed my problem. Think it might be useful to others, so I submit. Regards, Thanks, GhostRider. I've made that change in the current version. Ben Stallings February 08, 2007, at 10:39 AM 2007-31-01 by GhostRider? Another observation here, after a successfull submission to db, Update Form displays information about it, but fields are still filled with previously submitted values which I find quite annoying. Is it possible to reset form after successfull submission ? Well, you have two options... you can either provide a link to the form page (which will reset the form because no record is specified), or you can have a separate form for data entry which uses input tags instead of update tags. Update tags will always display the current record when a record is specified. Sorry for the confusion. Ben Stallings February 08, 2007, at 10:39 AM Input tags instead of update tags did the thing, thank you :) 2007-03-03 by GhostRider? 2007-03-04 by GhostRider? Another question, hope it won't bother you much ;). I'm trying to get the following: - perform a query to db (using e.g. SelectQuery) - provide 'edit this row' link inside the query above like this:
I need to provide a way for my users to edit entries in db. It's quite tricky I think. Not tricky at all! SelectQuery is designed to do just that. I'll address your question on the SelectQuery page. Ben Stallings March 04, 2007, at 10:33 AM Is there an easy way to update or add one form field (entered or selected by user) to other fields of other tables than the one the form users see? I.e. can I do sort of hidden add/'insert into' actions that are run with the same submit button, within the same form? And if so, could you provide example code? Also, could you show an example where in one form you obtain data from one table, and add that selected data to a different table? I.e. do cross-table copy-paste like actions. I hope it can be done using UpdateForm (and maybe SelectQuery?), but I'm tempted to abandon pmwiki for this entirely. By the way, the %center% tag does not seem to work in front of Submit buttons, or am I missing something? UpdateForm as it currently stands has no ability to rename fields, so you can only save incoming data to a table field with the same name as the form field it was submitted in. However, if you have fields with the same names in more than one table, you can save to multiple tables like this: (:update form table=tblPlants fields="plant_id,common_name,scientific_name" where=plant_id:) (:update hidden plant_id:)(:update hidden change_id:) Common Name: (:update text common_name:) Scientific Name: (:update text scientific name:) (:update end:) (:update form table=chgPlants fields="plant_id,common_name,scientific_name" where=change_id:) (:update end:) In order to save incoming data to a field with a different name, you would have to either use a form processor like ZAP to rename the fields (and then use DataQuery instead of UpdateForm) or add a feature to UpdateForm so that you could use a syntax like (:update form table=tblPlants fields="plant_id AS id":) If you need help with that, let me know. Ben Stallings April 17, 2008, at 09:07 AM Regarding your other questions, if you want to pull data from a SelectQuery, display it in a form, and upon submitting that form save the data to another table, you would do something along the lines of (:selectquery columns=firstname tables=users options=userid display=custom:)
(:update form table=losers fields=nickname where=loser_id:)
Your Nickname: (:input text nickname "{`firstname`}":)
(:update submit:)
(:update end:)
Note I am using an input rather than an update for the text field, so that the value from the SelectQuery will be used instead of the one from the UpdateForm. Depending on what you have in mind, you might use an update field instead. To center the submit button (or anything else), if %center% doesn't work, use >>center<< (:update submit:) >><< Hope this helps. Ben Stallings April 18, 2008, at 01:43 PM See AlsoContributors |