Laravel pre-filling multiple forms if validation failed

浪尽此生 提交于 2019-12-05 03:02:33

问题


One of the coolest Laravel feature is, Laravel pre-filled the form fields if validation error occurred. However, if a page contain more than one form, and form fields have same name, Laravel pre-filling all forms fields.

For example:

I have a page where i have two forms to create new users or whatever.

<h1>Create user1</h2>    
    {{ Form::open(array('url' => 'foo/bar')) }}
        {{ Form::text('name', null) }}
        {{ Form::email('email', null) }}
    {{ Form::close() }}

</h1>Create user2</h1>    
    {{ Form::open(array('url' => 'foo/bar')) }}
        {{ Form::text('name', null) }}
        {{ Form::email('email', null) }}
    {{ Form::close() }}

Controller

class UsersController extends BaseController
{
  public function store()
  {
     $rules = [
        'name'   => 'required',
        'email'  => 'required'
    ];

     $validation = Validator::make(Input::all(), $rules);

     if ($validation->fails()) {

        return Redirect::back()->withInput()->withErrors($validation);
     }
  }
}

As i didn't fill up the email, Laravel will throw validation error and pre-filling the forms as following:

How to tell Laravel that do not fill-up the second form?


回答1:


There's no Laravel way of doing this, but you can use HTML basic form arrays to make it work. You need to understand that you have to identify your forms and fields so Laravel knows exactly where the data came from and where to send it back to. If all your fields have the same name how could it possibly know?

This is a proof of concept that will work straight from your routes.php file.

As I did it all and tested here before posting the answer I used Route::get() and Route::post(), to not have to create a controller and a view just to test something I will not use. While developing this you will have to put this logic in a controller and in a view, where I think they are alredy in.

To test it the way it is, you just have to point your browser to the following routes:

http://yourserver/form

and when you push a button it will automatically POST tho the route:

http://yourserver/post

I'm basically giving all forms a number and giving the buttons the number that we will usin in Laravel to get the form data and validate it.

Route::get('form', function() 
{
      return Form::open(array('url' => URL::to('post'))).
             Form::text('form[1][name]', null).
             Form::email('form[1][email]', null).
             '<button type="submit" name="button" value="1">submit</button>'.
           Form::close().

            Form::open(array('url' => URL::to('post'))).
              Form::text('form[2][name]', null).
              Form::email('form[2][email]', null).
              '<button type="submit" name="button" value="2">submit</button>'.
           Form::close();           
});

And here we get the data, select the form and pass all of it to the validator:

Route::post('post', function() 
{
    $input = Input::all();

    $rules = [
            'name'   => 'required',
            'email'  => 'required'
    ];

    $validation = Validator::make($input['form'][$input['button']], $rules);

    return Redirect::back()->withInput();
});

This is how you use it in a Blade view, now using 3 forms instead of 2 and you can have as many forms as you need:

<h1>Create user1</h2>    
    {{ Form::open(array('url' => URL::to('post'))) }}
        {{ Form::text('form[1][name]', null) }}
        {{ Form::email('form[1][email]', null) }}
        <button type="submit" name="button" value="1">submit</button>
    {{ Form::close() }}

</h1>Create user2</h1>    
    {{ Form::open(array('url' => URL::to('post'))) }}
        {{ Form::text('form[2][name]', null) }}
        {{ Form::email('form[2][email]', null) }}
        <button type="submit" name="button" value="2">submit</button>
    {{ Form::close() }}

</h1>Create user3</h1>    
    {{ Form::open(array('url' => URL::to('post'))) }}
        {{ Form::text('form[3][name]', null) }}
        {{ Form::email('form[3][email]', null) }}
        <button type="submit" name="button" value="3">submit</button>
    {{ Form::close() }}

And you can even use a loop to create 100 forms in blade:

@for ($i=1; $i <= 100; $i++)
    User {{$i}}
    {{ Form::open(array('url' => URL::to('post'))) }}
        {{ Form::text("form[$i][name]", null) }}
        {{ Form::email("form[$i][email]", null) }}
        <button type="submit" name="button" value="{{$i}}">submit</button>
    {{ Form::close() }}
@endfor



回答2:


Use old input with $request->flash().

https://laravel.com/docs/5.2/requests#old-input



来源:https://stackoverflow.com/questions/20715467/laravel-pre-filling-multiple-forms-if-validation-failed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!