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



我遇到以下问题。

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

我做了一个论坛控制器,他处理:

  • 论坛主页(与他们的论坛的表演表演)
  • 论坛类别页面(与她的论坛访问符号一起显示选定的论坛类别)
  • 论坛子类别页面(与她的论坛图一起显示选定的论坛范围)
  • 论坛主题页面(与她的forummessage一起显示选定的论坛(即反应))

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

为了通过重定向创建/编辑,我了解了如何。

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

我已经尝试创建一个forummessage链接的数组,以指向MessageType表单的数组。但是,当我必须将每种形式的.createview()给小树枝时,我的大脑故障。

请,请在Sigle页面上(每个链接指向已引用实体)上有许多编辑表单并在控制器中处理。

我已经实现了JS功能以进行按钮外交和链接div。

我的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 SymfonyComponentHttpFoundationResponse
 * @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中的类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>

对于任何其他ressources,请问我!

我的方法是(也许有些调整是必要的,没有测试)

简短的解释:该列表仅包含容器。当您编辑一条消息时,只需加载表单并将其推到此特定容器。如果您对此进行编辑并按"保存",则将每个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 SymfonyComponentHttpFoundationResponse
 * @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>

最新更新