A really common type of PHP script is an add/edit/delete form. This is typically used in a back-end content management system for an administrator to add/edit/delete information. For example, a news editor with three fields:
- Title
- Date
- Story (HTML)
The administrator will need to be able to add news items, edit existing items and delete items as well.
As imagined, this requires 3 separate form functions:
- Add Function (title,date,story)
- Edit Function (title,date,story)
- Delete Function (id)
To make this form more efficient and easier for the user, a good coding practice is to join parts of these functions. What we end up with is only two user form pages and integrated functions. The initial page will consist of two separate forms:
- Add Form with Title Input Box
- Edit/Delete Form with Select ID Box
The Add form submits to a database insert query and then returns the edit function with the inserted mysql row id. This cuts out the code for making an entire add form and insert code. The Select Box actually only submits to the Edit Button, which the function is self explanatory. Finally, the delete button uses a simple onClick method to append the selected ID onto the URL, by which the page recognizes the GET variable and deletes it. Of course, it’s good practice to always have a confirm delete function, before passing the URL on.
Tricks like these are easy to implement with simple forms, but efficient coding practices are hard to maintain with larger and more dynamic forms. These types of forms take much more time to ensure the correct usability and efficiency are implemented. Take for example a recent form I did for listing an item on an eBay like site. I’ve done plenty of real estate listing forms before, but this one would be used by the general public, not just an administrator. It’s easy to teach an administrator what to do and what not to do, but when coding for the general public, all possibilities must be considered!
A good initial step is to write/think about the usability aspect of the form – that will save you some time! One of the main issues (small, but still an issue) was denying multiple listing adds from a user. Let’s say a user wants to create a new listing. With multiple steps (like on eBay), we can’t just have one big add form, we need to break it up. If we break it up, generally, the first part of the form will add a new row to the database and the remaining parts will update that row. Simple right? Wrong!
The problem here is the ability for users to go back and refresh, which means multiple rows added, which equals a dirty database and a bad user experience. How can we fix that? Well one of the first thoughts was to add a random ID on the initial load of the first part of the form, before anything is added. That ID is added to the database with the first data, and if the back button is pressed, we can check to see if that ID is present. Unfortunately, that solution doesn’t solve the problem entirely. If the user goes back (too far) to the homepage and returns to the initial part of the form, the random ID is different and so it starts a new row in the database. To really solve this problem, we need to thoroughly understand what is happening here.
Users like to go back and forth between pages, which can sometimes drive a programmer nuts! Users do this to check over or edit the data they’ve put in, fair enough. What we need is a system that allows them to jump to any page, see data they’ve put in before, and edit that data. This can get a little tricky when you start including server side error checking, messaging, and splitting the data between the POST data (what they’ve submitted) and what’s already in the database, but we won’t touch on any of that. What we’re interested in here is allowing the user to jump between pages with their data in there. The answer then is to be filling in forms with information that’s already in the database. Where then do we add the database row for which they’ll be using? The answer would be before the form starts! The problem with that though is, again, multiple row adding.
Say the user goes to the add a new listing form, and a row is input into our database with an id returned. Everything is good, the user can jump to any page to update info, except our initial page, because it will add another row. To prevent this from happening, we use an active field in our row, as well as putting the users’ username in there. The active field is defaulted to zero (0) and only is active when the listing is complete (or when the user is done jumping around). When the form starts now, we can then use a session variable to access to the user’s username and lookup to see if there is a listing by that user with active set to zero. If there is (means they’ve refreshed/revisited that page), we’ll use that listing id, and if there isn’t (they just started the form up) we’ll create a new row with the username in it and use that listing id. Everything else falls together, and now a form process with step by step links is available to the user to jump around wherever they want without losing any data.
To implement restrictive step links at the top (they can only click on where they’ve been), you can store what step that listing is on and update it in each subsequent function. Since the user is able to jump around though, you’ll want to make sure that the step only gets updated if the new value is greater that the current database value.
Overall, efficient code and good usability takes great planning.