Laravel 5.8: проверка нескольких входных данных

Что я имею

У меня есть форма с 3 входами, и я хочу проверить следующие условия:

  • Все входные данные являются целыми числами, и они обязательны.
  • 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.
    • Нет успеха: мы показываем пользователю сообщение об ошибке с сообщением, объясняющим ему, что числа недействительны.

Я решил это с помощью следующих строк.

Контроллер:

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

Просмотр (с использованием 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

Что я ищу

  • When MyOwnClass::checkMathOperation($numbers) is false:
    • To highlight number1, number2 and number3 inputs.
    • Чтобы показать уникальное пользовательское сообщение об ошибке
    • Чтобы скрыть сообщения об ошибках ввода number1, number2 и number3.

Как я могу сделать это с помощью валидаторов?

Решение

Создайте вызов Form Request Validation, например, NumbersForm используя:

php artisan make:request NumbersForm

Предыдущая команда создает файл App/Http/Requests/NumbersForm.php. Сделайте так, чтобы authorize() возвращало true, поместите правила проверки в rules() и создайте функцию withValidatior().

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

Примечание. Текст во втором параметре $validator->errors()->add('number1', ' '); не важен, но он не может быть пустым. Если это пустая строка, $errors->has('number1') возвращает false, и поле не будет выделено.

Установите контроллер следующим образом:

use App\Http\Requests\NumbersForm;

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

И, наконец, если мы хотим напечатать уникальное сообщение об ошибке, мы должны удалить следующие строки из представления:

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

и замените их на:

@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

person cespon    schedule 12.03.2019    source источник
comment
Вы пробовали с Validator ? laravel.com/docs/5.8/validation Надеюсь, вы сможете использовать это для решения своей проблемы.   -  person Abhinav Verma    schedule 12.03.2019


Ответы (2)


Я не проверял это, но я думаю, что это может заставить вас двигаться в правильном направлении.

1 // Подсветка входных данных

Вы можете сделать это, обратившись к объекту ошибки в своем представлении. Этот объект является экземпляром объекта MessageBag.

Вот документы: https://laravel.com/docs/5.7/validation#working-with-error-messages

Пример:

// 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 // Показать уникальное пользовательское сообщение об ошибке и скрыть сообщения по умолчанию

См. документы валидатора: https://laravel.com/docs/5.8/validation#custom-error-messages && https://laravel.com/docs/5.7/validation#working-with-error-messages — это должно решить обе проблемы.

Существует обратный вызов валидатора, и я думаю, вы можете передать ему свою вторую проверку. Если эти номера недействительны, вы можете добавить свои собственные сообщения об ошибках и получить к ним доступ так же, как я сделал выше.

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');
        }
    });
}
person Vim Diesel    schedule 12.03.2019

Пользовательские правила проверки:

Чтобы добавить собственные сообщения и проверку, вы также можете написать настраиваемое правило проверки.

Пример:

class Uppercase implements Rule
{
/**
 * Determine if the validation rule passes.
 *
 * @param  string  $attribute
 * @param  mixed  $value
 * @return bool
 */
public function passes($attribute, $value)
{
    return strtoupper($value) === $value;
}

/**
 * Get the validation error message.
 *
 * @return string
 */
public function message()
    {
        return 'The :attribute must be uppercase.';
    }
}

Пользовательские сообщения об ошибках:

Вы также можете добавить собственные сообщения об ошибках для правил в запросе:

public function messages()
{
    return [
        'number1.required' => 'My custom message telling the user he needs to fill in the number1 field.',
        'number1.integer' => 'My custom message telling the user he needs to use an integer.',
    ];
}
person Kerel    schedule 18.03.2019