Symfony:如何在单页上显示和处理多个编辑表单

问题描述 投票:0回答:1

我遇到了以下问题。

我正在使用Symfony 4.2.3来构建一个论坛(一个更大的项目)

我做了一个处理的ForumController:

  • 论坛主页(显示论坛分类及其forumSubCategories)
  • 论坛类别页面(用她的forumSubCategories显示选定的forumCategory)
  • 论坛子类别页面(显示所选forumSubCategory与她的论坛主题)
  • 论坛主题页面(显示所选论坛与她的forumMessage(即反应))

我想要的是实现一个编辑按钮,该按钮不会重定向到编辑页面,而是$(this).slidedown在div中的编辑表单。仅当ForumMessage作者是当前登录用户时,才会显示此按钮。因此,如果该用户有很多时间回复该主题,我需要尽可能多的按钮(和表单)。点击编辑后,页面可以重新加载和实体更新。

对于使用重定向创建/编辑我已经理解了如何。

问题是,如何处理未知数量的编辑MessageType表单(以及未知的表单id)。

我尝试创建一个ForumMessage数组的链接到MessageType Form数组。但是当我必须将每个表单的.createView()赋予树枝时,我的大脑才会出现故障。

那么请问,我怎样才能在单个页面上有很多编辑表单(每个链接到被引用的实体)并在我的控制器中处理它们以进行.flush修改?

我已经为按钮和链接div的diplaying实现了JS函数。

我的ForumController.php的showTopic方法:

/**
 * @Route("/forum/category={idCategory}/subCategory={idSubCategory}/topic={idTopic}", name="topic")
 * @ParamConverter("topic", options={"id" = "idTopic"})
 * @param $idCategory
 * @param $idSubCategory
 * @param $idTopic
 * @param Request $request
 * @param ObjectManager $manager
 * @param UserInterface $user
 * @return \Symfony\Component\HttpFoundation\Response
 * @throws \Exception
 */
public function showTopic($idCategory, $idSubCategory, $idTopic, Request $request, ObjectManager $manager, UserInterface $user = null) {
    $topic = $this->getDoctrine()->getRepository(ForumTopic::class)->find($idTopic);
    $userMessages = $this->getDoctrine()->getRepository(ForumMessage::class)->findBy([
        'author' => "Kaarie",
        'forumTopic' => $topic
    ]);

    // Nouveau message sur un topic
    $message = new ForumMessage();
    $form = $this->createForm(ForumMessageType::class, $message);
    $form->handleRequest($request);
    if($form->isSubmitted() && $form->isValid()) {
        $message->setAuthor($user->getUsername())
                ->setCreatedAt(new \DateTime())
                ->setForumTopic($topic);
        $manager->persist($message);
        $manager->flush();

        return $this->redirectToRoute('topic', [
            'idCategory' => $idCategory,
            'idSubCategory' => $idSubCategory,
            'idTopic' => $topic->getId(),
        ]);
    }

    // Editer un message
    $editMessage = new ForumMessage();
    $editForm = $this->createForm(ForumMessageType::class, $editMessage);
    $editForm->handleRequest($request);
    if($editForm->isSubmitted() && $editForm->isValid()) {
        $manager->persist($editMessage);
        $manager->flush();

        return $this->redirectToRoute('topic', [
            'idCategory' => $idCategory,
            'idSubCategory' => $idSubCategory,
            'idTopic' => $topic->getId(),
        ]);
    }

    return $this->render('forum/showTopic.html.twig',[
        'idCategory' => $idCategory,
        'idSubCategory' => $idSubCategory,
        'topic' => $topic,
        'messageForm' => $form->createView(),
        'editForm' => $editForm->createView(),
        'userMessage' => $userMessages,
    ]);
}

MessageType.php中的MessageType类

class ForumMessageType extends AbstractType
{
   public function buildForm(FormBuilderInterface $builder, array $options)
   {
      $builder
        ->add('content')
        ->add('submit', SubmitType::class)
    ;
   }

   public function configureOptions(OptionsResolver $resolver)
   {
      $resolver->setDefaults([
        'data_class' => ForumMessage::class,
      ]);
   }
}

从showTopic.html.twig显示消息的树枝部分

    <ul>
        {% for message in topic.ForumMessages %}
            <li>
                {{ message.author }},</br>
                {{ message.content }}
                {% if app.user %}
                    {% if is_granted("ROLE_MODERATOR") %}

                        <button>Moderate</button> {# TODO: moderation d'un message #}
                    {% endif %}
                    {% if app.user.username == message.author %}
                        <div  class="alert alert-danger" style="margin: 1em; display: none">
                            <h3>Etidé votre réponse :</h3>
                            {{ form_start(editForm) }}
                            {{ form_row(editForm.content) }}
                            {{ form_row(editForm.submit, {'label': 'Editer'}) }}
                            {#<button type="submit" class="btn btn-primary">Editer</button>#}
                            {{ form_end(editForm) }}
                        </div>
                        <button id="buton_EditTopic">Modifier</button>
                    {% endif %}
                {% endif %}
            </li>
        {% endfor %}
    </ul>

对于任何其他资源,请问我!

forms symfony user-interface symfony-forms forum
1个回答
0
投票

我的方法是(可能需要一些调整,没有测试)

简写说明:该列表仅包含容器。编辑一条消息时,只加载表单并将其推送到此特定容器。如果你编辑它并按保存,它会将每个ajax请求的表单发送给控制器。如果表单有效,它将返回一个json repsonse而不是html ...

控制器:

/**
 * @Route("/forum/category={idCategory}/subCategory={idSubCategory}/topic={idTopic}", name="topic")
 * @ParamConverter("topic", options={"id" = "idTopic"})
 * @param $idCategory
 * @param $idSubCategory
 * @param $idTopic
 * @param Request $request
 * @return \Symfony\Component\HttpFoundation\Response
 * @throws \Exception
 */
public function showTopic(
    $idCategory, 
    $idSubCategory, 
    $idTopic, 
    Request $request, 
    ObjectManager $manager, 
    UserInterface $user = null
)
{
    $topic = $this->getDoctrine()->getRepository(ForumTopic::class)->find($idTopic);
    $userMessages = $this->getDoctrine()->getRepository(ForumMessage::class)->findBy([
        'author' => "Kaarie",
        'forumTopic' => $topic
    ]);

    return $this->render('forum/showTopic.html.twig',[
        'idCategory' => $idCategory,
        'idSubCategory' => $idSubCategory,
        'topic' => $topic,
        'userMessage' => $userMessages,
    ]);
}

/**
 * With this, you can create and mod Topics
 * @Route("/forum/messages/{forumMessage}/mod-message", name="message.mod", defaults={"forumMessage":0})
 * @IsGranted("ROLE_USER")
 * @param Request $request
 * @param ForumMessage $forumMessage
 * @return mixed
 */
public function modTopic(
    Request $request, 
    Objectmanager $manager, 
    ForumMessage $forumMessage=null
)
{

    if($formMessage == null) {
        $forumMessage = new ForumMessage();
        /* set Additional Info here, maybe User, IP Adress or whatever */
    }
    $editForm = $this->createForm(ForumMessageType::class, $forumMessage);
    $editForm->handleRequest($request);
    if($editForm->isSubmitted() && $editForm->isValid()) {
        $manager->persist($forumMessage);
        $manager->flush();

        return new JsonRepsonse(['status'=>true, 'message' => "ForumMessage save successfull"]);
    }


    return $this->render('mod.message.html.twig',[
        'messageForm' => $editForm->createView(),
    ]);
}

FormType:

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

   public function configureOptions(OptionsResolver $resolver)
   {
      $resolver->setDefaults([
        'data_class' => ForumMessage::class,
      ]);
   }
}

list.html.twig

<ul>
    {% for message in topic.ForumMessages %}
        <li>
            {{ message.author }},</br>
            {{ message.content }}
            {% if app.user %}
                {% if is_granted("ROLE_MODERATOR") %}

                    <button>Moderate</button> {# TODO: moderation d'un message #}
                {% endif %}
                {% if app.user.username == message.author %}
                    <div id="modMessageContainer{{ message.id }}"  class="alert alert-danger" style="margin: 1em; display: none">
                    </div>
                    <button onclick="modMessage(this);" 
                         data-attr-url="{{ path('message.mod'.{'forumMessage':message.id}) }}" 
                         data-attr-container="#modMessageContainer{{ message.id }}"
                    >Modifier</button>
                {% endif %}
            {% endif %}
        </li>
    {% endfor %}
</ul>
<script>
    function modMessage(element)
    {
        $.ajax({
            url: $(element).attr('data-attr-url'),
            success: function(data) {
                $($(element).attr('data-attr-container')).html(data).show();
            }
        });
    }

    function saveMessage(element)
    {
        var container = $(element).attr('data-attr-container');
        $.ajax({
            url: $(element).attr('data-attr-url'),
            type:'POST',
            data: $(container +' form').serialize(),
            success: function(data) {
                if(typeof data == 'object' && data instanceof Object && !(data instanceof Array)) {
                    if(data.status) {
                        location.reload()
                    } else {
                        alert(data.message);
                    }
                } else {
                    $(container).show();
                    $('#modMessage').replaceWith($(data).find('#modMessage'));
                }
            }
        });
    }
</script>

mod.html.twig

<div>
    <div id="modMessage">
        <h3>Etidé votre réponse :</h3>
        {{ form_start(editForm) }}
        {{ form_row(editForm.content) }}
        {{ form_row(editForm.submit, {'label': 'Editer'}) }}
        {#<button type="submit" class="btn btn-primary">Editer</button>#}
        {{ form_end(editForm) }}
        <div style="text-align:right">
            <button onclick="saveMessage(this);" 
                 type="button" 
                 class="btn btn-success" 
                 data-attr-container="modMessageContainer{{ message.id }}" 
                 data-attr-url="{{ path('message.mod', {'forumMessage':message.id}) }}"
             >Save</button>
        </div>
    </div>
</div>
© www.soinside.com 2019 - 2024. All rights reserved.