I'm available to work on new projects starting August 2018! Get in touch!

Back to post list

Laravel: Validate login and register forms on the same view

12-02-2016

This is a quick tip for something I had to work on a while back. A client wanted to have the login and register forms on the same view, side by side.

There are two parts to pay attention to: The forms and the validations. The forms is fairly trivial, it will be 2 separate forms, that post to 2 separate controller methods. The validation however is the thing we need to be careful on. If we submit the login form with emtpy email field, using the usual validation in laravel, both email fields on the login and register forms will be highlighted.

This quick hint will show how to prevent this, using laravel's form requests.

What we're trying to accomplish

We're trying to separate the validation of the 2 forms.

The from requests

This is where the laravel magic happens. Laravel exposes a protected $errorBag class property on the FromRequest class. This is what's used to differentiate between the 2 forms.

/**
 * The key to be used for the view error bag.
 *
 * @var string
 */
protected $errorBag = 'default';

We can set that $errorBag property to login on the login form request.

use Illuminate\Foundation\Http\FormRequest;

class LoginFormRequest extends FormRequest
{
    protected $errorBag = 'login';

    public function rules()
    {
        return [
            'email' => 'required|email',
            'password' => 'required|min:8',
        ];
    }

    public function authorize()
    {
        return true;
    }

    public function messages()
    {
        return [];
    }
}

The register form request however can remain intact. Optionally you could also specify the error bag, but this is not required.

The forms

The 2 forms are posting to 2 different locations, containing their respective fields.

Login form

{!! Form::open(['route' => 'session.store', 'role' => 'form']) !!}
{!! Form::close() !!}

Register form

{!! Form::open(['route' => 'account.store', 'role' => 'form']) !!}
{!! Form::close() !!}

With the error bag specified for the login request, we need to access the errors in a slightly different manner:

{!! Form::open(['route' => 'session.store', 'role' => 'form']) !!}

	{!! Form::label('email', 'Email') !!}
	{!! $errors->login->first('email', '<span class="form__error">:message</span>') !!}
	{!! Form::email('email', old('email'), ['data-field-id' => 'login:email']) !!}

	{!! Form::label('password', 'Password') !!}
	{!! $errors->login->first('password', '<span class="form__error">:message</span>') !!}
	{!! Form::password('password') !!}

{!! Form::close() !!}

As you can see we're getting the errors of the login property on the $errors object. This keyname is the one we've set in the protected $errorBag property.

And that's it! Now only the login errors will be shown on the login form, and the register errors on the register form. Note that if you've also set an $errorBag property for the register form request, you need to access the errors in the same manner we did for the login errors.

I'm available to work on new projects starting August 2018! Get in touch!

Laravel 5.2: Morph Map Why Care About PHP Middleware?