Search code examples
phpformssymfonyentity

Symfony2 form type entity add extra option


I have the following Symfony form field, it's a drop down that loads from an entity:

->add('measureunit', 'entity', array('label' => 'Measure Unit',
            'class' => 'TeamERPBaseBundle:MeasureUnit',
            'expanded' => false, 'empty_value' => '',
            'multiple' => false, 'property' => 'abreviation'
        ))

As you can see I have added 'empty_value' => '' and everything works fine. Now, what I want is to have an extra option at the end to add a let say new measure unit. In other words the dropdown should display all the content of my entity, the empty value and other extra option called new measure unit or what ever I want to call it. Is it possible?

Edit: The whole form type file has this:

<?php
namespace TeamERP\StoresBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class ProductType  extends AbstractType 
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
        ->add('name', 'text', array('label'=>'Product name', 'required' => true,
        'attr' => array('class' => 'form-control')))
        ->add('code', 'text', array('label'=>'Code', 'required' => false,
        'attr' => array('class' => 'form-control')))
        ->add('description', 'text', array('label'=>'Description', 'required' => false,
        'attr' => array('class' => 'form-control')))
        ->add('cost', 'money', array('label'=>'Cost', 'divisor' => 100, 'currency' => 'BWP'))
        ->add('category', new CategoryType(), array('required' => false))
        ->add('measureunit', 'entity', array('label' => 'Measure Unit',
            'class' => 'TeamERPBaseBundle:MeasureUnit',
            'expanded' => false, 'placeholder' => '',
            'multiple' => false, 'property' => 'abreviation'
        ))
        ->add('qtyToPurchase', 'number', array('label'=>'Quantity to purchase', 'required' => false,
        'attr' => array('class' => 'form-control')))
        ->add('reorderPoint', 'number', array('label'=>'Reorder point', 'required' => false,
        'attr' => array('class' => 'form-control')))
        ->add('qtyOnSalesOrder', 'number', array('label'=>'Quantity on sales order', 'required' => false,
        'attr' => array('class' => 'form-control')));
    }
public function getName()
    {
        return 'product';
    }
public function finishView(FormView $view, FormInterface $form, array $options)
    {
        $new_choice = new ChoiceView(array(), 'add', 'add new'); // <- new option
        $view->children['measureunit']->vars['choices'][] = $new_choice;//<- adding the new option 
    }
}

Error: Compile Error: Declaration of TeamERP\StoresBundle\Form\Type\ProductType::finishView() must be compatible with Symfony\Component\Form\FormTypeInterface::finishView(Symfony\Component\Form\FormView $view, Symfony\Component\Form\FormInterface $form, array $options)

Edit2 Working form file:

<?php
namespace TeamERP\StoresBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormView; 
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\Extension\Core\View\ChoiceView;
class ProductType  extends AbstractType 
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
        ->add('name', 'text', array('label'=>'Product name', 'required' => true,
        'attr' => array('class' => 'form-control')))
        ->add('code', 'text', array('label'=>'Code', 'required' => false,
        'attr' => array('class' => 'form-control')))
        ->add('description', 'text', array('label'=>'Description', 'required' => false,
        'attr' => array('class' => 'form-control')))
        ->add('cost', 'money', array('label'=>'Cost', 'divisor' => 100, 'currency' => 'BWP'))
        ->add('category', new CategoryType(), array('required' => false))
        ->add('measureunit', 'entity', array('label' => 'Measure Unit',
            'class' => 'TeamERPBaseBundle:MeasureUnit',
            'expanded' => false, 'placeholder' => '',
            'multiple' => false, 'property' => 'abreviation'
        ))
        ->add('qtyToPurchase', 'number', array('label'=>'Quantity to purchase', 'required' => false,
        'attr' => array('class' => 'form-control')))
        ->add('reorderPoint', 'number', array('label'=>'Reorder point', 'required' => false,
        'attr' => array('class' => 'form-control')))
        ->add('qtyOnSalesOrder', 'number', array('label'=>'Quantity on sales order', 'required' => false,
        'attr' => array('class' => 'form-control')));
    }
public function getName()
    {
        return 'product';
    }
public function finishView(FormView $view, FormInterface $form, array $options)
    {
        $new_choice = new ChoiceView(array(), 'add', 'add new'); // <- new option
        $view->children['measureunit']->vars['choices'][] = $new_choice;//<- adding the new option 
    }
}

Solution

  • In your form type override the function finishView:

    public function buildForm(FormbuilderInterface $builder, array $options){
        $builder->add('measureunit', EntityType::class, array(
            'label' => 'Measure Unit',
            'class' => 'TeamERPBaseBundle:MeasureUnit',
            'expanded' => false, 
            'empty_value' => '',
            'multiple' => false, 
            'property' => 'abbreviation'
        ));
    }
    
    public function finishView(FormView $view, FormInterface $form, array $options)
    {
        $newChoice = new ChoiceView(array(), 'add', 'Add New'); // <- new option
        $view->children['measureunit']->vars['choices'][] = $newChoice;//<- adding the new option 
    }
    

    You will get a new option 'add new' with value 'add' to the bottom of the field.