19

I get the following error when trying to pass through an option to my buildForm method in one of my forms.

The option "numOfHoles" does not exist. Defined options are: "action", "allow_extra_fields", "attr", "auto_initialize", "block_name", "by_reference", "cascade_validation", "compound", "constraints", "csrf_field_name", "csrf_message", "csrf_protection", "csrf_provider", "csrf_token_id", "csrf_token_manager", "data", "data_class", "disabled", "empty_data", "error_bubbling", "error_mapping", "extra_fields_message", "inherit_data", "intention", "invalid_message", "invalid_message_parameters", "label", "label_attr", "label_format", "mapped", "max_length", "method", "pattern", "post_max_size_message", "property_path", "read_only", "required", "translation_domain", "trim", "validation_groups", "virtual".

In my controller:

// hardcoded here for brevity in this example
$form = $this->createForm('crmpicco_course_row', $courseRow, array('numOfHoles' => 18));

In crmpicco_course_row Form class:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('name', 'text')
        ->add('course', 'crmpicco_course', array('numOfHoles' => $options['numOfHoles']))
    ;
}

In crmpicco_course Form class:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    for ($i = 0; $i < $options['numOfHoles']; $i++) {
        $builder->add($i, 'text', array('required' => 'false'));
    }
}

/**
 * @return string name
 */
public function getName()
{
    return 'crmpicco_course';
}

Can anyone see why the option numOfHoles is not pulling through?

crmpicco
  • 14,513
  • 22
  • 113
  • 191
  • You have to add the `numOfHoles` option using the `setDefaults` or `setRequired` function inside the `configureOptions(OptionsResolver $resolver)` of your form builder. – gp_sflover Oct 26 '15 at 12:53

3 Answers3

31

As you have discovered, each form type has a predefined list of options. Adding a new option requires a slight adjustment. The actual method has changed over the course of Symfony development so you may come across some older depreciated solutions.

The most up to date solution is discussed here: http://symfony.com/blog/new-in-symfony-2-7-form-and-validator-updates#deprecated-setdefaultoptions-in-favor-of-configureoptions

So basically add

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle\Entity\Whatever',
        'numOfHoles' => 0,
    ));

To your form types and you should be good to go.

Cerad
  • 44,053
  • 8
  • 77
  • 79
0

I saw in the video that you need to create a form type extension to "invent" options:

https://symfonycasts.com/screencast/symfony-forms/form-type-extension#play

"It turns out that you can't just "invent" new options and pass them: each field has a concrete set of valid options. But, in TextareaSizeExtension, we can invent new options. "

For example when needed to add rows atribute, in extension done this:

   public function buildView(FormView $view, FormInterface $form, array $options)
    {
        $view->vars['attr']['rows'] = $options['rows'];
    }

public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'rows' => 10
        ]);
    }

And now in buildForm method when you add a field you can pass option this way:

->add('content', null, ['rows' => 15])

This should at least work with symfony 4 as in the video was talked, probably 3.4 also.

Just watched another video https://symfonycasts.com/screencast/symfony-forms/form-options-data and saw doing same as Cerad answered. So now as I understand we need formExtention only if we want to extend third party form type.

Darius.V
  • 566
  • 5
  • 10
-2

Try doing this:

$numOfHoles = array('numOfHoles' => $options['numOfHoles']));

then:

$oForm = $this->createForm(new CompanyForm($numOfHoles));

Then you need to call it before your buildForm:

public function __construct($contacts))
{
$this->vnumOfHoles = $numOfHoles;
}
Besbes Riadh
  • 671
  • 1
  • 9
  • 22