bface007
bface007

Reputation: 67

symfony 2 jquery bootstrap tag input

I have two entities: BlogPost and Keyword in manytomany relationship. I have to use a form to add BlogPost and Keywords in database at the same time. I want to use a jquery tag input plugin like Bootstrap tagsinput to insert keywords in input. How can I implement it please? There are my entities:

class BlogPost
{
    //...
    /**
    * @var \Doctrine\Common\Collections\ArrayCollection
    * @ORM\ManyToMany(targetEntity="ESGISGabon\PostBundle\Entity\Keyword", cascade={"persist"})
    */
    private $keywords;

    public function __construct()
    {
        $this->keywords = new \Doctrine\Common\Collections\ArrayCollection();
    }

    public function getKeywords()
    {
        return $this->keywords;
    }
}


class Keyword
{
    /**
    * @var string
    * @ORM\Column(type="string", name="category_title", nullable=false, length=30)
    */
    protected $title;

    public function getTitle()
    {
        return $this->title;
    }
}

Upvotes: 1

Views: 805

Answers (1)

bface007
bface007

Reputation: 67

I finally found a solution for my problem. I had to use Data transformer and a custom form field type. I also use FPNTagBundle and its tagManager. This is the way I've done it:

class TagsTransformer implements DataTransformerInterface
{

    private $tagManager;

    public function __construct(TagManager $tagManager)
    {
        $this->tagManager = $tagManager;
    }

    /**
     * Transforms a value from the original representation to a transformed representation.
     *
     * By convention, transform() should return an empty string if NULL is
     * passed.
     *
     * @param mixed $value The value in the original representation
     *
     * @return mixed The value in the transformed representation
     *
     * @throws TransformationFailedException When the transformation fails.
     */
    public function transform($tags)
    {
        if(!is_null($tags))
            return join(', ', $tags->toArray());

        return '';
    }

    /**
     * Transforms a value from the transformed representation to its original
     * representation.
     *
     * By convention, reverseTransform() should return NULL if an empty string
     * is passed.
     *
     * @param mixed $value The value in the transformed representation
     *
     * @return mixed The value in the original representation
     *
     * @throws TransformationFailedException When the transformation fails.
     */
    public function reverseTransform($tags)
    {
        if(is_null($tags) || !$tags)
            return;

        return $this->tagManager->loadOrCreateTags(
            $this->tagManager->splitTagNames($tags)
        );
    }
}


class TagType extends AbstractType
{

    protected $tagManager;

    public function __construct(TagManager $tagManager)
    {
        $this->tagManager = $tagManager;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $transformer = new TagsTransformer($this->tagManager);
        $builder->addModelTransformer($transformer);
    }


    public function getName()
    {
        return 'tags';
    }

    public function getParent()
    {
        return 'text';
    }
}

And finally my form is like this:

class CorporatePostType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('keywords', 'tags');
    }

    //.....
}

You would have to create a custom template for your custom form field type for the integration of Bootstrap tagsinput.

Upvotes: 1

Related Questions