Syllz
Syllz

Reputation: 340

Symfony Forms: Collection - Just Add New Entries / Prevent Modifying Old Entries

I got a problem in my project and dont really know how to fix it. Maybe my approach is completely wrong and I should go another direction.


I have two Entities: Article & ArticleComment

In my ArticleType I add the Comments with a CollectionType (main reason for this is that I also want to modify the Article - basically change Article stuff and also be able to add 1 comment):

//ArticleType.php
$builder->add('articleComments', CollectionType::class, ['label' => false, 'entry_type' => AritcleCommentType::class, 'entry_options' => ['label' => false]]);

My ArticleCommentType is just a textarea field:

//ArticleCommentType.php
$builder->add('text', TextareaType::class, ['label' => 'comment', 'required' => false, 'attr' => ['class' => 'textarea-sm']]);

This solution works perfectly for me.

However, whenever I add a comment, my other comments are also rendered in a textarea field and can be edited, which I do not want. I simple want the user to add 1 comment, reload the page and maybe add another comment thats it.

I already tried to prevent rendering the other comments, but this throws an error, since the element is not in the DOM anymore - but still expected.

Any ideas how to fix this? (Hiding the fields is no valid solution for me)


Update:

My controller:

//ArticleController.php

...

/**
 * @Route("/article/{id}", name="app_article", requirements={"id"="\d+"})
 */
public function article(Request $request, Article $article)
{
    $articleComment = new ArticleComment();
    $article->addArticleComment($articleComment);

    $form = $this->createForm(ArticleType::class, $article);
    $form->handleRequest($request);

            if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($articleComment); //cascade not active
            $em->persist($article);
            $em->flush();
            $this->addFlash('success', 'entry_saved');
            return $this->redirectToRoute('app_article', ['id' => $article->getId()]);
        }
        return $this->render('article/view.html.twig', ['article' => $article, 'form' => $form->createView()]);
}

...

Changed ArticleType:

$builder->add('articleComments', ArticleCommentType::class, ['label' => false, 'data' => new ArticleComment()]); //changed as suggested

Upvotes: 0

Views: 826

Answers (1)

DonCallisto
DonCallisto

Reputation: 29942

As long as you use

$builder
  ->add('articleComments', CollectionType::class, [
    'label' => false, 
    'entry_type' => AritcleCommentType::class, 
    'entry_options' => ['label' => false],
    'mapped' => false,
  ]);

you'll render the whole collection.

To me the best fitting solution is to add directly ArticleCommentType with data attribute sette to new ArticleComment.

If you want to display all the comments, you should do directly in the template passing all existing ArticleComment displaying what you need to display.

Only thing you should take care is to manually add (maybe in a form subscriber) the brand new element (if has any value) to existing collection.

Upvotes: 2

Related Questions