CodeConnoisseur
CodeConnoisseur

Reputation: 1879

Laravel form validation redirects back to home page upon form errors instead of staying on same page

I have a contact form that is successfully going to the DB when submitted. The issue is when I check for validation on my webpage. The errors appear properly using Laravel $error validation. The problem is that my webpage always redirects back to home when errors appear instead of the page still showing the errors. I must keep scrolling down to where my contact form is to see the errors; this will annoy my future users. How do I get the page to remain where it is if there are errors? NOTE: My page redirects correctly when the form is valid and submitted. This is not an issue. NOTE-2: I have created a single-page webpage to which the nav links take you. There are no redirects. Instead, it is one HTML page.

Web.php

Route::get('/', 'HomeController@index')->name('home');
Route::post('/contact/submit', 'MessagesController@submit');

MessagesController.php

namespace App\Http\Controllers;

use App\Message;
use Illuminate\Http\Request;

class MessagesController extends Controller
{
    public function submit(Request $request)
    {
        $validatedData = $request->validate([
            'name' => 'required|min:2',
            'email' => 'required|max:255',
            'phonenumber' => 'required|min:10|max:10',
            'message' => 'required|min:5',
        ]);

        Message::create($validatedData);

        return redirect('/')->with('success', 'Your message has been 
            successfully sent. We will reach out to you soon');
    }
}

contact.blade.php

{{--CONTACT FORM--}}
<section id="contact">
    <div class="container-fluid padding">
        <div class="row text-center padding">
            <div class="col-12">
                <h2 class="lead display-3">Contact Us</h2>
                <hr class="my-4">

                <form action="/contact/submit" method="POST">
                    @csrf
                    <div class="field">
                        <label for="name" class="label">Name</label>

                        <div class="control">
                            <input type="text" class="input {{$errors->has('name') ? 'is-danger' : 'is-success'}}"
                                   name="name" placeholder="Project Title" value="{{old('name')}}">
                        </div>
                    </div>

                    <div class="field">
                        <label for="name" class="label">Email</label>

                        <div class="control">
                            <input type="text" class="input {{$errors->has('email') ? 'is-danger' : 'is-success'}}"
                                   name="email" placeholder="Project Title" value="{{old('email')}}">
                        </div>
                    </div>
                    
                    <div class="field">
                        <label for="name" class="label">Phone Number</label>

                        <div class="control">
                            <input type="text"
                                   class="input {{$errors->has('phonenumber') ? 'is-danger' : 'is-success'}}"
                                   name="phonenumber" placeholder="Project Title" value="{{old('phonenumber')}}">
                        </div>
                    </div>

                    <div class="field">
                        <label for="message" class="label">Message</label>
                        <div class="control">
                            <textarea name="message"
                                      class="textarea {{$errors->has('message') ? 'is-danger' : 'is-success'}}"
                                      placeholder="Project description">{{old('message')}}</textarea>
                        </div>
                    </div>

                    <div class="field">
                        <div class="control">
                            <button type="submit" class="button is-link">Create Project</button>
                        </div>
                    </div>

                    <!--Errors variable used from form validation -->
                    @if($errors->any())
                        <div class="notification is-danger">
                            <ul>
                                @foreach($errors->all() as $error)
                                    <li>{{$error}}</li>
                                @endforeach
                            </ul>
                        </div>
                    @endif
                </form>
            </div>
        </div>
    </div>
</section>

Upvotes: 6

Views: 11578

Answers (2)

user633440
user633440

Reputation:

First, move the errors to the top of the form so you can see them.

<form action="/contact/submit" method="POST">
    @csrf
    @if($errors->any())
        <div class="notification is-danger">
            <ul>
                @foreach($errors->all() as $error)
                    <li>{{$error}}</li>
                @endforeach
            </ul>
        </div>
    @endif

A better way of handling validation is to separate it using a form request.

php artisan make:request SendMessageRequest
namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class SendMessageRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }
    
    public function rules()
    {
        return [
            'name' => 'required|min:2',
            'email' => 'required|max:255',
            'phonenumber' => 'required|min:10|max:10',
            'message' => 'required|min:5',
        ];
    }
}

If validation fails, a redirect response will be automatically generated to send the user back to their previous location.

Now update your controller.

use App\Http\Requests\SendMessageRequest;
use App\Message;

class MessagesController extends Controller
{
    public function submit(SendMessageRequest $request)
    {
        Message::create($request->validated());

        return redirect('/')->with('success', 'Your message has been
            successfully sent. We will reach out to you soon');
    }
}

You can leave the validation in your controller using the Validator and back() redirection, but the first is the better way.

public function submit(Request $request)
{
    $validator = Validator::make($request->all(), [
        'name' => 'required|min:2',
        'email' => 'required|max:255',
        'phonenumber' => 'required|min:10|max:10',
        'message' => 'required|min:5',
    ]);

    if ($validator->fails()) {
        return back()->withInput()->withErrors($validator);
    }

    Message::create($request->all());

    return redirect('/')->with('success,' 'Your message has been
        successfully sent. We will reach out to you soon');
}

Upvotes: 5

Yuvan
Yuvan

Reputation: 94

You need to create a manual validator so that you have control over the redirect if the validation fails (which I assume is what you are having issues with).

public function submit(Request $request)
    {
        $validator = Validator::make($request->all(),[
            'name' => 'required|min:2',
            'email' => 'required|max:255',
            'phonenumber' => 'required|min:10|max:10',
            'message' => 'required|min:5',
        ]);

        if ($validator->fails()) {
            return redirect(url()->previous() .'#contact')
                    ->withErrors($validator)
                    ->withInput();
        }

        Message::create($request->all());

        return redirect('/')->with('success', 'Your message has been 
            successfully sent. We will reach out to you soon');
    }

Upvotes: 7

Related Questions