kristijanhusak / laravel-form-builder

Laravel Form builder for version 5+!
https://packagist.org/packages/kris/laravel-form-builder
MIT License
1.71k stars 296 forks source link

How to pass values returned by getFieldValues() back to the form #489

Open kmbt opened 5 years ago

kmbt commented 5 years ago

Hi, I have a form that is not directly associated to any Eloquent Model. Instead the values are taken out using getFieldValues() and persisted as JSON. I need a way to get the values back to form so I can use it to edit the values. I have tried passing the data array as model option but have errors while rendering the form (htmlspecialchars() expects parameter 1 to be string, array given). The form includes choice fields and I suspect that this might cause problems.

I would like to know the proper way to populate form values when having data as returned from getFieldValues().

Could you help me with that?

kristijanhusak commented 5 years ago

You can pass an associative array as model, and you should get values populated. For choice type you need to have associative array (key => value pairs) for options. For example:

$this
  ->add('gender', 'choice', [
    'choices' => ['M' => 'Male', 'F' => 'Female']
  ])
  ->add('name', 'text');

So the model that you will pass down should look something like this:\

$model = [
  'gender' => 'M',
  'name' => 'John'
];

FormBuilder::create(MyForm::class, ['model' => $model ]);
mikeerickson commented 5 years ago

@kmbt Was the suggestion supplied above enough to close this issue?

kmbt commented 5 years ago

@mikeerickson thank you for your interest. The solution described by @kristijanhusak works for simple fields, but breaks in collection fields for me. This includes both collections of single fields as well as collection of subforms.

Having a field like:

$this
            ->add('tags', 'collection', [
                'type' => 'text',
            ]);

And pre-filling it with $model = ["tags" => ["first", "second", "third"]] populates the form correctly, however after submitting the form, and extracting data with $form->getFieldValues() the "second" and "third" values are missing (while the Request contains a complete array).

When I define "data" option the form stores as many values as there are in "data" array, however I cannot use that since I want to add more sibling fields using JS on the front end. (In the process I make sure to update the indices in newly generated fields.) The data from added fields is discarded by the Form while still being available in the Request.

Could you show me a way to prevent the Form from discarding additional input data from input arrays in collection fields?

kmbt commented 5 years ago

I suppose that my issue is partially solved in #497 . After setting prefer_input to true. The fields are read properly from request, however things break when initializing a fresh form (ie. with no Request input). This causes $currentInput to be null, so calling count($currentInput) throws an error. I am now referring to: https://github.com/kristijanhusak/laravel-form-builder/blob/30ae08082fbbc784325680a180b6edc18faa04a9/src/Kris/LaravelFormBuilder/Fields/CollectionType.php#L99

kmbt commented 5 years ago

I have created a new issue #515 for this particual problem.

rudiedirkx commented 5 years ago

@kmbt The form you create in the GET request (to show in html) should be identical to the form you create in the POST request (to validate). If it is, the validation form knows which input is allowed.