I usually instantiate my forms in an action and that's where I process them when they're submitted. I then pass them on to the view and output them there as usual.
This form (a search box) is different because it's not part of a single page. It has to be visible everywhere. I've made it part of the template layout.phtml and instantiated and accessed it right there.
$search = new SearchForm();
echo $search;
The form prints out fine but the question now is where do I handle this form. I usually have processing code like this in the action..
if ($this->_request->isPost()) {
//and form is valid
//process the data
}
but since this form is universal, there's no action for it. How should I handle this?
Should I:
create a dummy action for it (which doesn't make sense because the form is everywhere)
or should I put the processing code right into the layout.phtml (which I think is bad MVC practice because I'm now mixing processing the form with the view).
What should I do? Any advice on this?
Surely the search will need some processing code to build up the results, so I would create this action somewhere generic (like on your IndexController) and point the form at that. Even if the form is on every page it's perfectly fine for you to point it at a specific URL like /search/.
Otherwise you could create a controller plugin that checks the request to see if it has been submitted, and then runs the processing code.
Related
I have a question related to form submission done in PHP application that's built in MVC architecture (self-written framework).
All examples that I've seen so far (including existing back-end frameworks) work this way that once form for adding record to database is submitted then certain method of controller is executed [say i.e. addRecord()], which triggers method of appropriate model. If everything goes OK then record is added and controller's method [addRecord() in this example] renders view of "index" page that displays table with records from database.
What I would like to achieve is to render view with form used to add records (the same that I used to add first record) instead of "index". Obviously I can do it easily by just rendering appropriate view from addRecord() (view with the form).
But the tricky point is when you check url you'll see the following:
The first time you enter it will be i.e.
http://project_name/my_controller/create
Once first form was submietted and you return to the view from addRecord() method then url will be:
http://project_name/my_controller/addRecord
What I would like to see is return to the original url, that is http://project_name/my_controller/create
Not sure if this is clear?
PS. Of course I could use AJAX call for form submission (that way I will stay at the same page) but perhaps it's possible to achieve the same without AJAX.
Thanks in advance,
On the controller you will want to submit to the addRecord route and do the processing. Have a check to make sure it was successful and on successful submission you can redirect back to the create route.
It is hard to give an example since you are using a custom made framework. I use slim which has a redirect method for a route. If what you have made does not have something like that then using should do the trick.
header('Location: '.$createUrl);
die(); //or exit
I am new to developing PHP forms and currently trying to understand and learn how they are processed. If I understand it correctly, there are two approaches to using the "Action" attribute.
Method A: Use a separate PHP file to process the form. So in your first file (Form.php), you have the code for the form and submit button. Then in the ProcessForm.php file, you put all of your code for validating the data. In this case, you define the form as
<form method="post" action="ProcessForm.php" >
Method B: Use one PHP file for everything, including the code for the form, submit button, and all validation stuff (including output of error messages if form fields aren't entered properly). Here, you define the the form as
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Right now, I don't understand if one of these methods is more correct or why you would use one vs the other.
I see a form as having four components: HTML for the form, PHP for connecting to MySQL, PHP for input validation/cleaning/error printout, and PHP for moving the data into the MySQL database. I want my form to be able to (upon submitting) work as follows:
If there are one or more errors in the submission process, stay on the same page (stop the submit process) and display relevant error messages, with the fields all still populated (as opposed to blank).
If there are no errors in the submission process, move the data into MySQL, and then display a blank page that says "your data has been submitted successfully" and a link back to my homepage.
Currently I am using Method B, and have implemented #1 above successfully. But I haven't achieved #2. So after this long story, my question is this: Where am I supposed to put those four components? In one file or two, and why?
Neither method is "more correct"; both are just as valid, the one you choose completely depends on the UX you are trying to achieve. Where you are supposed to put the four components depends on whether you are using method A or B.
For method A
If the form is on one page, and you're going to be submitting the data to another page via the action="example.php" attribute, the HTML for the form should (obviously) be on the first page, while everything else should be on the second (example.php) page (all the PHP and SQL). If there's a validation error, you can use header(Location: firstpage.php?error=something) to return users to the original page to fix their mistake.
For method B
If you're doing everything on one page (by putting action="<?php echo $_SERVER["PHP_SELF"]; ?>" or simply action="", both of which do the exact same thing), you should do the validation when a user submits the form on that one page, and if there are no validation errors, insert the data into the database and redirect the user using PHP's header() function.
As you're using method B, this is my more detailed step-by-step process of how I would handle such a form. In the example, firstpage.php is the page a user starts on, and secondpage.php is the page a user is taken to if all the information is correct.
Present the user with your form.
When a user submits the form, the data is submitted via POST or GET (depending on whether you want this information accessible via the URL. If you're not sure, use POST) to firstpage.php where the following PHP is:
PHP:
<?php
if (isset($_POST['submit']) {
// Some validation function
if (do_validation()) {
// Information is valid, insert into db
header(Location: secondpage.php);
die();
}
else {
echo "Error; the information you submitted is not valid.";
}
}
?>
When the user ends up on secondpage.php, you can tell them that the form was successfully submitted.
If you are posting to the script that generates the form itself then you don't even need an action. So method 3 is:
<form method="post">
which is the best version since it will not break and makes it clear that one script renders and handles the post for the form.
Neither of your other methods is ideal. Really you should be looking at (Smarty or something similar) to let you template the HTML and separate the display from the logic. Having said that both options 1 & 2 are perfectly acceptable - if you choose not to use the (superior) option 3 from above.
I can't speak to a "Best Practice", but of the 4 "Components" you mentioned, I think a missing key item is client-side validation as well (javascript typically). This saves you the "round trip" overhead of processing a form that could have already been validated before submitting to the server to handle.
With that being said (and because it's the approach I use), you'll be incorporating some javascript, so what I do is use javascript to validate my fields "on submit" (I override the form's default submit with a javascript event handler), then, if it validates, perform the submit. I do this with ajax, or you can use standard javascript to submit the form. You can even use javascript to set the "action" attribute dynamically (assuming you need to - see #Paul's reasoning why you may not need to).
The php file it submits to typically does 0 presentation work. It connects to the database, saves the "post'ed" info, closes the connection, and returns a status (which is typically why I like ajax because it's easier for me to handle that status response). Based on the status response, you can display an error message (like an alert, a bootstrap modal or info alert, etc.) or a success message/redirect.
While my answer does not offer code, I think the methodology above will serve you better based on your question. The "how" is the easy part once you understand the steps you want to take.
I currently have a site I built using jquery/php/PDO/mysql.
I use classes for most functions, including database, logins, content, etc...
I am wanting to change my forms over to jquery's ajax calls. But there's where my problems start. With the ajax call, I can't call a php function in the ajax post url. Heres the heirarchy Im using;
->content.php (form resides in a function named content.)
->process.php (post checks and then a call to add content from class)
->class.content.php (insert vars into db)
Once form is submitted, it goes to process.php which contains checks and then a class call to add content.
While this hierarchy seems to be the most used for ajax, it causes path issues. It breaks my db connection, my config connection, etc...
All I really want is to add ajax forms. But I don't want to rewrite my whole site. Any suggestions?
It sounds like process.php was previously included in content.php but now you're trying to submit to it directly. However, process.php was dependant upon the configuration variables, database connection etc. which was included in content.php and accessible by being included within that page.
I think you need to make a new page which includes the same other files and has the same initialisation code as content.php, except it doesn't output the form and instead just includes process.php, then submit to the new page.
Hard to say for sure without code though.
I have a situation where I have several ways to perform the same activity in my php web app.
There is the "Manage Widgets" section of the app which has a form for creating new widgets and a list of existing widgets.
Then somewhere else in the app there is a button that pops up a dialog to add a new widget.
Then on the home page of the app there is another place where a form is embedded to add a widget (think home page portal).
My question is: What is the best practice for this? In this case all of the forms will be essentially the same. So my first instinct is to use the same code for all three of these scenarios. On the other hand, space on the home page could be smaller and layouts may have to differ between the three.
So even though it would be repetition, is it better to duplicate this form 3 times (there is a proper model layer, so the duplicated code would not include the logic to add/edit the widget)? Or try to force a single view in all of these scenarios? Both seem wrong to me and I am hoping for some ideas to discover some sort of middle ground.
One approach would be to have the markup (not the styles) for the form as a standalone file, which can then be included from anywhere you like.
You can then use AJAX to submit the form to a specific PHP script that handles the form submission and returns a meaningful JSON response. You can then display and style this JSON response on the page in question.
This way you have a single form (that can be styled differently) and a single handler for any view that's required to use the form.
i mean, the best way is compose form from other forms (Dont repeat yourself). You can use different templates for same form to change appearance of final form.
For example/idea you can check forms what is used in Nette Framework (http://doc.nette.org/en/forms)
T.
If you are just changing the styles, not the markup, I think the best approach is to add a specific class to the form element and then use Javascript (not Ajax, justa Javascript) to alternate between these clases as you need.
If your application do not use Ajax at all and you just generate web pages with PHP, is a simple matter of decide which class you form shoud have.
In CSS, you do something like this:
form.main { ... }
/* main form rules */
form.other { ... }
/* other form rules */
A very basic question. I have a form in one file form.php, I post it to another file processForm.php which does the server-side validation and processing. I am not using any framework.
Now, in case of form validation failure, I need to display the form again with all the values prefilled, without using a javascript history.back() from the processForm.php. What is the clean and proper way to do this so that I have all the posted values available again in form.php and can prefill them?
This is easy if the form submission happens to the same page, but this is how I got this and I cannot make the submission into the same page. So what would you do? Store the values in session? Curl post? Send the values using GET to form.php?
Why or why not? Please mention pros and cons.
Go read up on the MVC pattern.
You can't implement an interactive program without implementing a model, a view and a controller - the point is that your code should be structured to implement each of the three concerns as a single entity, be that as functions (or function trees), classes (or class trees) or files. And the three components within the pattern should be structurally grouped.
So if you want to the user to arrive at (say) second page after successfully filling in a form at first page, but to stay on first page when the form fails the validation, then a simple way to implement this would be to have first page implement the model view and controller, i.e. to both populate/generate the form and be the target for the form. Then if it receives a valid request sent from the form, send a redirect to second page.
This avoids the need for each page to load and process the MVC code for the preceding page as well as the current one - although that approach reduces the number of round trips to the browser which can help with performance.
NB using POST does not preclude the use of variables in the URL - indeed, I recommend using GET variables to indicate the data you wish to manipulate and POST variables to show how they should be manipulated.