2

I want to use form model binding in Laravel. The following (simplified) example works fine:

{{ Form::model($user, array('class'=>'form-horizontal')) }}
    {{ Form::token() }}

    {{ Form::label('email', 'Email Address') }}
    {{ Form::text('email') }}
{{ Form::close() }}

However, I want to use arrays in the name attributes, as is pretty standard nowadays. In other words, have user[email] as the field name, so that I get all the form elements in one array in the backend.

Is this possible with model binding? When I use {{ Form::text('user[email]') }} the email does not get filled in. I tried adding array('user'=>$user) in the Form::model function in case it needed a nested value, but no luck.

2
  • 1
    Form::open() and Form::model() will automatically add token, when ended with Form::close() Commented Aug 4, 2014 at 11:08
  • For the problem, you will probably need to use pure HTML to get the input names with array notation handled correctly. You can also use Form::macro() to simplify the task. Commented Aug 4, 2014 at 11:10

2 Answers 2

2

Form::model(array('user' => $user)) is the correct solution, BUT unfortunately the implementation of form model binding is pretty bad as it does not easily work on a nested, mixed set of arrays and objects. See https://github.com/laravel/framework/pull/5074

You could try Form::model(array('user' => $user->toArray())) or Form::model((object) array('user' => $user)).

Sign up to request clarification or add additional context in comments.

Comments

1

You could do something like this assuming that you would have a single $user and multiple $types

Form::macro('userTypes', function($user,$types)
{
    foreach ($types as $type) {
        $concat = $user . "_" . $type;
        return '<input type="{$type}" name="{$concat}">';
    }
});

And customize the output with your form style, even adding more complexity to the function might be required.

And then simply calling it for example

$user = "johndoe";
$types = array("email","text");
Form::userTypes($user,$types);

That would result in

<input type="email" name="johndoe_email">
<input type="text" name="johndoe_phone">

If you want to do it in a single line and assuming that you would have a single $user and a single$type you could do something like

Form::macro('userType', function($user,$type)
{
        return '<input type="{$type}" name="{$user[$type]}">';
});

And with the call

$user = [ "mail" => "some_mail_value" ];
Form::userType($user,"mail");

Would result in

<input type="mail" name="some_mail_value">

Or perhaps you'd like something that would work with a single $user key-value array as :

Form::macro('userType', function($user)
{       
        $keys = array_keys($user);
        foreach ($keys as $key => $value) {
            return '<input type="{$key}" name="{$value}">';
        }
});

And with the call

$user = ["mail" =>  "mail_value" , "text" => "text_value"];
Form::userType($user);

That would result in

<input type="mail" name="mail_value">
<input type="text" name="text_value">

And finally I didn't find a direct way to do it with default form model binding, as It requires the field name to be the same as the model attribute, but you could do a workaround as

Form::macro('customBind', function($user_model,$type)
{       
    return '<input type={$type} name="user[{$type}]" value="{$user_model->$type}">';
});

And then

$user = new User();
$user->email = "[email protected]";

Form::customBind($user,"email");

Which would produce something like

<input type="email" name="user[email]" value="[email protected]">

The takeaway point is that basically the solution to your problem is creating a Macro, I have provided some workarounds on this but you will need to refine this to your specific needs.

3 Comments

But then I have the exact same problem - single values in the name attribute and not arrays. Unless there is a simple way to parse all those into a single array in the controller?
It's just a matter of tweaking the function, I do not know if you are planning on having multiple user objects on the page, so I'll update the answer with one suggestion for a single user object.
No, it's only one user. What I mean is, when I submit your form I get two separate input variables, johndoe_email and johndoe_phone. What I want is for the name attribute to be like user[email] and user[phone] so that I just get $user as an array in the controller.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.