Symfony2 dynamic form generation

I have mysql 2 tables: user_profile_field and user_profile_data strong> with the following columns:

user_profile_field:

-id (integer)
-field (string)
-category(string) 

      

user_profile_data:

-id (integer)
-user_id (integer)
-field_id (integer) references user_profile_field(id)
-data (string)

      

I've also defined 2 Doctrine objects that represent this relationship. I need dynamic form creation to update user_profile_data. The form input type for each user_profile_field row depends on the user_profile_field: category column (3 possible values ​​correspond to different input types: text, textarea and select field) ...

Not sure how to create form and type type using "Symfony2" method?

Any help or suggestion is appreciated ...

+3


source to share


2 answers


An early solution that I used was to pass an array defining the form configuration to the form type constructor method and build those form fields during the buildForm method.

I don't know how you configured your users to fill in the blanks.

In the beginning I think it will happen in the controller, but the best way is to move as much logic into the form handler as FOS User Bundle: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Form/Handler/RegistrationFormHandler.php

You will need to get all the fields of your user profile and prepare them in an array ready to be added to the form type constructor (see example for ProfileType).

$form_config = array(
    'fields' => array()
);

// get all user_profile_field entities add them to $form_config['fields']
// foreach $user_profile_fields as $user_profile_field...
// $form_config['fields'][] = $user_profile_field;

      

Next, you need to create an array view of your user based on the user_profile_data you collected. This data is then linked to the form later.

I'm not sure if you can pass this version of the array directly to the form. If the form is expecting an Entity, you may need to first pass a basic custom object to the form and then bind the version of the array (containing dynamic data) to set the values ​​of the dynamic field.

Here's the profile form class you'll be using:



class ProfileType extends AbstractType
{
    // stores the forms configuration
    // preferably map defaults here or in a getDefaultConfig method
    private $formConfig = array();

    // new constructor method to accept a form configuration
    public function __construct($form_config = array())
    {
        // merge the incoming config with the defaults
        // set the merged array to $this->formConfig
        $this->formConfig = $form_config;
    }

    public function buildForm(FormBuilder $builder, array $options)
    {
        // add any compulsory member fields here 
        // $builder->add( ... );

        // iterate over the form fields that were passed to the constructor
        // assuming that fields are an array of user_profile_field entities
        foreach ($this->formConfig['fields'] as $field) {
            // as form is not a straight entity form we need to set this
            // otherwise validation might have problems
            $options = array('property_path' => false);
            // if its a choice fields add some extra settings to the $options

            $builder->add($field->getField(), $field->getCategory(), $options);
        }

    }

      

This covers the output of the form.

In the controller, create a form.

$profileForm = $this->createForm(new ProfileType($form_config), $user);

      

As a result, the controller method should be structured something like this (filling in spaces):

// get the user
// get user data
// create array version of user with its data as a copy

// get profile fields
// add them to the form config
// create form and pass form config to constructor and the user entity to createForm
// bind the array version of user data to form to fill in dynamic field values


// check if form is valid
// do what is needed to set the posted form data to the user data
// update user and redirect

      

I feel like form events is probably the best approach in Symfony2, but maybe this will help you get started. You can then consider form events in the refactoring step.

+7


source


Symfony 2 user documentation suggests using form events to create a dynamic form: http://symfony.com/doc/current/cookbook/form/dynamic_form_generation.html



+3


source







All Articles