Laravel - validate input arrays and return values in case of error

Asked

Viewed 3,702 times

3

I am creating form using the following code:

In the create.blade.php file

{!! Form::open(['route'=>'orcamentos.store']) !!}
{!! Form::text('descricao', null, ['class'=>'form-control', 'autofocus']) !!}
{!! Form::text('produto[]', null, ['class'=>'form-control']) !!}
{!! Form::text('produto[]', null, ['class'=>'form-control']) !!}
// Esse campo produto pode se repetir inúmeras vezes em tela
{!! Form::submit('Salvar', ['class'=>'btn btn-primary']) !!}

Note that I may have 'N' input "product".

On my controller I have this:

public function store(OrcamentoRequest $request){...}

And in the Orcamentorequest class I want to validate the mandating of these fields, does anyone know how I can do that?

Within function rules I have already made some attempts based on the searches made on the internet, but n have succeeded.

Below follows some unsuccessful attempts:

ATTEMPT 1:

$rules = [
     'descricao' => 'required',
     'produto.*' => 'required',
 ];

ATTEMPT 2:

foreach($this->request->get('produto') as $key => $val){
  $rules['produto.'.$key] = 'required';
} 

I also found something in the documentation itself. link here but nothing worked.

The mistake you’re making is this:

ErrorException in helpers.php line 531:
htmlentities() expects parameter 1 to be string, array given

Has anyone been through this before? Or does he know the answer?

1 answer

2


I’ve been testing and from what I think I’m doing this way it’s because you’re using Laravel 5.2, because the previous ones didn’t have validation built-in for inputs in array then did:

LARAVEL 5.2:

HTML:

@foreach ($errors->all() as $error)
    {{$error}}<br>  <!-- imprimir os erros de validação caso haja algum, serão enviados pelo Validator -->
@endforeach

<form action="/product/store" method="POST">
    {!! csrf_field() !!}
    <input type="text" name="descricao" value="{{old('descricao')}}"></input>
    <input type="text" name="products[]" value="{{old('products.0')}}"></input>
    <input type="text" name="products[]" value="{{old('products.1')}}"></input>
    <input type="text" name="products[]" value="{{old('products.2')}}"></input>
    <input type="text" name="products[]" value="{{old('products.3')}}"></input>
    <input type="submit">
</form>

Routa:

Route::post('/product/store', 'TestsController@product_store');

Controller:

use Validator;
...

public function product_store(Request $request) {

    $inputs = $request->except('_token'); // valores de todos os inputs excepto o do csfr token
    // $inputs = Array ( [descricao] => mobilidade [products] => Array ( [0] => carro [1] => mota [2] => camiao [3] => barco) )

    $rules = array(
        'descricao' => 'required', // mesmo nome dos nossos inputs, name="descricao"
        'products.*' => 'required' // mesmo nome dos nossos inputs, name="products"
    );

    $validator = Validator::make($inputs, $rules);
    if($validator->fails()) {
        return redirect()->back()->withInput()->withErrors($validator); // voltar para trás e enviar os erros, regras ($rules), que não foram respeitadas
    }
    // Esta tudo bem, fazer outras coisas
}

And it worked.

LARAVEL 5.1:

Here I had to take a slightly different approach since it doesn’t seem to have validation for arrays by default:

The only thing I’ve changed is the controller, so:

public function product_store(Request $request) {

    $inputs = $request->except('_token');
    // $inputs = Array ( [descricao] => mobilidade [products] => Array ( [0] => carro [1] => mota [2] => camiao [3] => barco) )

    $products = array(
        'descricao' => $inputs['descricao'], // valor da descricao introduzido
    );

    $rules = array(
        'descricao' => 'required', // mesma key que demos nos $products
    );

    foreach ($inputs['products'] as $key => $value) {
        $products['product_' .$key] = $value;
        $rules['product_' .$key] = 'required';
    }

    $validator = Validator::make($products, $rules);
    if($validator->fails()) {
        return redirect()->back()->withInput()->withErrors($validator); // voltar para trás e enviar os erros, regras ($rules), que não foram respeitadas
    }
    // Esta tudo bem, fazer outras coisas
}

Always remember that the Keys of the rules, our $rules, have to be the same Keys of the array that we will validate, in this last case the $products.

  • Thanks for the explanations... I used the example of 5.2 but he does not know how to fill in the fields at the moment that shows the error message. It happened to you too?

  • I’ll edit, so that it happens, be aware

  • Thank you, that worked, but I think the code ta getting a little 'weird' too... changing my design a little and leaving the inputs so product[1], product[2]... and putting inside the Rules so 'product. *' => required . So Laravel already knows how to validate and fill the data back when reassembling the screen, I think I’ll go this way. I honestly didn’t want to touch my views, but within the proper circumstances I think it’s the best option. Thank you, your help was very important.

  • You have to at least add in the values of the inputs what I have above, products.0, remember that it is not products[0] is how I have there. And add withInput() in redirect when there are errors

  • I just didn’t like this part very much here: {{old('products.1')}} , this having to stay fixed in the inputs of the view I think means "gambiarra", because how do I get the data editing view?? , then that your solution would not solve I think. So I will use the numbered inputs because that way Laravel already knows how to work.

  • I also confess that I think the same. But I don’t know anything better for it using the Laravel

  • What is the most advised place for me to put the conclusions we have reached from these speeches to the next person not needing to read all the comments?

  • You can edit the question according to the things that have been clarified and that the solution covers. I’ve already edited the title, I think this is more appropriate to our dicussion

  • You can also save input values in Session, e.g.: value={{Session:get('products')[0]}}...

  • @Andersonsouza realized his doubt as to what to do in editing. Easy, no value put value="{{$obj_a_editar->product0 or old('products.0')}}", which is the equivalent of value="@if(isset($obj_a_editar)){{$obj_a_editar->product0}}@else{{old('product.0')}}@endif"

  • Yeah, but I think it’s gonna be too much code... but thanks for trying to help. But I will change the name of inputs in the same views, I will leave so product[1], product[2] ... will give me more work now, but the code will get cleaner.

Show 6 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.