Form that spans many pages - php

How do I create a form that spans over multiple pages? I would like to ask a large amount of questions, and based on the answers of previous questions, new specific questions will be asked.

Traditional method: store all the previous answers to questions in <input type="hidden"> fields on subsequent pages, so that the last form contains the entire submission (only not all visible). Drawback: file uploads are annoying to remember, amount of data can get large.
Common method: throw answers-so-far into the session or cookies as you go along, picking them out at the end. Drawback: concurrent operations end up with unpredictable conflicting results. File uploads still annoying. I would avoid cookie/session storage solutions for this.
Modern method: have a simple (long) single form, but use JavaScript to show only part of it at once. On clicking ‘Next’ you simply hide the previous page worth of content and show the next. The last button is the real submit button.

There are several ways to do this:
Incrementally populate a database, submit by submit
Keep all form fields on every page, but hide (<input type='hidden' ...>) the ones that shouldn't show up (as #Trufa suggests in another answer)
Accumulate an object that's persisted implicitly in the session (depends on your server architecture)
Accumulate stuff in one or more cookies (seems icky by I list it for completeness)
If you wanted to be super-trendy, you could accumulate information in HTML5 client-side storage. Of course that'd rule out older Microsoft browsers.

There isn't such a thing as a single form spanning multiple pages: each page/form is independent of the others.
If you somehow keep track of what has already been entered (possibly in session variables), then you can just display the new questions in a new form until you have all the data you want.

I'm assuming that by your question, as there is no such thing as a multiple page form, you mean how do you build up a set of answers from a user by using multiple pages, each containing a form.
The mechanism PHP supplies for such things is the session mechanism. You'd build up the set of answers in the session as the user submits each page, and when you have a complete set the full set of answers in the session gets committed to the database.
This isn't the only approach of course, you could also incrementally add the data to the database on each page submit, but then you will end up with partial answer sets where people have only done the first page or first few pages and then abandoned it. You'd have to write code to handle these partial submissions.

Related

best design practice in PHP for navigating from one form to another

I have an application in which I display a form so a user can search for client records based on last name. After entering search parameters, the record or records (there could be multiple clients with the same last name) are displayed. I then want the user to be able to select a client record, possibly with a radio button, and hit one of two buttons: Display details, or Create Reservation. The Display Details button should cause a new display with details of the selected record. The Create Reservation button should cause a new form, with its own handling, to be displayed.
Now, I know I can set things up according to this login
<?php
if (display button was pressed)
{
php code to retrieve more data and display details
}
else if (create reservation button was pressed)
{
php code to generate and display the reservation form, with appropriate handling
}
?>
display the original form with the search results
The problem is, I end up with really ugly, hard to read code because the php code to generate and display the reservation form is lengthy, and needs its own validation, database interaction, and form handling. The code, to my Java-oriented eye, looks ugly and non-modular. Plus, the code for handling the reservation form is icky, with lots of flag setting to determine if we are in form entry mode or form handling mode. I would like a much cleaner way to do this. So my question is, what is the best practice for handling the situation where there are multiple buttons and the action associated with each button is complex?
I could call a function, obviously, but I still end up with the ugly flags determining which state the script is in (are we displaying the reservation form or handling it?). I could create another php file and include it, but the ugliness persists. Or, I could use header, and pass the client record id in a session variable to the new php script. But that would mean a second, unnecessary retrieve from the database to get the client information again.
All the code examples I see on the web show very simple processing after a form button is pressed. What is the best way to do complex processing and displaying a second form based on a button press?
Have you considered using a framework like Laravel for your site. It would seem to me that you must be doing this "manually". With the complexities you described, having a system with routes and "build-in" functionality (like Eloquent ORM) might serve to simplify things for you.
I would go for using ajax and a rich jQuery plugin (or some other framework) to do what you want.
Basically you will handle lists and the functionality that you mentioned with the php reading data and jQuery scripts to dysplay it. And the information that you have to show would be through ajax. Or when you want to edit.
Here is a cleaner example of what you need:
http://jqueryui.com/dialog/#modal-form

PHP Inserting row into MySQL - Which method is more appropriate?

There are two most notable ways of inserting a row into a MySQL database using PHP:
Create a single PHP file which uses a loop to detect whether isset($_POST['submit_button'] has been submitted, and if the form has not been submitted then display the HTML form. If the form has been submitted, during the loop insert the data into the MySQL table.
Create the HTML form on page1.html and when the form is submitted parse the data and insert into the MySQL table on page2.php.
Both methods work perfectly fine - however, based on your own opinion, is one better than the other (such as security, maintainability etc...)?
Given the choice, I would choose neither. Instead I would opt for the Post-Redirect-Get (PRG) pattern, by which the form posts to a secondary page which only processes the input, but produces no output itself. Upon successful or unsuccessful completion of processing, the script redirects to a final page, which may be the original form page to display messages, errors, or request resubmission.
Typically, session variables would be used to pass information back to the final redirection point, whether that means values from $_POST to repopulate a form, or success/error codes.
This goes a long way toward solving issues with accidental form resubmission via the browser back button.
Your second method of posting to a different page is like an incomplete form of PRG.
I can say that from a usability standpoint, I prefer the first method, because it allows you to create sticky forms, i.e.
<input id="foo" name="foo" value="<?php echo $_POST['foo']; ?>" />
For cases where it is practical, I'd try to get away from having a second user pageload at all. page1.html submits via AJAX to a web service provided via page2.php. And yes, there are many cases where this isn't appropriate, but the most common patterns I can think of where the form handler is simply inserting rows into a database are well suited to an AJAX submit.

What is the most sensible mechanism by which to maintain/resubmit POST variables between pages?

Potentially silly question, but I'm looking for the most sensible mechanism by which to maintain and "resubmit" POST variables. Basically the workflow is as follows:
STEP 1) Select charges to pay, and enter payment info
STEP 2) Display confirmation/summary page with option to "PROCEED WITH PAYMENT" or "EDIT INFO"
STEP 3) Return to "edit" form or send data to be processed.
I'm currently using a single page for all actions (just one giant SWITCH based on an "action" var) and submitting the information. The problem I'm having is that between the "confirmation page" and either option, I'm losing my POST data (which I understand). What I need now is a way to preserve that data without duplicating the input fields in each SWITCH section. Below are a few options I've considered. Feel free to comment on the merits or stupidity of each:
1) serialize it to a SESSION var then unserialize it?
2) simply key/value it into a SESSION array?
3) recreate every INPUT for each "form" presented and refill the values
4) put the SWITCH inside a single form and only display relevant portions
5) I would handle it all with Javascript (sort of a faux submission technique), but there is currently processing that occurs between the initial form and the summary and ajaxifying that would be a beast atm.
What's the recommended course of action for the classic INPUT->CONFIRM->PROCESS process? It'd be amazing if I were just missing something über obvious/simple.
FYI: Currently using PHP 5.1.6
Best!
EDIT 1
Clearly using individual pages for the various functionality is desired. The only reason I'm not using separate pages is because other pages are dependent on this one page and management won't allow a clean break at this point in time. It was poorly constructed over 3 years ago and is just now being partially addressed.
At this point I'm using:
foreach($_POST as $key=>$value)
<input type="hidden">.......
...in order to achieve the desired goal.
serialize it to a SESSION var then unserialize it?
simply key/value it into a SESSION array?
Very bad. Clicking "Confirm" should always confirm what is being displayed on the page, not what happens to be in some nebulous session stored on some server somewhere (which may not be the same server that served the previous request if you have a load-balanced cluster).
There are plenty of websites out there which will try to detect when you press the back button and display an error page, probably for related reasons.
recreate every INPUT for each "form" presented and refill the values
You need to do this anyway for the "go back to editing" page.
What's hard about <input type="hidden" ... /> in a loop on the confirmation page?
put the SWITCH inside a single form and only display relevant portions
You mean stick all the inputs in display:none for the confirmation page? That feels ugly too.
Firstly, breaking it up into multiple pages might be a good solution but I don't know your specific needs.
1 and 2 are bad ideas. That being said, I don't know what you gain out of serializing and unserializing to a session variable that you don't get with simple key value pairs in the session. Session management gets pretty hairy if you are running multiple servers behind load balancers
4 Just sounds odd. I don't know what the switch gives you here. If you ever have to use conditional logic to display a completely different functionality to the user, it is probably better of being on a separate page.
5 Faux submission? Just sounds like a kludge. You mean send the data back to the server and return the same data back and display the confirmation div? Why not just use Javascript and manipulate the DOM at that point? Nevertheless bad idea.
Just repost the parameters to the confirmation form and populate the confirmation fields accordingly. (Standard process). I think that is what 3 is but I suggest you use a different page for each step. Just keeps things clean.
I actually ended up using
<?$forward_post_data = base64_encode(serialize($_POST));?>
<input type="hidden" value="<?=$forward_post_data?>"/>
...I then decode it as necessary. It works perfectly.

How to store the form data in a MULTIPAGE form?

I am trying to develop a registration page which involves three separate information.
First Page will get contact details
Second page - working details
Third page - study details.
How to keep the form data of the previous pages before posting the form?
You could do it with Ajax - multiple divs and hide/show the appropriate ones.
Or you could POST each page and save the data in the $_SESSION global variable until all pages are complete. Then save it all to the database.
While the other answers are certainly good ideas, you may also want to consider persisting the intermediate data to your database between each page. So, submitting the first page would create the new row, with the columns relating to contact details populated, and a status column set to a value indicating that the submission is not yet complete.
The second page would update that record in the database. The third page would also update the record, as well as the status flag to indicate the submission is complete.
The main benefit to this is that the user can walk away after the first (or second) page, and then return to it later, even if he had closed his browser and his session had expired. (As long as he has a unique URL to return).
This approach might not have a lot of benefit if you are only collecting three pages of data, but if you had many pages, the ability to leave and return later might be more important.
You should take a look at http://jqueryui.com/demos/tabs/, it should be able to do what you need.
While shifting to another page, you just put the values of first page variable in sessions, then you can access the value of previous page at any page, then post the value to the database query. In this way, you can use the use the value of first page at third page, up to when browser is open. As the browser close then variable lost their values.
Back in the day, I would've put hidden fields for all of the previous pages in each subsequent page, so the final submit would have everything... i.e.
Now, I would probably only have one actual page.. with multiple steps implemented by showing/hiding div's and collecting all of the data in one big form, broken up visually for the user... and if I was feeling especially frisky, with frequent validation and final submission through ajax.

How to select items from multiple pages using PHP, HTML, etc?

On a site that I'm working on, I'm displaying results from a database query. Each page shows 15 results, so if there are 45 results returned from the query, they will be displayed on 3 separate pages, each containing 15 results.
I want the user to be able to select any number of items from the first page, then switch to the other pages and select items from those pages as well, while still remembering the items that were selected on the first page. (Eventually, when the user has selected all the items, he will click a Submit button.) So if the user navigates back to the first page, the items that he checked should show up as being selected. On pages that I've seen on the Web, when the user navigates back to the first page, all the checkboxes are cleared again (which is not what I want).
Any ideas on the best way to achieve this? Thanks.
Remembering the selections in-between pages means you have some state that needs storing somewhere. There are a variety of ways to do it, but it boils down to one of these...
Keep it on the client (e.g. cookies)
Keep it on the server (e.g. in a database)
Keep sending it backwards and forwards (e.g. hidden form field, as in ASP.NET viewstate)
A common abstraction offered by platforms such as PHP and ASP.NET is the idea of "session". The actual implementation of session state might be some combination of those 3 possibilities above, and it probably offers the easiest route. I suggest you look at session state in PHP.
use hidden inputs to carry over the results from the previous set
<!-- hidden fields -->
<input type='hidden' name='whatever[]' value='whatever'/>
<!-- checkboxes -->
<input type='checkbox' name='whatever[]' value='whatever'/>
You could do many things.
Save as a JavaScript cookie
Save as a session by using AJAX on each click
Hide each page as a "tab" so they are actually there but just not shown.

Categories