How to check multiple form submission with PHP? - 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).

Related

Laravel redirecting back to list after submitting create form

Maybe I'm missing something but I can't figure out how to do this.
I have a index view that lists all the records from my tiers table. The page has a "Create New Tier" button that displays a form. The user enters the data for the new tier and hits the submit button. In my TierController I have the following:
public function store()
{
//
$data = Input::all();
$tier = new Tier();
$tier->name=$data['name'];
$tier->price = $data['price'];
$tier->save();
return Redirect::back()->with('message',"Tier created successfully.");
}
This takes me back to the empty create form and displays the message but the user has to press the back button to return to the index view which doesn't show the new data until I hit refresh. I would like to have the system automatically return to the index view after the submit button is clicked with the refreshed data.
I know that I can do a Redirect::to('tiers.index')->with('message','Tier created successfully') but the problem I have with that is then the browser history looks like
tier.index -> tier.create -> tier.index
This then is very confusing for the user when they do hit the back button as the create view shows up and freaks them out.
Is there a way to do a Redirect::back (or something) that would not leave the tier.create view in the history and also refresh the index data?
Thanks
I don't think you can manipulate the user's browsing history without resorting to Javascript or something. Certainly not with Laravel alone. So, don't. You're overthinking this. Why do you care so much about what's in the browser's history? And why would you want to manipulate it so that it doesn't reflect the pages the user actually went through? It sort of defeats the purpose of having a history...
If your app's navigation is sufficiently intuitive and familiar, the user won't feel the need to use the native browser's back / forward buttons. Don't assume your users will make the most basic browsing mistakes unless you have data to back that up.
Having said that, conventions don't give you much choice in this matter: generally you either lead the user back to the index -- i.e. Redirect::route('tiers.index') -- or to the newly created item -- i.e. Redirect::route('tiers.show', $tier->id). Both are perfectly acceptable and surely within the user's expected outcome.
If tiers are something the user can only add within certain limits (one per user, one per category, once a day, etc), then I'd attempt to redirect him away from the create page, preventing him from filling out a fresh form which won't ever pass validation. Otherwise, chose one of the pages above and move on to your next development challenge.

Making a multi-step selection process with different outcome for each page

On any given page (It's used site-wide for different purposes) I'd like to call a function getMyForm() or something similar and this would render a several step selection process for a product. We only have this one product but it is quite a complex selection process.
If I wanted to implement this on one page only it would be fairly simple... but I'd like this selection process to be available on different pages, and it seems silly for me to recreate the form for each page used when it's only really the outcome after the selection process that will change for each.
How would I go about achieving this:
Should I have the form on it's own page anyway then link to it at the beginning of the selection process and redirect to the appropriate page after selection depending on the page the user first came from?
Use a service container or similar to render the form on the specific page, then use session attributes/variables to track which step the user is currently on, and refresh the current page after each selection.
Something completely different?
Additional stuff:
I want this to be functional without javascript/jQuery, but this
would be a nice addition in future so I don't want to rule it out if
possible.
The selection process is dependent on what was selected in the
previous step, so I can't just render the whole form in step one, and
some kind of refresh will be required.
First, i'd say you can't completely avoid javascript your selection process, if only for triggering change event on your selectors. Having user to manually trigger page refresh through some button doesn't seem like a good idea.
But if you're so inclined, you need to create a form controller with form builder, there just check a request and render a form accordingly.
For example, if no request is supplied it renders a starting form contains only one select and a submit button, and its action is simple submit to the same page. Main page controller includes a form controller, so form controller gets a request and renders second part and so on...

PHP5 - wizard style submission of data

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

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.

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.

Categories