จะส่งและคงแบบฟอร์ม Symfony และแบบฟอร์มซ้อนเพิ่มเติมได้อย่างไร

ฉันใช้แบบฟอร์มสองประเภทสำหรับหนึ่งหน้าในโครงการ Symfony ของฉัน ฉันทำเช่นนี้เพื่อให้ผู้ใช้ตัดสินใจระหว่างสองตัวเลือกในการสร้างเอกสารใหม่ ประเภทแบบฟอร์ม

วิธีสร้างเพจ: มีช่องข้อความหลายช่องที่ต้องกรอก ทั้งหมดเป็นของ DocumentCreateType ของฉัน และยังรวมส่วนที่ถูกต้องของตัวเลือกด้วย (เลือก IATA ด้วยตนเอง) ที่คุณเห็นในภาพ แบบฟอร์มประเภทที่สองของฉัน (UploadProfileType) มีเมนูแบบเลื่อนลงสามรายการเหมือนกันบวกกับรายการเพิ่มเติม (ตลาด ช่องทาง1 และผลิตภัณฑ์) แต่อยู่ที่ไซต์ด้านซ้ายของตัวเลือก (ใช้โปรไฟล์อัปโหลด)

ดังนั้น ขึ้นอยู่กับสิ่งที่ผู้ใช้เลือก จะต้องส่งเฉพาะ DocumentCreateType หรือแบบฟอร์มทั้งสองประเภทต้องถูกส่งและคงอยู่

ฉันจะทำให้สิ่งนี้ทำงานในคอนโทรลเลอร์ของฉันได้อย่างไร จนถึงตอนนี้คอนโทรลเลอร์ของฉันดูเหมือนเป็นเช่นนั้น แต่ข้อมูลไม่ถูกต้อง

  $upForm = $this->createForm(UploadProfileType::class, $document, array('user' => $currentuser));
    $form = $this->createForm(DocumentCreateType::class, $document);

      $form->handleRequest($request);
     $upForm->handleRequest($request); 

    if ($form->isSubmitted() && $form->isValid())
    {
    ...
    }

ChoiceType สำหรับตัวเลือกระหว่างโปรไฟล์การอัปโหลดและ IATA มีลักษณะเช่นนั้นและจัดการโดย javascript:

  $builder

        ->add('use_upload_profile', ChoiceType::class, array(
                  'choices' => array(
                      true => 'label.use_upload_profile',
                      false => 'label.select_iatas_manually'
                  ),
                  'mapped' => false,
                  'expanded' => true,
                  'label' => false,
                  'data' => true,
                  'translation_domain' => 'Documents'))

            ;
          }

person sonja    schedule 19.12.2017    source แหล่งที่มา
comment
สร้างปุ่มตัวเลือกอย่างง่ายในมุมมองของคุณและในการตรวจสอบคอนโทรลเลอร์ของคุณซึ่งถูกเลือกและทำสิ่งต่าง ๆ ด้วยคำตอบ...   -  person Smaïne    schedule 19.12.2017
comment
@ Smaïneคำตอบไหน? หรือคุณหมายถึงอะไร?   -  person sonja    schedule 19.12.2017


คำตอบ (2)


หลายรูปแบบ

ใน HTTP คุณสามารถส่งแบบฟอร์มได้เพียงแบบฟอร์มเดียวตามคำขอ

สร้างจุดสิ้นสุดสำหรับการส่งแบบฟอร์มแต่ละรายการโดยที่คุณส่งแบบฟอร์มเดียวเท่านั้น

สร้างเอกสาร A -> createADocumentAction()

สร้างเอกสาร B -> createBDocumentAction()

รูปแบบเดียวที่มีทุกสิ่ง

หากคุณกำลังเรียกแบบฟอร์มไปยังชุดข้อมูล แต่ทุกอย่างถูกส่งด้วยคำขอเดียว คุณควรสร้าง Symfony From (ประเภท) ที่มีข้อมูลทั้งหมดของแบบฟอร์ม Symfony ทั้งสองที่คุณวางแผนจะส่ง

person albert    schedule 19.12.2017
comment
ฉันไม่สามารถใช้แบบฟอร์มเดียวได้ เนื่องจากฉันใช้ EntityTypes ของเอนทิตีเดียวกันในสองแบบฟอร์มของฉัน ด้วยรูปแบบเดียว ฉันจึงไม่สามารถมีสองรายการแบบเลื่อนลงสำหรับเอนทิตีเดียวกันได้ .. วิธีการหลายรูปแบบดูเหมือนจะซ้ำซ้อนมากเนื่องจากเป็นเพียงส่วนเล็ก ๆ ของการดำเนินการเท่านั้น .. - person sonja; 19.12.2017
comment
คุณสามารถมีรายการแบบเลื่อนลงได้มากเท่าที่คุณต้องการในแบบฟอร์ม ไม่ว่าเอนทิตีจะเป็นประเภทใดก็ตาม - person albert; 20.12.2017
comment
ไม่ ฉันไม่สามารถมีรายการแบบเลื่อนลงสองรายการจากเอนทิตีเดียวกันได้ ฉันไม่ต้องทำการตลาดแบบเลื่อนลง - person sonja; 20.12.2017
comment
โปรดอัปโหลดแบบฟอร์มของคุณสำหรับคำถามของคุณ แล้วเราจะอัปเดตโค้ดสำหรับการมีหลายรายการแบบเลื่อนลง - person albert; 20.12.2017

คุณไม่สามารถส่งแบบฟอร์มสองฉบับพร้อมกันได้ เนื่องจากจะต้องส่งอย่างใดอย่างหนึ่ง ดังนั้นฉันขอแนะนำให้คุณสร้างรูปแบบที่แตกต่างกันสองแบบ:

  • รายการแรกจะถูกส่งเมื่อเลือก "ใช้โปรไฟล์การอัปโหลด"

  • ส่วนที่สองจะถูกส่งเมื่อเลือก "เลือก IATA ด้วยตนเอง"

ในแต่ละแบบฟอร์มคุณต้องส่งข้อมูลทั้งหมดเพื่อส่ง หากคุณต้องการหลีกเลี่ยงรหัสที่ซ้ำกันใน FormType คุณสามารถสร้างประเภทแบบฟอร์มแบบกำหนดเองได้ (ไม่เกี่ยวข้องกับเอนทิตี):

<?php
// src/AppBundle/Form/Custom/CustomFormType.php

namespace AppBundle\Form\Custom;

use Symfony\Component\Form\Extension\Core\Type\FormType;

class CustomFormType
{
    /**
     * Create the 'upload profile' custom form (not associated to a class)
     * 
     * @param type $formFactory
     * @param type $defaultData
     * @return type
     */
    public function createUploadProfileCustomForm($formFactory, $defaultData)
    {
        /* Create the 'upload profile' form (not associated to a class) */
        $form = $formFactory->createBuilder(FormType::class, $defaultData, array());

        $this->addMarkets($form);
        $this->addChannel1($form);
        $this->addProducts($form);

        /* Add whatever other field necessary */
        $form->add(...);

        /* Return the form */
        return $form->getForm();
    }

    /**
     * Create the 'select IATA manually' custom form (not associated to a class)
     * 
     * @param type $formFactory
     * @param type $defaultData
     * @return type
     */
    public function createSelectIATAManuallyCustomForm($formFactory, $defaultData)
    {
        /* Create the 'select IATA manually' form (not associated to a class) */
        $form = $formFactory->createBuilder(FormType::class, $defaultData, array());

        $this->addMarkets($form);
        $this->addChannel1($form);
        $this->addProducts($form);

        /* Add whatever other field necessary */
        $form->add(...);

        /* Return the form */
        return $form->getForm();
    }

    protected function addMarkets($form)
    {
        $form->add('markets', ...
            /* To complete */
        );
    }

    protected function addChannel1($form)
    {
        $form->add('channel1', ...
            /* To complete */
        );
    }

    protected function addProducts($form)
    {
        $form->add('products', ...
            /* To complete */
        );
    }
}

ในการจัดการทั้งสองรูปแบบในคอนโทรลเลอร์:

/* Create the 'upload profile' form (not associated to a class) */
$defaultDataUP = array(...);
$customFormTypeUP = new CustomFormType();
$formUploadProfile = $customFormTypeUP->createUploadProfileCustomForm($this->get('form.factory'), $defaultDataUP);
$formUploadProfile ->handleRequest($request);

/* Create the 'select IATA manually' form (not associated to a class) */
$defaultDataSM = array(...);
$customFormTypeSM = new CustomFormType();
$formSelectManually = $customFormTypeSM->createSelectIATAManuallyCustomForm($this->get('form.factory'), $defaultDataSM);
$formSelectManually ->handleRequest($request);

/* If the user selected 'upload profile' and submitted the associated form */
if ($formUploadProfile->isSubmitted() && $formUploadProfile->isValid()) {

    /* Do some action, persist to database, etc. */

    /* Then redirect the user */
    return new RedirectResponse(...);
}
/* Else, if the user selected 'select manually' and submitted the associated form */
elseif ($formSelectManually->isSubmitted() && $formSelectManually->isValid()) {

    /* Do some action, persist to database, etc. */

    /* Then redirect the user */
    return new RedirectResponse(...);
}

/* Render the page, don't forget to pass the two forms in parameters */
return $this->render('yourPage.html.twig', array(
    'form_upload_profile' => $formUploadProfile->createView(),
    'form_select_iata_manually' => $formSelectManually->createView(),
    /* Add other parameters you might need */
));

จากนั้น ด้วย JavaScript ขึ้นอยู่กับปุ่มตัวเลือกที่เลือก คุณจะแสดงแบบฟอร์มแรก (พร้อมปุ่มส่งของตัวเอง) หรือแบบฟอร์มที่สอง (รวมถึงปุ่มส่งของตัวเองด้วย)

person Nicolas    schedule 19.12.2017