Phil
Phil

Reputation: 2246

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'));
}

Upvotes: 2

Views: 6049

Answers (6)

plexus
plexus

Reputation: 1798

I am now using the browser back via JS in onclick. Seems to work:

<a onclick="window.history.back();">Back</a>

Upvotes: 1

Dima Kuzmin
Dima Kuzmin

Reputation: 41

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:

<a href="{{ old('redirect_to', URL::previous())}}">cancel</a>

Upvotes: 4

Amany Taweel
Amany Taweel

Reputation: 1

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

Upvotes: 0

Phil
Phil

Reputation: 2246

I used this jquery for the cancel button.

$(document).ready(function(){
    $('a.back').click(function(){
        parent.history.back();
        return false;
    });
});

Upvotes: 0

Tim Lewis
Tim Lewis

Reputation: 29306

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.

Upvotes: 1

ollieread
ollieread

Reputation: 6301

It's actually working correctly, it's just the usage that is incorrect.

Take the following:

  1. You submit a form at GET /attendee/edit/{id}
  2. The form takes you to POST /attendee/edit/{id}
  3. 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.

Upvotes: 3

Related Questions