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
Related
I'm fairly new to cakephp, so I may just be setting things up wrong here.
I have created a simple blog with comments and posts (among other things).
I can add Comments while viewing a Post which submits back to the Comments controller (/controllers/comments/add).
The problem that I am running into is that when there are validation errors, it displays them in the /views/comments/add view, rather than the view where I was adding the comment /views/posts/view.
This has to be a pretty common thing to do I'd think, where am I going wrong?
You can ask the add method of the comments controller to render a different view:
$this->render('/Posts/view');
But then of course you'll need to make sure all the data that the 'Posts/view/' file needs is collected and set by the add method of the Comments controller.
Instead, what I would do is just make the comment form submit via AJAX (you know about AJAX?). That way, you can render the Comments/add view (or the appropriate part of it) without refreshing the rest of the page.
Of course, users with Javascript disabled will still have to go to a different page to correct their errors. But that shouldn't happen often, and you can always just redirect them back to the Posts page once they successfully submit their comment.
If you're new to CakePHP, and you're going to use AJAX, you'll probably want to use something like this somewhere:
if ($this->request->is('ajax')) {
$this->render('/Elements/ajax_comment_form');
}
// If it's not AJAX it'll fall through and show the regular comment add.ctp view
Ive run into a little problem with an application im trying to write with CodeIgniter, basically i want to have a login form on each page up the very top of the site, but im finding it difficult to figure out the logic with the validation function.
From my understanding, the validation rules ( set_rules ) have to be set from the controller, now if i want a login form on each page, does this mean i have to set the rules on each and every controller i write? this seems a little odd. can i set the validation rules from inside the view?
What i have at the moment is one view for the login box, which i call from my view with the
<?php $this->load->view('includes/members_login'); ?>
command.
Any help or guidance on this would be great .... im quite stuck.
Cheers,
No, you only have to set the rules in the controller function that recieves/processes the login form. I generally keep a dedicated "Auth" controller to execute related operations like login/logout/reset password/etc...
for layout, you can just include it in the consistant header, but just point the form at your controller/function that processes the login.
For login forms though, I'm not sure why you'd want to "validate" them. Either the user/pass matches up or it doesn't.
One idea that comes on my mind is to create basic layout for all of your pages which will load lets say 5,6 other files and build view for each page.
Some of these parts will be called on every page, like header, navigation... so you can use your login form in these parts and it will be loaded on every request.
I think you should try something like AJAX via javascript to authenticate any user login. Basically the login button would be handled by an onclick event which would get the details of the button and pass it to your "Auth" (or Login or maybe UserAuth - up to you to decide) controller which would do the validation..
If you really want the login form on every page, you could create your own My_Controller and do the form validation in the constructor. Alternatively, as you said, you can do it in the view also. CI doesn't force adherence to MVC. If putting the code into your view would make for quicker development and easier maintenance, there is no reason not to do so.
I have a custom MVC application/framework where each action is a function inside of a controller class.
I have a signup action which renders a view with a form requesting user details. On submit it posts to a processSignup action that validates the data and either inserts the user into the database and redirects to a success page or needs to redisplay the original view/form with the errors.
The signup action runs several queries and hands off a variety of data to the view. E.g. it needs to get a list of available countries that the user can choose in a drop-down, retrieve a list of suggested usernames based on the name they entered on a previous form, and retrieve other data from a model.
I'm trying to find out how I can avoid repeating all these queries and the render of the view in my processSignup action in the event of an error. What's the standard way to handle these situations? The signup action receives POST data from a previous form so I can't have the signup form submit to itself and branch based on GET vs POST.
I could just call the signup function directly and have it receive an optional parameter to differentiate between normal requests and ones for invalid forms but that seems hackish. How do other frameworks handle this scenario? I'm using PHP but this is more of a high-level question than one specific to the language.
Avoiding duplicate code certainly isn't unique to MVC frameworks. The standard approach would be to simply create a private function that both signup and processSignup call before rendering the view. Something like:
private function setCommonVars()
{
// set country, username arrays, etc...
}
As far as rendering the signup view, the flexible thing about MVC is that you can reuse views. Your framework should have a way of explicitly choosing a view within a controller method (e.g., $this->view = 'signup'). That way, if an error occurs in processSignup, you can choose the signup view before rendering.
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.
I'm using the Zend Framework and I'm about to hack up some of my controller code to do something that seems like there should be a pattern for already.
Currently when I only have one form, the form's action points back to the same action and controller as the one that generated the page. The controller's action function then verifies the form and if verification succeeds, does the desired action. If verification fails, it doesn't perform the action and the page is re-generated using the form that was validated so error messages appear in the correct place.
My situation now is that I have an action/controller that creates two forms and a list of items to the view for display. The view displays the list (say, for example, a list of users) and shows the forms (add user and create role - just as an example). What is the correct "Zend Framework" way to handle this? Should each of the forms' actions be pointing back to the same action/controller? If so, how does one handle validation?
My guess (and how I'm going to proceed for now) is to point both forms back to the controller, figure out which form was submitted, validate that form only, perform action on validation, or re-generate view on failure.
Yes. Let each form have different submit name and validate them based on that. But beware, when you validate wrong form, the error messages will appear ;) So test carefully.
You can submit the two forms to the two different actions of the same controller, and extract the list generation to a third method, and call it from indexAction, and the both form submission actions.