Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 5.8: Validation multiple inputs

What I have

I have a form with 3 inputs and I want to check the following conditions:

  • All inputs are integers and they are required.
  • We do a math operation with all the numbers and we get if the operation was successfull or not.
    • Success: we redirect the user to a success page.
    • No success: we show a error message to the user with a message explaining him that the numbers aren't valid.

I resolved this with the following lines.

Controller:

function formAction(Request $request) {
    $this->validate($request, [
        'number1' => 'integer|required',
        'number2' => 'integer|required',
        'number3' => 'integer|required',
    ]);

    $numbers = $request->all();
    $isValid = MyOwnClass::checkMathOperation($numbers);

    if($isValid) {
        return redirect()->route('success');
    } else {
        $request->session()->flash('error', 'The numbers are not valid.');
        return back();
    }
}

View (using Bootstrap):

<form method="POST" action="{{ route('form-action') }}">
    @csrf

    <div class="form-group">
        <label for="number1">number1</label>
        <input id="number1" name="number1" class="form-control {{ $errors->has('number1') ? ' is-invalid' : '' }}" />
    </div>

    <div class="form-group">
        <label for="number2">number2</label>
        <input id="number2" name="number2" class="form-control {{ $errors->has('number2') ? ' is-invalid' : '' }}" />
    </div>

    <div class="form-group">
        <label for="number3">number3</label>
        <input id="number3" name="number3" class="form-control {{ $errors->has('number3') ? ' is-invalid' : '' }}" />
    </div>

    <button type="submit" class="btn btn-primary">Submit</button>
</form>

@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

What I looking for

  • When MyOwnClass::checkMathOperation($numbers) is false:
    • To highlight number1, number2 and number3 inputs.
    • To show an unique custom error message
    • To hide the number1, number2 and number3 input error messages.

How can I do that with validators?

Solution

Create a Form Request Validation called, for example, NumbersForm using:

php artisan make:request NumbersForm

The previous command creates a App/Http/Requests/NumbersForm.php file. Make authorize() returns true, put the validation rules into rules() and create a withValidatior() function.

class NumbersForm extends FormRequest
{
    public function authorize() {
        return true;
    }

    public function rules() {
        return [
            'number1' => 'integer|required',
            'number2' => 'integer|required',
            'number3' => 'integer|required',
        ];
    }

    public function withValidator($validator) {
        $validator->after(function ($validator) {
            $numbers = $this->except('_token'); // Get all inputs except '_token'
            $isValid = MyOwnClass::checkMathOperation($numbers);

            if(!$isValid) {
                $validator->errors()->add('number1', ' ');
                $validator->errors()->add('number2', ' ');
                $validator->errors()->add('number3', ' ');
                $validator->errors()->add('globalError', 'The numbers are not valid.');
            }
        });
    }
}

Note: It's not important the text in the second param of $validator->errors()->add('number1', ' ');, but it can't be empty. If it is an empty string, $errors->has('number1') returns false, and the field won't be hightlighted.

Set the controller like this:

use App\Http\Requests\NumbersForm;

function formAction(NumbersForm $request) {
    $this->validated();
    return redirect()->route('success');
}

And, finally, if we want to print an unique error message, we must remove the following lines from view:

@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

and replace them with:

@if ($errors->has('globalError'))
    <div class="alert alert-danger">
        {{ $errors->first('globalError') }}
    </div>
@else
    @if ($errors->any())
        <div class="alert alert-danger">
            <ul>
                @foreach ($errors->all() as $error)
                    <li>{{ $error }}</li>
                @endforeach
            </ul>
        </div>
    @endif
@endif
like image 853
cespon Avatar asked Dec 28 '25 11:12

cespon


1 Answers

I haven't tested this but I think it can get you going in the right direction.

1 // Highlight the inputs

You can do this by accessing the error object within your view. This object is an instance of the MessageBag object.

Here is the docs: https://laravel.com/docs/5.7/validation#working-with-error-messages

Example:

// if the error exists for the input the class will be added
<input class=" {{ $error->has('number1') ? 'highlight' : '' }}" name="number1">
<input class=" {{ $error->has('number2') ? 'highlight' : '' }}" name="number2">
<input class=" {{ $error->has('number3') ? 'highlight' : '' }}" name="number3">

2 & 3 // Show a unique custom error message and hide the default messages

See the validator docs: https://laravel.com/docs/5.8/validation#custom-error-messages && https://laravel.com/docs/5.7/validation#working-with-error-messages -- this should solve both of these.

There is a validator callback and I think you can pass your second validation into that. If these numbers aren't valid then you can add your custom error messages and access them the same way as I did above.

function formAction(Request $request) {
    $validator = $this->validate($request, [
        'number1' => 'integer|required',
        'number2' => 'integer|required',
        'number3' => 'integer|required',
    ]);

    $validator->after(function ($validator) {
        $numbers = $request->all();
        $isValid = MyOwnClass::checkMathOperation($numbers);

        if(!$isValid) {
           $validator->errors()->add('number1', 'Unique message');
           $validator->errors()->add('number2', 'Unique message');
           $validator->errors()->add('number3', 'Unique message');
        }
    });
}
like image 195
Vim Diesel Avatar answered Dec 31 '25 05:12

Vim Diesel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!