PHP5 - wizard style submission of data - php

I have a multi-step form that I have spread across 4 separate pages - in other words, 4 sections (I chose this method as it would be far too complex to process all my fields on one page). In my MySQL DB I have a table for each of the sections on each page (step1, step2, step3, step4). After submitting the first page I would like to insert my Page1 data to the DB and have it return the Primary Key, which I aim to then post to the next page (step2.php) ... and the same process will follow for Step3 and Step4.
The tables for Step2, Step3 and Step4 in the DB all have a Primary Key (reg_id) which are also all Foreign Keys to step1.reg_id.
I would like some advice/suggestions please on how to:
Post data back to my DB after each page submit (Do I post back to the same page, or have a separate processor page to handle that?)
Redirect to the next page
Pass the reg_id returned from Step1 to the Next Step pages
I am using plain and simple PDO to get my data in MySQL. I admit that I don't have a lot of PHP knowledge to accomplish this as I am too used to the lifecycle of ASP.NET webforms development, hence my asking for your expertise here.
Much appreciated as always!

As Karl said in his comment, it makes the most sense to save the form values as $_SESSION values before redirecting to the next page. The form processor then accesses the values from $_SESSION, just as if you had sent them as $_POST values.
To expand a bit on why this is a bit better, you have to think about what would happen if your users don't just go from page 1 to page 2... to the end of the form in one sitting. What if someone exits the wizard partway through? What if they need to go back and edit values, sometimes multiple times? In short, if your users have a workflow that results in either incomplete forms or the user going back and forth between form pages, you might end up with an awful lot of unnecessary validation and writes to the database.
If you save the form values in the session and only store them in the database when the user completes the entire multi-page form, you remove the possibility of these unnecessary writes to the database.
It also makes it easy for people to go backwards in the form to make edits without breaking your validation which you've indicated is a bit complicated. Ex. suppose a value x on page 1 is related to a value y on page 4. The user gets all the way to page 5 but then decides that they want to go back to page 1 to edit x. Page 1 has access to the session, and therefore has access to both x and y -- you could, for example, warn them if their new x value would make y invalid, or something along those lines.

You can either have 5 seperate pages for this, and pass data between them all.
Page1.php would have the initial form but do no processing, it posts all of its data to page2 onSubmit.
Page2.php would retrieve all the post data from page1.php, store into a database, and retrieve the ID of that and then display a form for the second stage of the wizard. This form onSubmit, sends the ID (in a hidden field) and the form elements to page3.php
Page3.php stores the post data from page2.php, retrieves the ID and displays the next form. Again submitting the hidden ID and form fields, this time to page4.php
You can repeat this step as many times as you have steps in the wizard.
The other way to do this is to have it all in one page. There will be several if statements, that read what data has been sent. A hidden field will keep track of the current step. i.e.
if $step == 1, display the first form (onsubmit sent $step = 2 as hidden field)
if $step == 2 retrieve post data from first form and insert into DB then display the second form (onsubmit send $step = 3 as hidden field)
if $step == 3 retrieve post data from previous form and insert into DB then display the second form (onsubmit send $step = 4 as hidden field)
and so on

Related

How to check multiple form submission with PHP?

I have my own MVC applicaiton where I have 3 main area: model, view, controller.
In the view, I've created a form, to insert some data to the DB. The action is set to the same page and the type is: POST.
In the model, I have some basic checking if the form has been submitted or not. There is an 1 second sleep after that.
In the controller, I'm connecting the view and the model in a very simple way, so they can commuicate between each other.
However a problem is arising, whenever the visitor clicks multiple times on the submit button. Because there is 1 second waiting (it is intentional - so it looke like the system is processing the data), they can click multiple times to the button.
There is an issue with that, because this way, the data gets inserted to the database based on the amount of clicks. If I output a simple word, like "Foo" it will get displayed only 1 time (I guess this is because the page is reloading every time), however the data gets inserted multiple times to the DB.
Is there any way around this issue? My intention was to create a session and check if this is the first submit, else do nothing with the DB. However this didn't work, because the session always got the basic value upon the page load.
Can anyone help me with this issue?
Two options:
Put some javascript on the front-end to disable the button upon being clicked and then submit the form - this is probably the easiest way but you may want to try and leave the front-end as uncluttered as possible.
Set a session variable before you load the page, then when you do the insert delete this session variable immediately after. Before doing the insert you should check for the session variable - if it is set then the insert is allowed, if it is not then it isn't. You may also want to add in code into a master controller (if all your controllers are derived from one master controller) that checks what controller has been called and then if the session variable that is set should be for a different controller then it should be deleted (so it no longer exists if the user goes to a different page without submitting the form).

POST Data Without Form

Basically I have a bunch of data I get from a database and put onto my page in a table. Right now I have the user type in the name, session, etc. in the table and that is sent as post data into the next PHP page, which I then use to lookup more stuff in the DB and so on and so forth.
Obviously that's not a great user experience; it would be much easier to simply CLICK the item in the table and everything gets sent automatically into the next page.
I'm not sure how I'd go about doing this.
My tables are first and last names for now, so if you click a certain row it should go to the next page sending each cell as data.
EDIT: Some examples:
Traditionally you do this with a form
<form method="post" action="pageDataIsGoingTo.php">
to send data to the next page. However, I don't want to do this with a form; but rather when they click a URL and/or button that sends the data. I can "hide" the data from view I suppose, but I still don't know the function to actually go ahead and do that.
Would I make a javascript button/function that sets something in an invisible form?
You can use invisible/hidden form fields.
That might be your best guess.
Javascript would be a good solution if you wanted an ajax POST call, but you want to load other page.
So hidden form fields are your solution.
Parallel with table data.
You need to embed hidden fields and your visible item row within a form
(so each item row contains also a form & hidden form fields and visible submit button,
which you can style with css)
This presuming that your table contains more items which you can choose to send.
Although I would do this with backbone & jquery and do it all in ajax.

PHP Sessions and have "prev" and "next" button and retain values

I have a multi-page form.
I'd like to have a "prev" and "next" button on page 2, 3 and 4 so that if an user in the middle of filling out page 2 can decide to return to page 1 to edit/enter something and be able to still see values on page 2 where he left off.
Is this possible? any pointers/links would be immensely helpful.
(Yes, I have sessions and I can see the sessions after printr but if Im in the middle of page 2 and click backwards, I still dont see these sessions).
Thanks in advance.
Start the session when the user hits page 1. Each page should look in the session to see if there's any data there for that page, and if so, render the form with those values pre-filled. When the user hits either PREV or NEXT, process the form as if they hit submit, but instead of saving the values to (for example) a database, save them to the session. Then redirect to the requested NEXT/PREV page. When the user hits DONE (or whatever) on the last page, pull all the values from the session and process them to your database (or whatever.)
For a simple approach to a "multi-step" form, simply use Javascript. That is what I do.
However, if you want to have a stateful form that remembers data in between pages, you will have to use a session array to track the values entered.
When you fill out a page, the POST array is populated on page2. Serialize the array of post data and store it in a session array. Back on page1, if that session array is set, unserialize the data and echo the values into the right form element.
You can save all of the data in a database as they move to a different page as well as print these values out when the page is loaded. This would still have to be sent to the server via AJAX in the case of a "Previous" link click.
You can put all pages in one html page, then just hide/show the correct pages when they navigate using javascript.
Save all entered data in a session, which would have to be sent to the server via AJAX if it is not submitted through a form the traditional way.

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.

'Previous' Button in HTML/PHP

I thought hours about that problem but I didn't come to any conclusion. My problem here is that I need a 'Previous' Button added to a form. The user should fill out a formular that is splitted up in 13 parts. Every part is an own formular having a 'Next' button for submitting everything to a database and redirecting to the next page.
How do I integrate a 'Previous' button there? ...
I don't if it might be usefull for you to know that I'm using cakePHP, and well I'm pretty new to it.
Store the POST data of each form and the current form index in your session.
When clicking the back button, open form (currentForm - 1) (if that's a valid form index) and populate the fields with formData[currentForm] (assuming currentForm is now the form the back button redirected to)
The question really is, do you want to store each stage of the formula in a record? or do you want to store every stage of the formula in the "transaction"? The difference here is important. What is your relationship with the user? Do they login? are they anonymous? How do you associate their answers from one form entry to the next? If you store each entry in the database, in some chronological way, then simply populate the previous form with the previously entered values; when they click previous. If you do not store the entries and instead utilize a session to retain values between "next" clicks then populate the "previous" form with those values.
I've coded a similar form in classical ASP, see if you can make it work in CakePHP:
I had a 7 step form, step 2-7 have previous buttons. Each step consists of one asp script. All scripts post back to themself. I check the REQUEST_METHOD upon every invocation of the script to see if it was called by GET method or POST. If POST then data is validated, if validated then it is saved. There are three submit buttons on forms that allows user to choose whether he wants to just save the data, save and move to next step or save and move to previous step. Depending on which button was clicked, the user is "redirected" to the previous/next page. This post specifies how to add and handle the previous/next buttons:
Multiple Submit Buttons — Specifying default button

Categories