Symfony2 form: how to make the same element twice in the same view

I have a controller where I create a form with two dropdowns inside.

When I look at my view, I would like to have the same form elements at the top and bottom of the page. The problem is that the elemetns (dropdownlists) forms are displayed only at the top of the page, even if I ask the branch to put them also on the bottom.

Here is what I would like to have:

enter image description here

1 and 2 are drop-down lists. And I would like to duplicate this at the top and bottom of the page.

Any idea on how to do this?

The top content and the bottom content where the two dropdownlists are located are in the same sseparate twig file (searchPanel.html.twig), and this file is included in the page

{% include "MyBundle:Search:searchPanel.html.twig" %} 

Here is searchPanel.html.twig

 <div class="searchPanel"> <form action="{{ path }}" method="POST" {{ form_enctype(form) }}> Papers per page {{ form_widget(form.papers_per_page, { 'class': 'ppp'}) }} / Sort by {{ form_widget(form.sort_by, { 'class': 'sort'}) }} {{ form_rest(form) }} / Papers ({{ papers_number }} results) <input type="submit" class="updateSearchResults" value="Update"></input> </form> 
+7
source share
3 answers

The problem with your approach is that the Symfony Form component will display form elements with an identifier that will be duplicated if you place the same form twice on your page. You may also encounter the csrf_token problem. The bottom line is that forms are not intended to be duplicated.

Here is what I will do. Create a twig template containing your paginator form without using Symfony \ Form, i.e. Create all the form elements statically and pass it a pointer object (or array) to get the data instead of using form_widget() . Something like that:

 <form action="{{ path(app.request.attributes.get('_route') }}" method="POST"> <select name="paginator[per_page]"> {% for per_page in paginator.papers_per_page %} <option value=""{{ per_page }}">{{ per_page }}</option> {% endfor %} </select> </form> 

The form action will automatically send data to your current route, so you can insert it into different actions and it will transfer data to the same action. In POST, you can simply create a pointer object with post data and then add it as form data. After that, you simply use isValid () as usual.

In your controller you can get the following data:

 use Symfony\Component\HttpFoundation\Request; // ... public function PaperController() { public function listAction(Request $request) { if ($request->getMethod() == 'POST') { $data = $request->request->get('paginator'); $paginator = new Paginator($data); $form = new PaginatorFormType(); $form->setData($paginator); if ($form->isValid()) { // ... } } } } 

You can easily insert a form into your view as follows:

 {{ include 'AcmeDemoBundle:Form:paginator.html.twig' with { 'paginator': paginator } }} 

Basically you just use the Form component in your controller for validation. If you want to set some default values ​​or add additional arguments, you can create a macro from this template, but that should be enough for your use case. Maybe someone has a better solution, but I did this with a similar problem in one of my projects.

+5
source

another option is a rendering assistant helper. This way you can make the same form on the page as many times as you want. The difference is that the use of this helper is also necessary to handle the visualization of the form as an independent controller. Action: anywhere in your branch template, you want to display the form in the helper in order to invoke the form, there should be something like this:

 {{ render(controller('BundleNameBundle:Controller:Action', { 'param': paramId })) }} 

After that, you just need to create a controller ...

+2
source

Another option is to create 2 forms in the controller:

  //first form $form = $this->createForm(new MyFormType(), ...); //second form: must have different form name that default, //to render in twig the fields with different ids $formType = new MyFormType(); $formType->setName('second_form_name'); $formSecond = $this->createForm($formType, ...); 

Send both when rendering the twig shape:

 return $this->render( ... 'form' => $form->createView(), 'formSecond'=>$formSecond->createView())); 

Then define the second one with the name

formSecond

and he will conflict with the first.

0
source

All Articles