Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Hidden field for Symfony2 entities
<?php
namespace Dpn\ToolsBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Dpn\ToolsBundle\Form\DataTransformer\EntityToIdTransformer;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Doctrine\Common\Persistence\ObjectManager;
class EntityHiddenType extends AbstractType
{
/**
* @var ObjectManager
*/
protected $objectManager;
public function __construct(ObjectManager $objectManager)
{
$this->objectManager = $objectManager;
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$transformer = new EntityToIdTransformer($this->objectManager, $options['class']);
$builder->addModelTransformer($transformer);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver
->setRequired(array('class'))
->setDefaults(array(
'invalid_message' => 'The entity does not exist.',
))
;
}
public function getParent()
{
return 'hidden';
}
public function getName()
{
return 'entity_hidden';
}
}
<?php
namespace Dpn\ToolsBundle\Form\DataTransformer;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Doctrine\Common\Persistence\ObjectManager;
class EntityToIdTransformer implements DataTransformerInterface
{
/**
* @var ObjectManager
*/
protected $objectManager;
/**
* @var string
*/
protected $class;
public function __construct(ObjectManager $objectManager, $class)
{
$this->objectManager = $objectManager;
$this->class = $class;
}
public function transform($entity)
{
if (null === $entity) {
return;
}
return $entity->getId();
}
public function reverseTransform($id)
{
if (!$id) {
return null;
}
$entity = $this->objectManager
->getRepository($this->class)
->find($id);
if (null === $entity) {
throw new TransformationFailedException();
}
return $entity;
}
}
@Lughino

This comment has been minimized.

Copy link

commented Feb 25, 2013

Great job!
One question, how do I pass the class?

@tfernandez

This comment has been minimized.

Copy link

commented May 6, 2013

Worked like a charm! Thanks!

Remember add the service in the bundle services.yml to allow use the new field type

services:
 acme_demo.type.entity_hidden:
   class: Acme\DemoBundle\Form\Type\EntityHiddenType
   arguments: ["@doctrine.orm.entity_manager"]
   tags:
   - { name: form.type, alias: entity_hidden }

add the services.yml to the config.yml imports:

 imports:
  - { resource: "@AcmeDemoBundle/Resources/config/services.yml" }

Modify the namespaces to fit with your bundle structure

and just add a new "entity_hidden" field to the form in this way:

    $builder
            ->add('email')
            ->add('name')
            ->add('car', 'entity_hidden', array(
                'class' => 'Acme\DemoBundle\Entity\Car'
            ))

More info about apply the DataTransformer in the symfony2 Docs:

http://symfony.com/doc/current/cookbook/form/data_transformers.html#creating-the-transformer

@lmejiahn

This comment has been minimized.

Copy link

commented May 7, 2013

It worked!, thanks @dreipunktnull

@caiomoritz

This comment has been minimized.

Copy link

commented May 11, 2013

It worked for me as well, thanks.

@Tocacar

This comment has been minimized.

Copy link

commented May 14, 2013

I found this very useful - thanks!

@gffranco

This comment has been minimized.

Copy link

commented May 15, 2013

Thanks for sharing this, it helped a lot!

@wagnerpinheiro

This comment has been minimized.

Copy link

commented Dec 10, 2013

Thanks! very useful...

@igormancos

This comment has been minimized.

Copy link

commented Dec 13, 2013

Thanks, is fine!

@alfchee

This comment has been minimized.

Copy link

commented Jan 10, 2014

Do you guess this works the same if I only change the argument for ODM? Meaning, changing this in the configuration of the service: arguments: ["@doctrine.odm.mongodb.document_manager"]

@mdjaman

This comment has been minimized.

Copy link

commented Feb 9, 2014

Excuse my questions, im new to symfony. How can i pass some options to the form since i used this in controller?

private function createEditForm(Sms $entity)
{
        $form = $this->createForm(new SmsType(), $entity, array(
            'action' => $this->generateUrl('sms_update', array('id' => $entity->getId())),
            'method' => 'PUT',
        ));

        $form->add('submit', 'submit', array('label' => 'Update'));

        return $form;
 }
@bjo3rnf

This comment has been minimized.

Copy link
Owner Author

commented Feb 9, 2014

Wow, I didn't notice all those comments. Thanks and sorry for not answering some of them.

@alfchee: yes, that should work as well.
@mdjaman: what kind of options do you mean?

@mdjaman

This comment has been minimized.

Copy link

commented Feb 9, 2014

Thx 4 answering. I need to pass user entity

@mdjaman

This comment has been minimized.

Copy link

commented Feb 9, 2014

Thx found what i was looking for. Thought that only instance of AbstractType could be passed in

$this->createForm('acme_userbundle_sms', $entity, array(
            'action' => $this->generateUrl('sms_create'),
            'method' => 'POST',
        ));
```php
form_name 'acme_userbundle_sms' could be passed. Thks for your time
@mellivora-capensis

This comment has been minimized.

Copy link

commented Feb 15, 2014

Thanks, dude =)

@AhmedSamy

This comment has been minimized.

Copy link

commented Feb 16, 2014

  • 1 cheers !
@jamogon

This comment has been minimized.

Copy link

commented Mar 5, 2014

Thanks!!! Great Job!!!

If the user doesn't write the class option:

$builder
        ->add('car', 'hidden_entity', array())
;

the class is null and the transformation throws the next error:
Class '' does not exist

If the user uses the method setRequired() in EntityHiddenType file:

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver
        ->setRequired(array('class'))
        ->setDefaults(array(
            'invalid_message' => 'The entity does not exist.',
        ))
    ;
}

the application throws a 500 error with the next information:
The required option "class" is missing.

@bjo3rnf

This comment has been minimized.

Copy link
Owner Author

commented Mar 30, 2014

Hi @jamogon,

thanks for the hint. I updated the Gist accordingly. Didn't even know about the setRequired() method of the OptionsResolver.

Cheers
Björn

@skonsoft

This comment has been minimized.

Copy link

commented Oct 20, 2014

Great Job !!

Thank you !

Why Symfony community would not integrate this solution. it's very useful !

@webdevilopers

This comment has been minimized.

Copy link

commented Nov 27, 2014

👍

Did you ever propose this improvement to Symfony, @bjo3rnf ?

There also seems to be a simple workaround using the property_path:

$builder->add('entity', 'hidden', array('property_path' => 'entity.id'));

as mentioned by @webmozart here:
symfony/symfony#3182

And it looks like it is finally going to make it into symfony here:
symfony/symfony#8293

@neonxp

This comment has been minimized.

Copy link

commented May 25, 2015

Thank you! Works great!

@shakogele

This comment has been minimized.

Copy link

commented Jul 28, 2015

How to pass default value to Hidden_entity field? for eg. I have test controller which has field Author. Author I am getting from db after user logs in to system.

@gastoncs

This comment has been minimized.

Copy link

commented Aug 26, 2015

How can I set an entity in a onPreSubmit or preSetData and have it attach to the form entity?

@xanaxilovsky

This comment has been minimized.

Copy link

commented Jan 25, 2016

Thanks! It helped a lot!

I forked it to make it compatible with symfony 2.8 ( https://gist.github.com/xanou/e630e4e25df60d33b050 )

@runciters

This comment has been minimized.

Copy link

commented Sep 29, 2016

Thanks, you made my day!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.