mario60

Nested forms. Symfony3

Jan 8th, 2017
218
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 16.77 KB | None | 0 0
  1. /*
  2. * I am working with Symfony 3.1
  3. * Entities Alpha, Beta, Gamma; Alpha 1:M Beta 1:M Gamma.
  4. * I need nested forms both to create and to edit/delete nested objects
  5. * To create nested object, code below works fine.
  6. * I am not sure how to insert apt JS into the edit form provided by Symfony as to  add/delete subobjects
  7. */
  8. // Entities defined as by default
  9. // FORMS
  10.  
  11. alphasType.php
  12.  
  13. <?php
  14.  
  15. namespace Jus\SimpleBundle\Form;
  16.  
  17. use Symfony\Component\Form\AbstractType;
  18. use Symfony\Component\Form\FormBuilderInterface;
  19. use Symfony\Component\OptionsResolver\OptionsResolver;
  20. use Symfony\Component\Form\Extension\Core\Type\TextType;
  21. use Symfony\Component\Form\Extension\Core\Type\CollectionType;
  22. use Symfony\Component\Form\Extension\Core\Type\SubmitType;
  23.  
  24. class AlphasType extends AbstractType
  25. {
  26.     /**
  27.      * {@inheritdoc}
  28.      */
  29.     public function buildForm(FormBuilderInterface $builder, array $options)
  30.     {
  31.         $builder->add('alphas', CollectionType::class, array(
  32.                     'entry_type'=> AlphaType::class,
  33.                     'allow_add'      => true,
  34.                     'allow_delete'  => true,
  35.             'by_reference' => false,
  36.                     'label' => 'Insert one more alpha',
  37.                     'prototype' => true,
  38.                     'prototype_name' => '__alpha_prot__'
  39.                ))
  40.               ->add('Save', SubmitType::class, array('attr' => array('class' => 'save')))      
  41.             ;
  42.     }
  43.    
  44.     /**
  45.      * {@inheritdoc}
  46.      */
  47.     public function configureOptions(OptionsResolver $resolver)
  48.     {
  49.        $resolver->setDefaults(array(
  50.             'data_class' => null
  51.         ));
  52.     }
  53.  
  54.     /**
  55.      * {@inheritdoc}
  56.      */
  57.     public function getBlockPrefix()
  58.     {
  59.         return 'jus_simplebundle_alphas';
  60.     }
  61. }
  62.  
  63. alphaType.php
  64.  
  65. <?php
  66.  
  67. namespace Jus\SimpleBundle\Form;
  68.  
  69. use Symfony\Component\Form\AbstractType;
  70. use Symfony\Component\Form\FormBuilderInterface;
  71. use Symfony\Component\OptionsResolver\OptionsResolver;
  72. use Symfony\Component\Form\Extension\Core\Type\TextType;
  73. use Symfony\Component\Form\Extension\Core\Type\CollectionType;
  74.  
  75. class AlphaType extends AbstractType
  76. {
  77.     /**
  78.      * {@inheritdoc}
  79.      */
  80.     public function buildForm(FormBuilderInterface $builder, array $options)
  81.     {
  82.         $builder->add('title', TextType::class)
  83.         ->add('betas', CollectionType::class, array(
  84.                     'entry_type' => BetaType::class,
  85.             'allow_add'      => true,
  86.                     'allow_delete'  => true,
  87.             'by_reference' => false,
  88.                     //'entry_options'  => array('entity_manager' => $entityManager),
  89.                     'label' => 'Insert betas for this alpha',
  90.             'prototype' => true,
  91.                     'prototype_name' => '__beta_prot__'
  92.                 ))       ;
  93.     }
  94.    
  95.     /**
  96.      * {@inheritdoc}
  97.      */
  98.     public function configureOptions(OptionsResolver $resolver)
  99.     {
  100.         $resolver->setDefaults(array(
  101.             'data_class' => 'Jus\SimpleBundle\Entity\Alpha'
  102.         ));
  103.     }
  104.  
  105.     /**
  106.      * {@inheritdoc}
  107.      */
  108.     public function getBlockPrefix()
  109.     {
  110.         return 'jus_simplebundle_alpha';
  111.     }
  112. }
  113.  
  114. betaType.php
  115.  
  116. <?php
  117.  
  118. namespace Jus\SimpleBundle\Form;
  119.  
  120. use Symfony\Component\Form\AbstractType;
  121. use Symfony\Component\Form\FormBuilderInterface;
  122. use Symfony\Component\OptionsResolver\OptionsResolver;
  123. use Symfony\Component\Form\Extension\Core\Type\TextType;
  124. use Symfony\Component\Form\Extension\Core\Type\CollectionType;
  125.  
  126. class BetaType extends AbstractType
  127. {
  128.     /**
  129.      * {@inheritdoc}
  130.      */
  131.     public function buildForm(FormBuilderInterface $builder, array $options)
  132.     {
  133.         $builder->add('title')
  134.         //->add('alpha')
  135.         ->add('gammas', CollectionType::class, array(
  136.                     'entry_type' => GammaType::class,
  137.             'allow_add'      => true,
  138.                     'allow_delete'  => true,
  139.             'by_reference' => false,
  140.                     //'entry_options'  => array('entity_manager' => $entityManager),
  141.                     'label' => 'Insert gammas for this beta',
  142.             'prototype' => true,
  143.                     'prototype_name' => '__gamma_prot__'
  144.                 ))     ;
  145.     }
  146.    
  147.     /**
  148.      * {@inheritdoc}
  149.      */
  150.     public function configureOptions(OptionsResolver $resolver)
  151.     {
  152.         $resolver->setDefaults(array(
  153.             'data_class' => 'Jus\SimpleBundle\Entity\Beta'
  154.         ));
  155.     }
  156.  
  157.     /**
  158.      * {@inheritdoc}
  159.      */
  160.     public function getBlockPrefix()
  161.     {
  162.         return 'jus_simplebundle_beta';
  163.     }
  164.  
  165.  
  166. }
  167.  
  168. gammaType.php
  169.  
  170. <?php
  171.  
  172. namespace Jus\SimpleBundle\Form;
  173.  
  174. use Symfony\Component\Form\AbstractType;
  175. use Symfony\Component\Form\FormBuilderInterface;
  176. use Symfony\Component\OptionsResolver\OptionsResolver;
  177.  
  178. class GammaType extends AbstractType
  179. {
  180.     /**
  181.      * {@inheritdoc}
  182.      */
  183.     public function buildForm(FormBuilderInterface $builder, array $options)
  184.     {
  185.         $builder->add('title')
  186.         //->add('beta')        
  187.         ;
  188.     }
  189.    
  190.     /**
  191.      * {@inheritdoc}
  192.      */
  193.     public function configureOptions(OptionsResolver $resolver)
  194.     {
  195.         $resolver->setDefaults(array(
  196.             'data_class' => 'Jus\SimpleBundle\Entity\Gamma'
  197.         ));
  198.     }
  199.  
  200.     /**
  201.      * {@inheritdoc}
  202.      */
  203.     public function getBlockPrefix()
  204.     {
  205.         return 'jus_simplebundle_gamma';
  206.     }
  207.  
  208.  
  209. }
  210.  
  211. alphaController.php
  212.  
  213. <?php
  214.  
  215. namespace Jus\SimpleBundle\Controller;
  216.  
  217. use Jus\SimpleBundle\Entity\Alpha;
  218. use Jus\SimpleBundle\Entity\Beta;
  219. use Jus\SimpleBundle\Entity\Gamma;
  220. use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  221. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
  222. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
  223. use Symfony\Component\HttpFoundation\Request;
  224.  
  225. /**
  226.  * Alpha controller.
  227.  *
  228.  * @Route("Jus/Simple/alpha")
  229.  */
  230. class AlphaController extends Controller
  231. {
  232.     /**
  233.      * Lists all alpha entities.
  234.      *
  235.      * @Route("/", name="Jus_Simple_alpha_index")
  236.      * @Method("GET")
  237.      */
  238.     public function indexAction()
  239.     {
  240.         $em = $this->getDoctrine()->getManager();
  241.  
  242.         $alphas = $em->getRepository('SimpleBundle:Alpha')->findAll();
  243.  
  244.         return $this->render('alpha/index.html.twig', array(
  245.             'alphas' => $alphas,
  246.         ));
  247.     }
  248.  
  249.     /**
  250.      * Creates a new alpha entity.
  251.      *
  252.      * @Route("/new", name="Jus_Simple_alpha_new")
  253.      * @Method({"GET", "POST"})
  254.      */
  255.     public function newAction(Request $request)
  256.     {
  257.         //$alpha = new Alpha();
  258.         $alphas = array(0 => new Alpha());
  259.         //$form = $this->createForm('Jus\SimpleBundle\Form\AlphaType', $alpha);
  260.         $form = $this->createForm('Jus\SimpleBundle\Form\AlphasType', $alphas,  array(
  261.     'action' => $this->generateUrl('Jus_Simple_alpha_new')));
  262.         $form->handleRequest($request);
  263.  
  264.       /*  if ($form->isSubmitted() && $form->isValid()) {
  265.             $em = $this->getDoctrine()->getManager();
  266.             $em->persist($alpha);
  267.             $em->flush($alpha);
  268.       */
  269.  
  270.         if ($form->isSubmitted() && $form->isValid()) { //echo 'yes';
  271.            try {
  272.         $postData = $request->request->get('jus_simplebundle_alphas');
  273. //dump($request->request); die();
  274.         $em = $this->getDoctrine()->getEntityManager();
  275.         $alphas = array();
  276.         foreach($postData['alphas'] as $key => $obj){$alphas[$key]= new Alpha();
  277.         $alphas[$key]->setTitle($obj['title']);
  278.         $em->persist($alphas[$key]);
  279.     if(isset($obj['betas'])){
  280.         $betas = array();
  281.         foreach($obj['betas'] as $kkey => $oobj){$betas[$kkey]= new Beta();
  282.     $betas[$kkey]->setAlpha($alphas[$key]);
  283.         $betas[$kkey]->setTitle($oobj['title']);
  284.         $em->persist($betas[$kkey]);
  285.         if(isset($oobj['gammas'])){
  286.         $gammas = array();
  287.         foreach($oobj['gammas'] as $kkkey => $ooobj){$gammas[$kkkey]= new Gamma();
  288.     $gammas[$kkkey]->setBeta($betas[$kkey]);
  289.     $gammas[$kkkey]->setTitle($ooobj['title']);
  290.     $em->persist($gammas[$kkkey]);
  291.     }}
  292.       }}}
  293.      $em->flush();  
  294.      
  295.  } catch (\Doctrine\DBAL\DBALException $e) {
  296.         die($e->getMessage());
  297.  }
  298.  
  299.      return $this->redirectToRoute('Jus_Simple_alpha_index');
  300. }
  301.  
  302.         return $this->render('alpha/new.html.twig', array(
  303.             'alphas' => $alphas,
  304.             'form' => $form->createView(),
  305.         ));
  306.     }
  307.  
  308.     /**
  309.      * Finds and displays a alpha entity.
  310.      *
  311.      * @Route("/{id}", name="Jus_Simple_alpha_show")
  312.      * @Method("GET")
  313.      */
  314.     public function showAction(Alpha $alpha)
  315.     {
  316.         $deleteForm = $this->createDeleteForm($alpha);
  317.  
  318.         return $this->render('alpha/show.html.twig', array(
  319.             'alpha' => $alpha,
  320.             'delete_form' => $deleteForm->createView(),
  321.         ));
  322.     }
  323.  
  324.     /**
  325.      * Displays a form to edit an existing alpha entity.
  326.      *
  327.      * @Route("/{id}/edit", name="Jus_Simple_alpha_edit")
  328.      * @Method({"GET", "POST"})
  329.      */
  330.     public function editAction(Request $request, Alpha $alpha)
  331.     {
  332.         $deleteForm = $this->createDeleteForm($alpha);
  333.         $editForm = $this->createForm('Jus\SimpleBundle\Form\AlphaType', $alpha);
  334.         $editForm->handleRequest($request);
  335.  
  336.         if ($editForm->isSubmitted() && $editForm->isValid()) {
  337.             $this->getDoctrine()->getManager()->flush();
  338.  
  339.             return $this->redirectToRoute('Jus_Simple_alpha_edit', array('id' => $alpha->getId()));
  340.         }
  341.  
  342.         return $this->render('alpha/edit.html.twig', array(
  343.             'alpha' => $alpha,
  344.             'edit_form' => $editForm->createView(),
  345.             'delete_form' => $deleteForm->createView(),
  346.         ));
  347.     }
  348.  
  349.     /**
  350.      * Deletes a alpha entity.
  351.      *
  352.      * @Route("/{id}", name="Jus_Simple_alpha_delete")
  353.      * @Method("DELETE")
  354.      */
  355.     public function deleteAction(Request $request, Alpha $alpha)
  356.     {
  357.         $form = $this->createDeleteForm($alpha);
  358.         $form->handleRequest($request);
  359.  
  360.         if ($form->isSubmitted() && $form->isValid()) {
  361.             $em = $this->getDoctrine()->getManager();
  362.             $em->remove($alpha);
  363.             $em->flush($alpha);
  364.         }
  365.  
  366.         return $this->redirectToRoute('Jus_Simple_alpha_index');
  367.     }
  368.  
  369.     /**
  370.      * Creates a form to delete a alpha entity.
  371.      *
  372.      * @param Alpha $alpha The alpha entity
  373.      *
  374.      * @return \Symfony\Component\Form\Form The form
  375.      */
  376.     private function createDeleteForm(Alpha $alpha)
  377.     {
  378.         return $this->createFormBuilder()
  379.             ->setAction($this->generateUrl('Jus_Simple_alpha_delete', array('id' => $alpha->getId())))
  380.             ->setMethod('DELETE')
  381.             ->getForm()
  382.         ;
  383.     }
  384. }
  385.  
  386. // BASE TEMPLATE with JQuery JS
  387.  
  388. <!DOCTYPE html>
  389. <html>
  390.     <head>
  391.     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  392.  
  393. <script src="{{ asset('bundles/js/simple/jquery-3.1.1.js') }}" type="text/javascript"> </script>  
  394. <script type="text/javascript">
  395.         var $collectionHolder;
  396.  
  397. // setup an "add aAlphas" link
  398.         var $addAlphaLink = $('<a href="#" class="add_Alpha_link">Crea un altro Alpha</a>');
  399.         var $newLinkLi = $('<li></li>').append($addAlphaLink);
  400.  
  401.  
  402.  
  403.     jQuery(document).ready(function() {
  404.             // Get the ul that holds the collection of Alphas
  405.             $collectionHolder = $('ul.Alphas');
  406.             // add the "add Alphas" anchor and li to the Alphas ul
  407.             $collectionHolder.append($newLinkLi);
  408. //window.alert($collectionHolder.append($newLinkLi).html());
  409.             // count the current form inputs we have (e.g. 2), use that as the new
  410.             // index when inserting a new item (e.g. 2)
  411.             var $index = 0;  
  412.         var $jndex = 0;
  413.         var $kndex = 0;
  414.  
  415.             $addAlphaLink.on('click', function(e) {
  416.                 // prevent the link from creating a "#" on the URL
  417.                 e.preventDefault();
  418.                 // add a newAlphas form (see next code block)
  419.                 addAlphaForm($collectionHolder, $newLinkLi, $index, $jndex, $kndex);  // Ok, it works!
  420.             $index++;
  421.         });
  422.     });
  423.  
  424.     function addAlphaForm($collectionHolder, $newLinkLi, $index, $jndex, $kndex ) {
  425.  
  426.             var $addBetaLink = $('<a href="#" class="add_Beta_link_'+$index+'" >Crea un altro Beta</a>');
  427.             var $newLinkLiBis = $('<ul>').append($addBetaLink).append('</ul>');
  428.  
  429.             // Get the data-prototype
  430.             var prototype = $collectionHolder.data('prototype');
  431.  
  432.             // get the new index
  433.         var index = $index;
  434. //window.alert($collectionHolder.data);
  435.             // Replace '__alpha_prot__' in the prototype's HTML to
  436.             // instead be a number based on how many items we have
  437.             var newForm = prototype.replace(/__alpha_prot__/g, index);
  438.  
  439.             // Display the form in the page in an li, before the "Add a Alphas" link li
  440.             var newForm =  $('<li></li>').append(newForm).insertBefore('.add_Alpha_link').append('<a href="#" class="remove-tag">x</a>').append($newLinkLiBis);  
  441.  
  442.                        // handle the removal, just for this example
  443.         $('.remove-tag').click(function(e) {
  444.                 e.preventDefault();
  445.                 $(this).parent().remove();
  446.                 return false;
  447.         });
  448.  
  449.         $addBetaLink.on('click', function(e) { 
  450.             e.preventDefault();
  451.             var $collectionHolderBis = $('div#jus_simplebundle_alphas_alphas_'+$index+'_betas');
  452.                 addBetaForm($collectionHolderBis, $newLinkLi, $index, $jndex, $kndex);  // Ok, it works!
  453.             $jndex++;
  454.         });
  455.         }
  456.  
  457.     function addBetaForm($collectionHolder, $newLinkLi, $index, $jndex, $kndex) {
  458.  
  459.        
  460.         var $addGammaLink = $('<a href="#" class="add_Gamma_link_'+$jndex+'" >Crea un altra Gamma</a>');
  461.             var $newLinkLiTris = $('<ul>').append($addGammaLink).append('</ul>');
  462.  
  463.             var prototype = $collectionHolder.data('prototype');
  464. //window.alert(prototype);
  465.         var index = $index;
  466.         var jndex = $jndex;
  467.         var kndex = $kndex;
  468.         var newFormSub = prototype.replace(/__alpha_prot__/g, index).replace(/__beta_prot__/g, jndex).replace(/label__/g, '');
  469.             $('<li></li>').append(newFormSub).append('<a href="#" class="remove-tag">y</a>').insertBefore('.add_Beta_link_'+$index).append($newLinkLiTris)
  470.  
  471.         $('.remove-tag').click(function(e) {
  472.                 e.preventDefault();
  473.                 $(this).parent().remove();
  474.                 return false;
  475.         });
  476.  
  477.         $addGammaLink.on('click', function(e) {
  478.             e.preventDefault();
  479.             var $collectionHolderTris = $('div#jus_simplebundle_alphas_alphas_'+$index+'_betas_'+$jndex+'_gammas');
  480. //window.alert('div#alphas_alphas_'+$index+'_betas_'+$jndex+'_gammas'+$collectionHolderTris.html());
  481.                 addGammaForm($collectionHolderTris, $newLinkLi, $index, $jndex, $kndex);  // Ok, it works!
  482.             $kndex++;
  483.         });
  484.         }
  485.  
  486.     function addGammaForm($collectionHolder, $newLinkLi, $index, $jndex, $kndex) {
  487.             var prototype = $collectionHolder.data('prototype');
  488.         var index = $index;
  489.         var jndex = $jndex;
  490.         var kndex = $kndex;
  491.         var newFormSubSub = prototype.replace(/__alpha_prot__/g, index).replace(/__beta_prot__/g, jndex).replace(/__gamma_prot__/g, kndex).replace(/label__/g, '');
  492.             $('<li></li>').append(newFormSubSub).append('<a href="#" class="remove-tag">z</a>').insertBefore('.add_Gamma_link_'+$jndex)
  493.  
  494.         $('.remove-tag').click(function(e) {
  495.                 e.preventDefault();
  496.                 $(this).parent().remove();
  497.                 return false;
  498.         });
  499.         }      
  500. </script>
  501.  
  502. <title>To Learn Symfony2</title>
  503. </head>
  504. <body {% block  bodyattr -%}   {% endblock %} >
  505.  
  506. <div id="header">
  507.  {% block header %}Welcome{% endblock %}
  508. </div>
  509.    
  510. <h1 class="title"> {% block title %}TEST NESTED FORMS{% endblock %} </h1>
  511.  
  512. {% block body %}{% endblock %}
  513.  
  514.  
  515.         <div id="footer">
  516.       {% block footer %}<a href="http://www.symfony.com">developed thanks to SYMFONY</a> {% endblock %}
  517.         </div>
  518.     </body>
  519. </html>
  520.  
  521. // new.twig.html template for alpha entities
  522.  
  523. {% extends 'basesimple.html.twig' %}
  524.  
  525. {% block body %}
  526.  
  527.  
  528.     <h1>Alpha creation</h1>
  529.  
  530.     {{ form_start(form) }}
  531. <ul class="Alphas" id="prots"  data-prototype="{{ form_widget(form.alphas.vars.prototype) | e }}">
  532.  
  533.     {# render the alpha's fields#}
  534.    {% for f in form.alphas %}  
  535.                <li class="here">   {{ form_row(f) }}
  536.          
  537.                </li>
  538.     {% endfor %} </ul>
  539. {{ form_end(form) }}
  540.  
  541.  
  542. <br>
  543. <hr>
  544.             <a href="{{ path('Jus_Simple_alpha_index') }}">Back to the list</a>
  545.  
  546. {% endblock %}
  547.  
  548.  
  549. // edit.twig.html template for alpha entities  
  550.  
  551. {% extends 'basesimple.html.twig' %}
  552.  
  553. {% block body %}
  554.     <h1>Alpha edit</h1>
  555.  
  556.     {{ form_start(edit_form) }}
  557.         {{ form_widget(edit_form) }}
  558.         <input type="submit" value="Edit" />
  559.     {{ form_end(edit_form) }}
  560.  
  561.     <ul>
  562.         <li>
  563.             <a href="{{ path('Jus_Simple_alpha_index') }}">Back to the list</a>
  564.         </li>
  565.         <li>
  566.             {{ form_start(delete_form) }}
  567.                 <input type="submit" value="Delete">
  568.             {{ form_end(delete_form) }}
  569.         </li>
  570.     </ul>
  571. {% endblock %}
Advertisement
Add Comment
Please, Sign In to add comment