Partage
  • Partager sur Facebook
  • Partager sur Twitter

[SF4] Sous formulaire

Sujet résolu
    20 juillet 2019 à 21:02:50

    Bonjour,

    Je cherche à créer des sous formulaires à mon formulaire de base.

    Je génère mes sous formulaires au clic sur un bouton grâce à JavaScript. Les formulaires s'affichent bien dans le DOM.

    $('.contract-add-elevator-button').on('click', function () {
        $.ajax({
            method: "POST",
            url: "/contract/addElevator"
        }).done(function (data) {
            var count = $('.contract-elevators-form-main').data('count');
    
            var elevatorsForm =
                '<div class="elevators-form">' +
                    '<h2>Ascenseur ' + count + '</h2>' +
                    '<div class="form-group">' +
                        '<label>Adresse</label>' +
                        '<input type="text" name="contract[elevators][][address]" class="form-control">' +
                    '</div>' +
                    '<div class="form-group">' +
                        '<label>Ville</label>' +
                        '<input type="text" name="contract[elevators][][city]" class="form-control">' +
                    '</div>' +
                    '<div class="form-group">' +
                        '<label>Code postal</label>' +
                        '<input type="text" name="contract[elevators][][zipCode]" class="form-control">' +
                    '</div>' +
                    '<div class="form-group">' +
                        '<label>Date d\'installation</label>' +
                        '<input type="date" name="contract[elevators][][installationDate]" class="form-control" placeholder="dd/mm/YYYY">' +
                    '</div>' +
                    '<div class="form-group">' +
                        '<label>Poids de la cabine</label>' +
                        '<input type="text" name="contract[elevators][][cabineLoad]" class="form-control">' +
                    '</div>' +
                    '<div class="form-group">' +
                        '<label>Vitesse</label>' +
                        '<input type="number" name="contract[elevators][][speed]" class="form-control">' +
                    '</div>' +
                    '<div class="form-group">' +
                        '<label>Nombre d\'étages</label>' +
                        '<input type="text" name="contract[elevators][][stageNumber]" class="form-control">' +
                    '</div>' +
                    '<div class="form-group">' +
                        '<label>Prix</label>' +
                        '<input type="float" name="contract[elevators][][price]" class="form-control">' +
                    '</div>'
            ;
    
            for (var i = 0; i < data.elevatorEquipmentsArray.length; i++) {
                elevatorsForm  +=
                    '<div class="form-group">' +
                        '<label>Equipements</label>' +
                        '<select name="contract[elevators][][elevatorEquipment]" class="form-control">' +
                            '<option value="' + (i + 1) + '">' + data.elevatorEquipmentsArray[i].title + '</option>' +
                        '</select>' +
                    '</div>'
                ;
            }
    
            for (var y = 0; y < data.elevatorShiftingsArray.length; y++) {
                elevatorsForm  +=
                    '<div class="form-group">' +
                        '<label>Déplacement</label>' +
                        '<select name="contract[elevators][][elevatorShifting]" class="form-control">' +
                            '<option class="form-control" value="' + (y + 1) + '">' + data.elevatorShiftingsArray[y].title + '</option>' +
                        '</select>' +
                    '</div>'
                ;
            }
    
            for (var x = 0; x < data.maintenanceTypesArray.length; x++) {
                elevatorsForm  +=
                    '<div class="form-group">' +
                        '<label>Type de maintenance</label>' +
                        '<select name="contract[elevators][][maintenanceType]" class="form-control">' +
                            '<option class="form-control" value="' + (x + 1) + '">' + data.maintenanceTypesArray[x].title + '</option>' +
                        '</select>' +
                    '</div>'
                ;
            }
    
            for (var z = 0; z < data.societiesArray.length; z++) {
                elevatorsForm  +=
                    '<div class="form-group">' +
                        '<label>Société</label>' +
                        '<select name="contract[elevators][][society]" class="form-control">' +
                            '<option class="form-control" value="' + (z + 1) + '">' + data.societiesArray[z].name + '</option>' +
                        '</select>' +
                    '</div>'
                ;
            }
    
            for (var u = 0; u < data.contractTypesArray.length; u++) {
                elevatorsForm  +=
                    '<div class="form-group">' +
                        '<label>Type de contrat</label>' +
                        '<select name="contract[elevators][][contractType]" class="form-control">' +
                            '<option class="form-control" value="' + (u + 1) + '">' + data.contractTypesArray[u].title + '</option>' +
                        '</select>' +
                    '</div>'
                ;
            }
    
            elevatorsForm += '</div>';
    
            $('.contract-elevators-form-main').append(elevatorsForm);
    
            count = count + 1;
    
            $('.contract-elevators-form-main').data('count', count);
        });
    });
    

    Ensuite, pour pouvoir gérer la validation côté Symfony grâce aux annotations j'utilise l'événement PRE_SUBMIT pour rajouter tous les champs de mes sous formulaires.

    Cela fonctionne très bien quand je n'ai qu'un seul formulaire mais des que j'en ai deux j'ai ce message d'erreur:

    Ce champ ne peut pas avoir de champs supplémentaires:
    "{{ extra_fields }}" => ""0", "1""


    et je ne vois pas trop comment régler le problème.

    Voici le résultat du contenu de mon formulaire dans le subscriber:

    array:12 [▼
      "client_ask_date" => "13/11/1997"
      "client_render_date" => "13/11/1997"
      "unioun_council_date" => "13/11/1997"
      "general_assembly_date" => "13/11/1997"
      "maintenance_ca" => "50000"
      "duration" => "50"
      "price" => "50"
      "fiscal_year" => "2019"
      "contractStatus" => "1"
      "society" => "1"
      "comment" => "test"
      "elevators" => array:2 [▼
        0 => array:13 [▼
          "address" => "15 rue de la Gare"
          "city" => "Levallois-Perret"
          "zipCode" => "92300"
          "installationDate" => "1997-11-13"
          "cabineLoad" => "50"
          "speed" => "50"
          "stageNumber" => "5"
          "price" => "50000"
          "elevatorEquipment" => "1"
          "elevatorShifting" => "1"
          "maintenanceType" => "1"
          "society" => "1"
          "contractType" => "1"
        ]
        1 => array:13 [▼
          "address" => "15 rue de la Gare"
          "city" => "Levallois-Perret"
          "zipCode" => "92300"
          "installationDate" => "1997-11-13"
          "cabineLoad" => "50"
          "speed" => "50"
          "stageNumber" => "5"
          "price" => "20000"
          "elevatorEquipment" => "1"
          "elevatorShifting" => "1"
          "maintenanceType" => "1"
          "society" => "1"
          "contractType" => "1"
        ]
      ]
    ]

    Merci d'avance pour votre aide! :)

    • Partager sur Facebook
    • Partager sur Twitter
    "Ils ne savaient pas que c'était impossible, alors ils l'ont fait" Mark Twain
    Anonyme
      20 juillet 2019 à 23:49:10

      Pourquoi n'utilises-tu pas les formulaires imbriqués de Symfony ?
      • Partager sur Facebook
      • Partager sur Twitter
        21 juillet 2019 à 0:30:51

        Je ne vois pas comment le gérer avec de l'ajax.

        Aurais-tu un exemple?

        • Partager sur Facebook
        • Partager sur Twitter
        "Ils ne savaient pas que c'était impossible, alors ils l'ont fait" Mark Twain
        Anonyme
          21 juillet 2019 à 0:50:25

          Je ne suis pas sûr. La requête AJAX part toujours vers la même page ; reçoit-elle des réponses différentes ?
          • Partager sur Facebook
          • Partager sur Twitter
            21 juillet 2019 à 1:05:16

            Mon controller ressemble à ça:

            <?php
            
            namespace App\Controller\User;
            
            use App\Entity\Contract;
            use App\Entity\Elevator;
            use App\Form\ContractType;
            use App\Repository\ContractRepository;
            use App\Repository\ContractTypeRepository;
            use App\Repository\ElevatorEquipmentRepository;
            use App\Repository\ElevatorShiftingRepository;
            use App\Repository\MaintenanceTypeRepository;
            use App\Repository\SocietyRepository;
            use Doctrine\ORM\EntityManagerInterface;
            use Knp\Component\Pager\PaginatorInterface;
            use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
            use Symfony\Component\HttpFoundation\JsonResponse;
            use Symfony\Component\HttpFoundation\Request;
            use Symfony\Component\Routing\Annotation\Route;
            
            class ContractController extends AbstractController
            {
                /**
                 * @Route("/contracts", name="contracts")
                 */
                public function index(Request $request, ContractRepository $contractRepository, PaginatorInterface $paginator)
                {
                    $contracts = $paginator
                        ->paginate(
                            $contractRepository->get50LastContractsQuery($this->getUser()),
                            $request->query->getInt('page', 1),
                            50
                        );
            
                    return $this->render('users/contract/index.html.twig', [
                        'contracts' => $contracts
                    ]);
                }
            
                /**
                 * @Route("/contracts/new", name="contracts_new")
                 *
                 * @param Request $request
                 */
                public function new(Request $request, EntityManagerInterface $em)
                {
                    $contractForm = $this->createForm(ContractType::class, $request->get('contract'));
            
                    if ($request->getMethod() === 'POST') {
                        $contractForm->handleRequest($request);
            
                        if ($contractForm->isSubmitted() && $contractForm->isValid()) {
                            $contract = $contractForm->getData();
            
                            $contract->setUser($this->getUser());
            
                            $em->persist($contract);
                            $em->flush();
            
                            $this->addFlash('success' , 'Le contrat a bien été créé.');
            
                            return $this->redirectToRoute('contracts');
                        }
            
                        $errors = [];
                        foreach ($contractForm->getErrors() as $error) {
                            $errors[] = $error;
                        }
            
                        dump($errors);
                        die;
            
                        return $this->render('users/contract/new.html.twig', [
                            'errors' => $errors
                        ]);
                    }
            
                    return $this->render('users/contract/new.html.twig', [
                        'contractForm' => $contractForm->createView()
                    ]);
                }
            
                /**
                 * @Route("/contracts/edit/{id}", name="contracts_edit")
                 */
                public function update(Contract $contract, Request $request, EntityManagerInterface $em)
                {
                    $contractForm = $this->createForm(ContractType::class, $contract);
            
                    $contractForm->handleRequest($request);
            
                    if ($request->getMethod() === 'POST') {
                        if ($contractForm->isSubmitted() && $contractForm->isValid()) {
                            $contract = $contractForm->getData();
            
                            $contract->setUser($this->getUser());
            
                            $em->persist($contract);
                            $em->flush();
            
                            $this->addFlash('success' , 'Le contrat a bien été modifié.');
            
                            return $this->redirectToRoute('contracts');
                        }
            
                        return $this->render('users/contract/edit.html.twig', [
                            'contractForm' => $contractForm->createView()
                        ]);
                    }
            
                    return $this->render('users/contract/edit.html.twig', [
                        'contractForm' => $contractForm->createView(),
                        'contract'     => $contract
                    ]);
                }
            
                /**
                 * @Route("/contracts/{id}", name="contracts_remove")
                 */
                public function remove(Contract $contract, EntityManagerInterface $em)
                {
                    $em->remove($contract);
                    $em->flush();
            
                    $this->addFlash('success', 'Le contrat a bien été supprimé.');
            
                    return $this->redirectToRoute('contracts');
                }
            
                /**
                 * @Route("/contract/addElevator", name="contracts_add_elevator")
                 */
                public function addElevatorForm(
                    ElevatorEquipmentRepository $elevatorEquipmentRepository,
                    ElevatorShiftingRepository $elevatorShiftingRepository,
                    MaintenanceTypeRepository $maintenanceTypeRepository,
                    SocietyRepository $societyRepository,
                    ContractTypeRepository $contractTypeRepository
                ) {
                    $elevatorEquipments = $elevatorEquipmentRepository->findAll();
                    $elevatorShiftings = $elevatorShiftingRepository->findAll();
                    $maintenanceTypes = $maintenanceTypeRepository->findAll();
                    $societies = $societyRepository->findAll();
                    $contractTypes = $contractTypeRepository->findAll();
            
                    $elevatorEquipmentsArray = [];
                    foreach ($elevatorEquipments as $elevatorEquipment) {
                        $elevatorEquipmentsArray[]['title'] = $elevatorEquipment->getTitle();
                    }
            
                    $elevatorShiftingsArray = [];
                    foreach ($elevatorShiftings as $elevatorShifting) {
                        $elevatorShiftingsArray[]['title'] = $elevatorShifting->getTitle();
                    }
            
                    $maintenanceTypesArray = [];
                    foreach ($maintenanceTypes as $maintenanceType) {
                        $maintenanceTypesArray[]['title'] = $maintenanceType->getTitle();
                    }
            
                    $societiesArray = [];
                    foreach ($societies as $society) {
                        $societiesArray[]['name'] = $society->getName();
                    }
            
                    $contractTypesArray = [];
                    foreach ($contractTypes as $contractType) {
                        $contractTypesArray[]['title'] = $contractType->getTitle();
                    }
            
                    return new JsonResponse([
                        'elevatorEquipmentsArray' => $elevatorEquipmentsArray,
                        'elevatorShiftingsArray'  => $elevatorShiftingsArray,
                        'maintenanceTypesArray'   => $maintenanceTypesArray,
                        'societiesArray'          => $societiesArray,
                        'contractTypesArray'      => $contractTypesArray
                    ]);
                }
            }
            



            • Partager sur Facebook
            • Partager sur Twitter
            "Ils ne savaient pas que c'était impossible, alors ils l'ont fait" Mark Twain
              22 juillet 2019 à 11:51:39

              up
              • Partager sur Facebook
              • Partager sur Twitter
              "Ils ne savaient pas que c'était impossible, alors ils l'ont fait" Mark Twain
                28 juillet 2019 à 19:19:00

                up
                • Partager sur Facebook
                • Partager sur Twitter
                "Ils ne savaient pas que c'était impossible, alors ils l'ont fait" Mark Twain
                  28 juillet 2019 à 22:30:40

                  il y a l'option  allow_extra_fields permettant au form d'accepter des champs supplémentaires

                  https://symfony.com/doc/current/reference/forms/types/form.html#allow-extra-fields

                  • Partager sur Facebook
                  • Partager sur Twitter
                    29 juillet 2019 à 11:43:25

                    Si le formulaire que tu souhaites ajouter plusieurs fois est le même, tu dois utiliser une collection d'objet. Ainsi si tu rajoutes plusieurs fois le même formulaire, Symfony gérera tout seul l'ajout de ces multiples formulaires. Voici la doc pour faire cela : 

                    https://symfony.com/doc/current/form/form_collections.html

                    • Partager sur Facebook
                    • Partager sur Twitter
                      29 juillet 2019 à 23:27:46

                      Merci Asuna, cela fonctionne à merveille.

                      Merci aux autres de m'avoir aidé.

                      • Partager sur Facebook
                      • Partager sur Twitter
                      "Ils ne savaient pas que c'était impossible, alors ils l'ont fait" Mark Twain

                      [SF4] Sous formulaire

                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                      • Editeur
                      • Markdown