Codeigniter Form Validation: How to redirect to the previous page if found any validation error? - codeigniter

I am using Codeigniter's validation class to validate my form. Could you please tell me how to redirect to the previous page from controller if found any validation error?
In my controller:
if ($this->form_validation->run() == FALSE){
//**** Here is where I need to redirect
} else {
// code to send data to model...
}

I extended the URL helper for this.
https://github.com/jonathanazulay/CodeIgniter-extensions/blob/master/MY_url_helper.php
In your controller:
$this->load->helper('url');
redirect_back();
Just put the MY_url_helper.php in application/helpers and you're good to go.

UPDATE
You want to post a form, validate it, then show the form again with the validation errors if validation fails, or show something entirely different if validation passes.
The best way to do this is to post a form back to itself. So the action of your form would be action="". This way, in your method, you can check to see if the form was submitted, and determine what to do there:
// in my form method
if ($this->input->post('submit')) // make sure your submit button has a value of submit
{
// the form was submitted, so validate it
if ($this->form_validation->run() == FALSE)
{
$this->load->view('myform');
}
else
{
$this->load->view('formsuccess');
}
}
else
{
// the form wasn't submitted, so we need to see the form
$this->load->view('myform');
}
OLD ANSWER
You can always pass the current URI in a hidden field in the form:
<input name="redirect" type="hidden" value="<?= $this->uri->uri_string() ?>" />
And then redirect if the validation fails:
redirect($this->input->post('redirect'));
Or you can set the redirect url in a flashdata session variable:
// in the method that displays the form
$this->session->set_flashdata('redirect', $this->uri->uri_string());
And then redirect if the validation fails:
redirect($this->session->flashdata('redirect'));

Well, usually you should do like this (pseudocode for now):
if form_validation == false --> the form is either not submitted yet or validation failed --> load the form view;
if form_validation == true --> do the processing.
This means you have to stay within the same controller. Your code should already be doing this behaviour, which is the intended one.
If you still feel the urge to redirect, call the appropriate function:
redirect('updatebatch/get/40','refresh');
// assuming 'updatebatch' is the name of your controller, and 'sundial' just a folder

I have created a function inside a library to create redirects when I need them.
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
class Functions {
public function generateRedirectURL()
{
$CI =& get_instance();
$preURL = parse_url($_SERVER['REQUEST_URI']);
$redirectUrl = array('redirectUrl' => 'http://' . $_SERVER['SERVER_NAME'] . $preURL['path']);
$CI->session->set_userdata($redirectUrl);
}
}
//End of the file
and when you want to create the redirect to that page, just write on the function:
$this->load->library('functions'); //you can put it in the autoloader config
$this->functions->generateRedirectURL();
Then you only need to call:
redirect($this->session->userdata['redirectUrl']);

Related

Laravel back using {{ URL::previous() }} doesn't work if there are validation errors

I want to make a cancel button on a simple CRUD edit form. However it seems that when there are validation errors the cancel button does not work.
I guess because it routes from controller#edit to controller#update the button just goes to controller#edit again instead of the actual previous page. Is this normal or did I do something wrong? How do I make it work?
attendee/edit.blade.php
<div class=pull-right>
{{Form::submit('Update',array('class'=>'btn btn-success'))}}
<a href = "{{URL::previous()}}" class = 'btn btn-warning'>Cancel</a>
</div>
{{ Form::close() }}
routes.php
Route::get('user/attendees', 'UserController#getAttendees');
Route::resource('attendee', 'AttendeeController');
attendee controller
public function edit($id)
{
$user = Auth::user();
if(empty($user->id))
return Redirect::to('/');
//return if attendee doesn't belong to user
if( !($user->attendee->contains($id)) )
return Redirect::to('user/index')->with( 'error', 'attendee id error.' );
$attendee = Attendee::find($id);
return View::make('attendees.edit', compact('attendee'));
}
/**
* Update the specified attendee in storage.
*
* #param int $id
* #return Response
*/
public function update($id)
{
$attendee = Attendee::findOrFail($id);
$validator = Validator::make($data = Input::all(), Attendee::$rules);
if ($validator->fails())
{
return Redirect::back()->withErrors($validator)->withInput()->with('id', $id);
}
$attendee->update($data);
return Redirect::intended();
}
user controller
public function getAttendees()
{
list($user,$redirect) = $this->user->checkAuthAndRedirect('user');
if($redirect){return $redirect;}
// Show the page
return View::make('site/user/attendees/index', compact('user'));
}
It's actually working correctly, it's just the usage that is incorrect.
Take the following:
You submit a form at GET /attendee/edit/{id}
The form takes you to POST /attendee/edit/{id}
You fail validation and are redirected to GET /attendee/edit/{id}
You cannot link to a page using a method other than GET. Your previous route was actually POST /attendee/edit/{id} but the link will always be GET.
Instead, nominate a page to be redirected to, I usually use the index for the section.
I think you should add a hidden input, like this
{!! Form::hidden('redirect_to', old('redirect_to', URL::previous())) !!}
and use this value in your link:
cancel
Redirect::back() doesn't really accomplish the right thing when using the validator provided by Laravel. What I've done before is pass the page to redirect back to as a hidden input in the form, and simply ignore it using Input::except("return"). Here's what I mean:
// On your HTML Form
<input type="hidden" name="return" value="{{ Request::path() }}" />
// In your PHP Controller
$validator = Validator::make($data = Input::except("return"), Attendee::$rules);
if ($validator->fails())
{
return Redirect::to(Input::get("return"))->withErrors($validator)->withInput()->with('id', $id);
}
Hope that can help shed some light. Other options are returning to a higher up, such as instead of attendee/edit/{id} redirect to attendee/edit/, but it all depends on the structure of you website.
I am now using the browser back via JS in onclick. Seems to work:
<a onclick="window.history.back();">Back</a>
I used this jquery for the cancel button.
$(document).ready(function(){
$('a.back').click(function(){
parent.history.back();
return false;
});
});
May you use the Front-End validation to test the input validation without a need to reload the page. So the {{URL::previous()}} won't affected.
The simple way to do that is by using Ajax or validator.js in your Laravel cade.
Here is a full example how to use jquery ajax in Laravel 5 to test the validation, may help:
http://itsolutionstuff.com/post/laravel-5-ajax-request-validation-exampleexample.html

How to repopulate form after form validation and also keep the URI?

I have a problem repopulating my form after validation fails. Problem is my url contains an additional uri which I access by clicking a link. This is what it looks like:
http://www.example.com/admin/trivia/add/5
At first trouble was that the segment 4 of the uri completely disappeared, so even though the validation errors showed and the form was repopulated, I lost my added uri.
Then I found in another question that the solution was to set form open like this:
echo form_open(current_url());
Problem is now it isn't showing any validation errors and the form is not repopulated. Is there a way to achieve this?
This is what my controller looks like:
function add()
{
$data = array('id' => $this->uri->segment(4));
if($_POST)
{
$this->_processForm();
}
$this->load->view('admin/trivia_form', $data);
}
And inside _processForm() I got all the validation rules, error message and redirecting in case success.
[edit] Here is my _processForm() :
function _processForm()
{
$this->load->library('form_validation');
//validation rules go here
//validation error messages
$this->form_validation->set_rules($rules);
$this->form_validation->set_error_delimiters('<div style="color:red">', '</div>');
if ($this->form_validation->run())
{
//get input from form and assign it to array
//save data in DB with model
if($this->madmin->save_trivia($fields))
{
//if save is correct, then redirect
}
else
{
//if not show errors, no redirecting.
}
}//end if validation
}
To keep the same url, you can do all things in a same controller function.
In your controller
function add($id)
{
if($this->input->server('REQUEST_METHOD') === 'POST')// form submitted
{
// do form action code
// redirect if success
}
// do your actual stuff to load. you may get validation error in view file as usual if validation failed
}
to repopulate the form fields you are going to need to reset the field values when submitting it as exampled here and to meke it open the same page you can use redirect() function as bellow:
redirect('trivia/add/5','refresh');
i don't know what you are trying to do, but try this to repopulate the form with the values user entered
<?php
echo form_input('myfield',set_value('myfield'),'placeholder="xyz"');
?>

ZF2 Session not lasting on redirect

My site uses multiple languages and my users can click on flags to set their desired language. When that flag is clicked, a Session should store that information and then i want my controller to redirect the user to another page. This i do with the following code:
<?php
public function setLangAction () {
$oLanguageCookie = new Container('language');
$oLanguageCookie->lang = $this->params ('langvar');
$this->redirect()->toRoute('loadpage', array('page' => 'home'));
}
?>
However, when i print_r($_SESSION) in the indexAction (the action where loadpage routes to), $_SESSION is empty.
Can somebody help me?
Depending where you param comes from you should execute
$this->params()->fromQuery('langvar');
$this->params()->fromPost('langvar');
unless it is a route parameter then you can use either:
$this->params()->fromRoute('langvar');
$this->params('langvar');

If condition for 2 forms(2 submit buttons) in one controller in CI

I have a controller auth and there are 2 methods login and register.
And it is working nicely.
However, I need to have another function called login_and_register which will have an if condition that will determine which part will be executed. If the login part (basically code from login method) or register part (code from register method).
The if condition should be checking which submit button was clicked.
But here is the problem.
I need the form_open for both forms (login and register) stay like this:
<?php echo form_open('auth/login_and_register'); ?>
And this cannot be changed to e.g. auth/login_and_register_log or auth/login_and_register_reg or auth/login_and_register/log or auth/login_and_register/reg etc.
The login and register forms are in the same view and after submit is pressed this function login_and_register in auth controller is exectuted.
I was thinking that I can make the if condition base on the name of submit value, because for login form it is called submitlog and for registration form it is called submitreg.
So, maybe something like this:
if( isset($this->form_validation->set_value('submitlog')) ) {
//code for login part
}
elseif ( isset($this->form_validation->set_value('submitreg')) ) {
//code for registration part
}
else {
//code for redirect to homepage
}
But it is not working. Any idea why?
Querying the submit button names is a good idea. Here is a piece of code that works:
if ($this->input->post("submitlog") !== false) {
//code for login part
} elseif ($this->input->post("submitreg") !== false) {
//code for registration part
} else {
//code for redirect
}
instead of that, you can keep a hidden field in both the forms with the value of corresponding form name. In the controller you can check this field value and identify which form is submitted. Then you can redirect into the required function..

codeigniter : using flash data but no new page load?

Usually, I just set a $feedback var or array and then check for that to display in my views.
However, it occurred to me I should perhaps use flashdata instead.
The problem is sometimes - for say an edit record form, I may simply want to reload the form and display feedback - not redirect. when i use flashdata, it shows but then it shows on the next request as well.
What would be the best practice to use here?
CodeIgniter supports "flashdata", or session data that will only be available for the next server request, and are then automatically cleared.
u use hidden field for that
I would use the validation errors from the Form validation class and load those directly to the view in its 2nd argument.
$this->form_validation->set_error_delimiters('<p>', '</p>');
$content_data = array();
if (!$this->form_validation->run()) {
$content_data['errors'] = validation_errors();
}
$this->load->view('output_page', $content_data);
Then check in your view whether $errors isset.
Controller:
$data['message'] = 'some message you want to see on the form';
$this->load->view('yourView', $data);
View:
if (isset ($message)) : echo $message; endif;
...

Resources