Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add custom options to symfony form

1 What i want to do is add custom (option is 'angular' in this case)option to my form widget template:

{%- block widget_attributes -%}
    id="{{ id }}" name="{{ full_name }}"

    {%- if angular %} ng-model="{{ full_name }}"{% endif -%}
 ....
    {%- if intention %} {{ intention }}{% endif -%}
    {%- if read_only %} readonly="readonly"{% endif -%}
 .....
{%- endblock widget_attributes -%}

I wand to decide about form has it option or no in my CustomFormType. But i can't achieve it. I tried different method.

Is it possible to add custom option to the main form?

I know that there are a lot of tutorials showing how to pass custom options in child element, e.g http://symfony.com/doc/current/cookbook/form/create_form_type_extension.html

I investigated core of form component and there are class

 namespace Symfony\Component\Form\Extension\Core\Type;

 class FormType extends BaseType{}

which has method build View

public function buildView(FormView $view, FormInterface $form, array $options)
{

     .....

    $view->vars = array_replace($view->vars, array(
        'read_only' => $readOnly,
        'errors' => $form->getErrors(),
        'valid' => $form->isSubmitted() ? $form->isValid() : true,
        'value' => $form->getViewData(),
        'data' => $form->getNormData(),
        'required' => $form->isRequired(),
        'max_length' => isset($options['attr']['maxlength']) ? $options['attr']['maxlength'] : null, // Deprecated
        'pattern' => isset($options['attr']['pattern']) ? $options['attr']['pattern'] : null, // Deprecated
        'size' => null,
        'label_attr' => $options['label_attr'],
        'compound' => $form->getConfig()->getCompound(),
        'method' => $form->getConfig()->getMethod(),
        'action' => $form->getConfig()->getAction(),
        'submitted' => $form->isSubmitted(),

    ));
}

Above symfony define base options. I can access these options globally in form template, but i can't find the way to add my own.

like image 599
Piotr Galas Avatar asked Apr 02 '15 08:04

Piotr Galas


3 Answers

Simply add default option in you form type

/**
 * @param OptionsResolverInterface $resolver
 */
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        // default form options
        'my_options' => 'my default value option'
    ));
}

EDIT

/**
 * {@inheritdoc}
 */
public function buildView(FormView $view, FormInterface $form, array $options)
{
    $view->vars['my_options'] = $options['my_options'];
}
like image 51
Charlie Lucas Avatar answered Nov 01 '22 07:11

Charlie Lucas


I found solution based on @Charlie Lucas post.

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

above method update only parent form (I ask about it), but if i pass this options in widget template:

{%- block widget_attributes -%}
 {{ 'my_options' }}
{%- endblock widget_attributes -%}

I recive errorr that the option doesnt exist.

Now I understand why error occured. This option is invoked in every widget. That mean that also child element invoke this option. But this option is not defined in children.

To solve it I add option to parent form and to child form in FormType class. In

  public function buildView(FormView $view, FormInterface $form, array $options)
 {
    .....
 }

We have no access to child element so I had to invoke finishView() instead. In this method i use recurence function to add option to all element

public function finishView(FormView $view, FormInterface $form, array $options)
{
    $params = array(
        'angular'=>true,
    );

    $this->setParam( $view, $params);

}

private function setParam(FormView $view, array $params)
{
    $this->updateParam($view, $params);
    $this->updateChild($view, $params);
}

private function updateChild(FormView $parent, array $params)
{
    foreach ($parent->children as $child){
        $this->updateParam($child, $params);
        $this->updateChild($child, $params);
    }
}

private function updateParam(FormView $view, array $params)
{
    foreach($params as $key => $value){
        $view->vars[$key] = $value;
    }
}
like image 30
Piotr Galas Avatar answered Nov 01 '22 09:11

Piotr Galas


In symfony 5

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'my_custom_option' => 'default_value',
        'data_class' => User::class,
    ]);
}
like image 37
krzysztof Avatar answered Nov 01 '22 07:11

krzysztof