Alex Rivera | Logout

Symfony 2 Entity field type with select and/or add new

Asked 2013-03-28T13:00:23.530
11

Context:

Let there be two entities (correctly mapped for Doctrine).

  1. Post with properties {$id (integer, autoinc), $name (string), $tags (collection of Tag)}
  2. Tag with properties {$id (integer, autoinc), $name (string), $posts (collection of Post)}

Relationship between these two is Many-To-Many.

Problem:

When creating a new Post, I want to immediately add tags to it.

If I wanted to add Tags that already are peristed, I would create entity field type, no problem with that.

But what would I do, if I wanted to add completely new Tags too? (Check some of already existing tags, fill name for new tag, maybe add some another new tag, then after submit assign everyting properly to Post entity)

    Create new Post:
     Name: [__________]

    Add tags
    |
    |[x] alpha
    |[ ] beta
    |[x] gamma
    |
    |My tag doesnt exist, create new:
    |
    |Name: [__________]
    |
    |+Add another new tag

Is there any way to do this? I know the basics of Symfony 2, but have no idea how to deal with this. Also surprised me I havent found my answer anywhere, seems like a common problem to me. What am I missing?

Edit
Report

1 Answer

10

My Tag entity has a unique field for the tag name. For add Tags I use a new form type and a transformer.

The Form Type:

namespace Sg\RecipeBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Bridge\Doctrine\RegistryInterface;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Sg\RecipeBundle\Form\DataTransformer\TagsDataTransformer;

class TagType extends AbstractType
{
    /**
     * @var RegistryInterface
     */
    private $registry;

    /**
     * @var SecurityContextInterface
     */
    private $securityContext;


    /**
     * Ctor.
     *
     * @param RegistryInterface        $registry        A RegistryInterface instance
     * @param SecurityContextInterface $securityContext A SecurityContextInterface instance
     */
    public function __construct(RegistryInterface $registry, SecurityContextInterface $securityContext)
    {
        $this->registry = $registry;
        $this->securityContext = $securityContext;
    }

    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->addViewTransformer(
            new TagsDataTransformer(
                $this->registry,
                $this->securityContext
            ),
            true
        );
    }

    /**
     * {@inheritdoc}
     */
    public function getParent()
    {
        return 'text';
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'tag';
    }
}

The Transformer:

<?php

/*
 * Stepan Tanasiychuk is the author of the original implementation
 * see: https://github.com/stfalcon/BlogBundle/blob/master/Bridge/Doctrine/Form/DataTransformer/EntitiesToStringTransformer.php
 */

namespace Sg\RecipeBundle\Form\DataTransformer;

use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Security\Core\S
answered 2013-03-28T13:27:13.403

Your Answer