I'm new to Symfony, I got a page in where I have a list of articles, and I created a form above it that allow me to filter the results of my query :
The form works fine, but when I click on the 2nd page of my paginator table, the form reset, so my filter is reset too. What I want is that we can filter results and be able to paginate the table, with the same filter, and that the form keep his data.
Here's my code right now :
Controller :
public function listeAction(Request $request, $page) {
if ($page < 1 && strlen($page) != 0) {
throw new NotFoundHttpException('Page "' . $page . '" inexistante.');
} else if (strlen($page) == 0) {
$page = 1;
}
$nbPerPage = 5;
$form = $this->createForm(ArticleRechercheType::class);
$form->setData(array('rds' => true));
//if we use filters
if ($request->isMethod('POST') && $form->handleRequest($request)->isValid()) {
$data = $form->getData();
$form = $this->createForm(ArticleRechercheType::class, $data);
if ($data['famille'] != null) {
$data['famille'] = $data['famille']->getId();
}
$listArticles = $this->getDoctrine()
->getManager()
->getRepository('GRBackOfficeBundle:Article')
->getFilteredArticles($page, $nbPerPage, $data);
} else {
$data = $form->getData();
$form = $this->createForm(ArticleRechercheType::class, $data);
$listArticles = $this->getDoctrine()
->getManager()
->getRepository('GRBackOfficeBundle:Article')
->getArticles($page, $nbPerPage);
}
$nbPages = ceil(count($listArticles) / $nbPerPage);
if ($nbPages != 0 && $page > $nbPages) {
throw new NotFoundHttpException('Page "' . $page . '" inexistante.');
}
if ($nbPages == 0) {
$nbPages = 1;
}
return $this->render('GRBackOfficeBundle:Article:liste_articles.html.twig', array(
'form' => $form->createView(),
'listArticles' => $listArticles,
'nbPages' => $nbPages,
'page' => $page
));
}
Form :
class ArticleRechercheType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('famille', EntityType::class, array(
'class' => 'GRBackOfficeBundle:Famille',
'choice_label' => 'nom',
'required' => false
))
->add('rds', CheckboxType::class, array('required' => false))
->add('recherche', TextType::class, array('required' => false))
->add('Rechercher', SubmitType::class);
}
public function configureOptions(OptionsResolver $resolver) {
$resolver->setDefaults(array(
'translation_domain' => false
));
}
}
View :
{% extends "GRBackOfficeBundle::layout.html.twig" %}
{% block title %}
Liste des articles
{% endblock %}
{% block gr_bo_body %}
<h2>Liste des articles</h2>
<div class="row">
<div class="well row">
{{ form_start(form) }}
{{ form_errors(form) }}
<div class="form-group col-md-2">
{{ form_label(form.famille, "Famille d'article", {'label_attr': {'class': 'control-label'}}) }}
{{ form_errors(form.famille) }}
{{ form_widget(form.famille, {'attr': {'class': 'form-control'}}) }}
</div>
<div class="form-group col-md-4">
{{ form_widget(form.rds, {'attr': {'class': ''}}) }}
{{ form_label(form.rds, "Montrer les articles en rupture de stock", {'label_attr': {'class': 'control-label'}}) }}
{{ form_errors(form.rds) }}
</div>
<div class="form-group col-md-3">
{{ form_label(form.recherche, "Recherche", {'label_attr': {'class': 'control-label'}}) }}
{{ form_errors(form.recherche) }}
{{ form_widget(form.recherche, {'attr': {'class': 'form-control'}}) }}
</div>
<div class="form-group col-md-3" style="text-align: center">
{{ form_widget(form.Rechercher, {'attr': {'class': 'btn btn-primary'}}) }}
</div>
{{ form_rest(form) }}
{{ form_end(form) }}
</div>
<div class="well row">
<table class="table table-bordered table-striped" id="listeArticles" style="width: 100%" cellspacing="0">
<thead>
<tr>
<th>Référence client</th>
<th>Référence interne</th>
<th>Famille</th>
<th>Libellé</th>
<th>Alerte</th>
<th>Stock</th>
</tr>
</thead>
<tbody id="bodyListeArticles">
{% for article in listArticles %}
<tr>
<td>{{ article.RefArticle }}</td>
<td>{{ article.RefLogistique }}</td>
<td>{{ article.famille.nom }}</td>
<td>{{ article.libelle }}</td>
<td>{{ article.StockAlerte }}</td>
<td>{{ article.StockActuel }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if nbPages > 1 %}
<ul class="pagination">
{% for p in range(1, nbPages) %}
<li {% if p == page %} class="active"{% endif %}>
{{ p }}
</li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
{% endblock %}
If anyone have an idea of how I can do that, that will be appreciated
You can use a bundle (like the knp paginator bundle for exemple), or put your args in session. But the bundle will make it simple as it does everything for you, you just have to pass your datas
Related
I want to keep data that have been entered in fields belonging to a form. I made this form so that the user creates an event. The reason is I included an other form to create a post address, so when the user submit his new address, he retrieves the information previously entered.
Do you have any idea how I can do this ?
(I apologize for all the bootstrap classes in my code.)
event_create.html.twig
{% extends 'base.html.twig' %}
{% block main %}
<div class="events">
<h1 class="display-2 text-center event_form_title">Création d'une nouvelle sortie ou d'une nouvelle activité</h1>
{{ form_start(eventform, {'attr' : {'class' : 'admin_form', 'novalidate': 'novalidate'}}) }}
<div class="d-flex justify-content-center">
<div id="eventform">
<div class="mb-3">
<p>Type</p>
{{ form_widget(eventform.category, {'value' : category.id} ) }}
</div>
<div class="mb-3">
<p>Titre</p>
{{ form_widget(eventform.title) }}
</div>
<div class="mb-3">
<p>Description</p>
{{ form_widget(eventform.description, {'attr' : {'rows' : '3'}} ) }}
</div>
<div class="mb-3 d-none">
<p>Langue à partiquer</p>
{{ form_widget(eventform.spokenlanguage) }}
</div>
<div class="mb-3" id="dateselection">
<p>Date</p>
{{ form_widget(eventform.start.date) }}
</div>
<div class="d-sm-flex justify-content-center">
<div class="d-flex justify-content-center justify-content-sm-end me-sm-3">
<div class="mb-3">
<p>Début</p>
{{ form_widget(eventform.start.time, {'attr' : {'class' : 'time_event'}} ) }}
</div>
</div>
<div class="d-flex justify-content-center justify-content-sm-start">
<div class="mb-3">
<p>Fin</p>
{{ form_widget(eventform.end, {'attr' : {'class' : 'time_event'}} ) }}
</div>
</div>
</div>
<div class="mb-3">
<p>Adresse</p>
{{ form_widget(eventform.address) }}
</div>
<button type="button" onclick="hideAddressButton(); showLocationForm();" class="btn btn-lg btn-outline-secondary w-100 mt-4 mb-5" id="showaddress">Créer une adresse</button>
<div class="d-flex justify-content-center" id="eventsubmit">
{{ form_widget(eventform.save, {'label': "Je valide", 'attr' : {'class' : 'btn btn-lg btn-outline-primary w-100 mb-5'}} ) }}
</div>
<div class="d-flex justify-content-center">
<span class="me-2"><</span> Retour à la liste
</div>
</div>
</div>
</div>
{{ form_end(eventform) }}
<!-- Sélectionner/Ajouter une langue -->
{{ form_start(languageform, {'attr' : {'id' : 'languageform', 'class' : 'mb-3'}}) }}
<p>Langue à pratiquer</p>
{{ form_widget(languageform.code, {'attr': {'onChange': 'selectLanguage();'} }) }}
{{ form_widget(languageform.name, {'attr': {'class': 'd-none'} }) }}
{{ form_widget(languageform.save, {'attr': {'class': 'd-none'} }) }}
{{ form_end(languageform) }}
<ul class="language_names d-none">
{% for language in languages %}
<li class="language_name">{{ language.name }}</li>
{% endfor %}
</ul>
<ul class="language_ids d-none">
{% for language in languages %}
<li class="language_id">{{ language.id }}</li>
{% endfor %}
</ul>
<!-- Créer/Ajouter une adresse -->
{{ form_start(locationform, {'attr' : {'id' : 'locationform'}}) }}
<hr>
<h1 class="display-2 mb-5">Création d'un lieu de rendez-vous</h1>
<div class="d-flex justify-content-center">
<div>
<div class="mb-3">
<p>Nom du lieu</p>
{{ form_widget(locationform.name) }}
</div>
<div class="d-sm-flex justify-content-center">
<div class="d-flex justify-content-center justify-content-sm-end me-sm-3">
<div class="mb-3">
<p>Numéro</p>
{{ form_widget(locationform.number, {'attr' : {'class' : 'numbers_address'}}) }}
</div>
</div>
<div class="d-flex justify-content-center justify-content-sm-start">
<div class="mb-3">
<p>Rue</p>
{{ form_widget(locationform.street, {'attr' : {'class' : 'texts_address'}}) }}
</div>
</div>
</div>
<div class="d-sm-flex justify-content-center">
<div class="d-flex justify-content-center justify-content-sm-end me-sm-3">
<div class="mb-3">
<p>Code postal</p>
{{ form_widget(locationform.zipcode, {'attr' : {'class' : 'numbers_address'}}) }}
</div>
</div>
<div class="d-flex justify-content-center justify-content-sm-start">
<div class="mb-3">
<p>Ville</p>
{{ form_widget(locationform.city, {'attr' : {'class' : 'texts_address'}}) }}
</div>
</div>
</div>
<div class="mb-3">
<p>Grande ville</p>
{{ form_widget(locationform.bigcity) }}
</div>
<button type="button" onclick="hideBigCityButton(); showBigCityForm();" class="btn btn-lg btn-outline-secondary w-100 mt-4" id="showbigcity">Ajouter une grande ville</button>
<div id="bigcity">
{% include "front/create/bigcity.html.twig" %}
</div>
<div class="d-flex justify-content-center my-5">
{{ form_widget(locationform.save, {'label': "Enregistrer une nouvelle adresse", 'attr' : {'class' : 'btn btn-lg btn-outline-primary w-100'}} ) }}
</div>
</div>
</div>
<hr>
{{ form_end(locationform) }}
{% endblock %}
EventController.php
<?php
namespace App\Controller\Front;
class EventController extends AbstractController
{
#[Route('/create/event/category/{id}', name: 'event_create', methods: ['GET', 'POST'])]
public function createEvent(
Request $request,
Category $category,
LanguageRepository $languageRepository,
CountryRepository $countryRepository,
EntityManagerInterface $entityManagerInterface,
UserRepository $userRepository,
LocationRepository $locationRepository
){
$languages = $languageRepository->findAll();
$language = new Language();
$languageform = $this->createForm(EventLanguageType::class, $language);
$languageform->handleRequest($request);
if ($languageform->isSubmitted() && $languageform->isValid()) {
$entityManagerInterface->persist($language);
$entityManagerInterface->flush();
}
$connected = $this->getUser();
$useremail = $connected->getUserIdentifier();
$user = $userRepository->findOneBy(['email' => $useremail]);
$location = new Location();
$locationform = $this->createForm(LocationType::class, $location);
$locationform->handleRequest($request);
if ($locationform->isSubmitted() && $locationform->isValid()) {
$location->setOrganizer($user);
$entityManagerInterface->persist($location);
$entityManagerInterface->flush();
}
$bigcity = new BigCity();
$bigcityform = $this->createForm(BigCityType::class, $bigcity);
$bigcityform->handleRequest($request);
if ($bigcityform->isSubmitted() && $bigcityform->isValid()) {
$entityManagerInterface->persist($bigcity);
$entityManagerInterface->flush();
}
$countries = $countryRepository->findAll();
$country = new Country();
$countryform = $this->createForm(NewCountryType::class, $country);
$countryform->handleRequest($request);
if ($countryform->isSubmitted() && $countryform->isValid()) {
$entityManagerInterface->persist($country);
$entityManagerInterface->flush();
}
$event = new Event();
$eventform = $this->createForm(EventType::class, $event, [
'addresses' => $locationRepository->findBy(['organizer' => $user])
]);
$eventform->handleRequest($request);
if ($eventform->isSubmitted() && $eventform->isValid()) {
$event->setOrganizer($user);
$entityManagerInterface->persist($event);
$entityManagerInterface->flush();
$participation = new Participation();
$participation->setParticipant($user);
$participation->setEvent($event);
$entityManagerInterface->persist($participation);
$entityManagerInterface->flush();
return $this->redirectToRoute('participations');
}
return $this->renderForm('front/event/create.html.twig', [
'eventform' => $eventform,
'languageform' => $languageform,
'languages' => $languages,
'locationform' => $locationform,
'bigcityform' => $bigcityform,
'countryform' => $countryform,
'countries' => $countries,
'category' => $category
]);
}
This is my trial with AJAX, but it does not work :
<script>
// I bring values entered in form and I send it with Ajax
inputs = document.querySelectorAll(["input", "select"]);
function saveDatas(){
let xhr = new XMLHttpRequest();
xhr.open("POST", "https://jsonplaceholder.typicode.com/posts", false);
xhr.setRequestHeader("Content-type", "application/json");
post = {
title: document.getElementById('event_title').value,
description: document.getElementById('event_description').value,
};
xhr.send(JSON.stringify(post));
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status <= 299) {
data = JSON.parse(xhr.response)
}
}
}
for (var i = 0 ; i < inputs.length; i++) {
inputs[i].addEventListener('click', saveDatas);
}
// I retrieve values and I entered them in form fields
languageform = document.getElementById('languageform');
function retrieveDatas(){
let xhr = new XMLHttpRequest();
xhr.open("GET", "https://jsonplaceholder.typicode.com/posts", false);
xhr.send();
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status <= 299) {
posts = JSON.parse(xhr.response)
posts.forEach((post) => {
document.getElementById('event_title').value = post.title;
document.getElementById('event_description').value = post.description;
})
}
}
}
languageform.addEventListener('submit', retrieveDatas);
</script>
I'm not sure to understand. You have a lot of ways to do it. You can use ajax and javascript (Stimulus is very good and documented on SymfonyCast) to avoid to reload page and create your new address. With Stimulus, your data-controller sent an ajax request, create the new address and update its own content.
You can merge your forms (so all data are sent) with two buttons (so you know which button has been push and which action is triggered. Then in your controller, you create the new address and send back all other data.
A third solution is to read this answer. It could help you.
IMO, the first solution is more user friendly.
I am creating an edit page where there will be as many forms as there will be results from my query. So after my query, I created a foreach loop to pass each "result" to a form and then I pass it all to my Twig.
$repo = $this->getDoctrine()->getRepository(Classement::class);
$q = $repo->createQueryBuilder('c');
$q->select('c', 'h')
->join('c.clubHistos', 'h')
->where('c.country = '.$country)
->where('c.season = '.$season);
$result = $q->getQuery()->getResult();
foreach ($result as $table) {
$table = $table;
$form = $this->createForm(ClassementType::class, $table);
}
return $this->render('back/editDivisionTables.html.twig', array(
'form' => $form->createView(),
'table' => $table
));
The problem is that I am only getting the last form when I should be having all of them. I did a dump($form) in my loop and everything seemed okay. So the problem is either in my return statement or in my Twig.
{{ form_start(form) }}
<div class="season-table-info">
<div class="country">
{{ form_row(form.country) }}
</div>
<div class="division">
{{ form_row(form.division) }}
</div>
{{ form_row(form.season) }}
</div>
<table id="dynamic-club-table">
<thead></thead>
<tbody id="dynamic-club-table-body" data-row-prototype="{{ formMacro.form(form.clubHistos.vars.prototype)|e('html_attr') }}">
{% for clubHistos in form.clubHistos %}
{{ formMacro.form(clubHistos) }}
{% endfor %}
</tbody>
</table>
{{ form_end(form) }}
I tried this solution but it didn't do the trick.
my form 'Donacion' have a relationship with 'pajuela' OneToMany.
When i add 'Pajuela' with addTagForm, it is created, but if i submit the form and i do dump(formulario), the ArrayCollection 'pajuelas' is empty.
I have read the official documentation but not found my problem...
This is the link: https://symfony.com/doc/3.3/form/form_collections.html
This is my code:
# DonacionType
...
case 4:
$builder
->add('pajuelas',CollectionType::class, array(
'entry_type' => PajuelaType::class,
'entry_options' => array(
'tipo_sede' => $options['tipo_sede'],
'sede_id' => $options['sede_id'],
),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
))
->add('observacionesPajuelas', TextareaType::class)
;
break;
...
# PajuelaType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('tipo', ChoiceType::class, array(
'choices' => array(
'Completa' => 'Completa',
'Controles' => 'Controles'
)
))
;
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Pajuela::class,
'tipo_sede' => null,
'sede_id' => null,
));
}
#Twig:
...
{% form_theme formulario _self %}
{% block _entidadbundle_donacion_pajuelas_entry_widget %}
{% if form is defined %}
{% if form.parent != null %}
<div class="form-group {% if form_errors(form.tipo) %}has-error{% endif %} col-lg-2 col-md-12 col-sm-12">
{% if form_errors(form.tipo) %}
{{ form_label(form.tipo, 'pajuela.tipo' | trans) }}
{{ form_widget(form.tipo, {'attr': {'class': 'form-control error'}}) }}
<label for="{{ form.tipo.vars.id }}"
class="error">{{ form_errors(form.tipo) }}</label>
{% else %}
{{ form_label(form.tipo, 'pajuela.tipo' | trans) }}
{{ form_widget(form.tipo, {'attr': {'class': 'form-control'}}) }}
{% endif %}
</div>
{% endif %}
{% endif %}
{% endblock %}
<div class="pajuelas" data-prototype="{{ form_widget(formulario.pajuelas.vars.prototype)|e('html_attr') }}">
{% for pajuela in formulario.pajuelas %}
<div class="row pajuela pajuela-persitida">{{ form_widget(pajuela) }}</div>
{% endfor %}
</div>
...
I can not find what is the problem that I am having.
I have such problem with symfony2.
I have base.html.twig and this base is the template for others twigs.
I want to render controller, which contains form with locale-type input field.
The form will be used to change language of site.
My LanguageController:
<?php
namespace Soczewki\PlatformaBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class LanguageController extends Controller {
public function createAction(Request $Request)
{
$form = $this->createFormBuilder()
->setMethod('POST')
->setAction(null)
->add('locale', 'locale', array(
'label' => ' ',
'choices' => array('pl' => 'Polski', 'de' => 'Deutsch', 'en' => 'English'),
'data' => $this->getRequest()->getLocale(),
'required' => true))
->add('submit', 'submit')
->getForm();
$form->handleRequest($Request);
if($form->isValid()) {
$this->getRequest()->setLocale('en');
}
return $this->render("SoczewkiPlatformaBundle::myForm.html.twig",
array(
'form' => $form->createView(),
'req' => $r
));
}
}
The whole base.html.twig:
<html>
<head>
<title>{% block pageTitle %}{% endblock %}</title>
{#js#}
<script src="{{ asset('bundles/soczewkiplatforma/js/jquery.js') }}"></script>
<script src="{{ asset('bundles/soczewkiplatforma/js/bootstrap.js') }}"></script>
{#/js#}
{% block stylesheets %}
<link href="{{ asset('bundles/soczewkiplatforma/css/bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ asset('bundles/soczewkiplatforma/css/my-style.css') }}" rel="stylesheet">
{% endblock stylesheets %}
</head>
<body>
{% if app.security.getToken().getUser().getAuthKey() is defined %}
{% if app.security.getToken().getUser().getAuthKey() is not empty %}
{% set diff = ( app.security.getToken().getUser().getEndDate()|date('U') - "now"|date('U') ) / 3600 %}
<div style="width: 300px; height: 140px; position: absolute; bottom: 90px; right: 50px;" class="alert alert-danger alert-error">
<button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<strong>Uwaga!</strong> Twoje konto nadal nie zostało aktywowane!<br />
Pozostało Ci: <span class="badge">{{ diff[0:2] }} godzin {{ ( diff[3:] * 60 )[0:2] }} minut </span>
<br /><br />
<button type="button" class="btn btn-danger">Wpisz kod</button>
<button type="button" class="btn btn-default" data-dismiss="alert">Zamknij</button>
</div>
{% endif %}
{% set hasParams = app.request.get('id') %}
{% if hasParams is empty %}
{% set currentPath = url( app.request.attributes.get( '_route', app.request.attributes.get('_route_params'))) %}
{% else %}
{% set currentPath = url( app.request.attributes.get( '_route', app.request.attributes.get('_route_params')),{'id': 0} ) %}
{% endif %}
{% set dirs = currentPath|split('/') %}
{% set flag = "" %}
{% set url = "" %}
<ol class="breadcrumb">
<li>Główna</li>
{% for key, dir in dirs %}
{% if url is not empty %}
{% set url = url ~ '/' ~ dir %}
{% else %}
{% set url = url ~ dir %}
{% endif %}
{% if flag == true %}
{% if '=' in dir %}
{% set _temp = dir|split('=') %}
{% else %}
{% set _temp = dir|split(' ') %}
{% endif %}
{% if key + 1 == dirs|length %}
<li class="active"> {{ _temp[0]|capitalize|replace('-',' ') }} </li>
{% else %}
<li> {{ _temp[0]|capitalize|replace('-',' ') }} </li>
{% endif %}
{% endif %}
{% if dir == 'app_dev.php' %}
{% set flag = true %}
{% endif %}
{% endfor %}
<li class="dropdown" style="float: right !important;">
Zalogowano jako: {{ app.security.getToken().getUser().getName() }} <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<li>Moje konteło</li>
<li>Wyloguj</li>
</ul>
</li>
</ol>
{% else %}
<ol class="breadcrumb">
<li>Główna</li>
<!--- logowanie --->
<li class="dropdown" style="float: right !important;">
Zaloguj <span class="caret"></span>
<div class="dropdown-menu" style="padding: 15px; padding-bottom: 0px; left: -200px;">
<form action="{{ path('login_check') }}" method="post">
<label for="username">Email/NIP:</label>
<input type="text" id="username" name="_username" />
<br />
<label for="password">Hasełko:</label>
<input type="password" id="password" name="_password" />
<br /><br />
<button type="submit">Loguj do Afganistanu</button>
</form>
</div>
</li>
<!--- log ---->
</ol>
{% endif %}
{{ render(controller('SoczewkiPlatformaBundle:Language:create')) }}
{% block pageContainer %}
{% endblock %}
</body>
</html>
Nothing shows and I get too any error.
Why is it like that?
// codes updated
myForm.html.twig:
{{ dump(req) }}
{{ form(form) }}
and LocaleListener.php:
<?php
namespace Soczewki\PlatformaBundle\Translations;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class LocaleListener implements EventSubscriberInterface
{
private $defaultLocale;
public function __construct($defaultLocale = 'pl')
{
$this->defaultLocale = $defaultLocale;
}
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
if (!$request->hasPreviousSession()) {
return;
}
// try to see if the locale has been set as a _locale routing parameter
if ($locale = $request->attributes->get('_locale')) {
$request->getSession()->set('_locale', $locale);
} else {
// if no explicit locale has been set on this request, use one from the session
$request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
}
}
public static function getSubscribedEvents()
{
return array(
// must be registered before the default Locale listener
KernelEvents::REQUEST => array(array('onKernelRequest', 17)),
);
}
}
You have created a situation where you are calling the same method an infinite amount of times until the page just dies.
You original base is being rendered which is in the end rendering the SoczewkiPlatformaBundle::base.html.twig template. Within this template a render() is calling an action that is then rendering the SoczewkiPlatformaBundle::base.html.twig template, which then calls the render(), which then render SoczewkiPlatformaBundle::base.html.twig, and on and on...
You need to specify a template for the form to be rendered in rather than the base and then call that in your changeAction.
For example...
Soczewki\PlatformaBundle\Controller\LanguageController
public function changeAction(Request $Request)
{
// ..
return $this->render("SoczewkiPlatformaBundle:Locale:change_form.html.twig",
array(
'form' => isset($form) ? $form->createView() : null,
));
}
SoczewkiPlatformaBundle:Locale:change_form.html.twig
{{ form_start(form, {'method': 'POST', 'action': 'your_locale_change_route' }) }}
{{ form_row(form.locale) }}
{{ form_end(form) }}
Your next problem would be that your changeAction isn't actually performing an action (apart from creating a form), although you may just be wanting that page to show before you get to that part.
You need to add this code where you want that the form appear
{{ form(form) }}
Edited after the comments below;
Create a file named myForm.html.twig and put in SoczewkiPlatformaBundle;
Now write this code inside:
{{ form(form) }}
now your controller should be:
public function changeAction(Request $Request)
{
$form = $this->createFormBuilder()
->add('locale', 'locale', array(
'label' => 'user.locale',
'required' => true,
'choices' => array('en' => 'English', 'de' => 'Deutsch', 'pl' => 'Polish')
))
->getForm();
$form->handleRequest($Request);
return $this->render("SoczewkiPlatformaBundle::myForm.html.twig",
array(
'form' => $form->createView(),
));
}
I have a list of records that the user needs the option to edit. This is what I've got so far:
{% for mpt in mempassedtest %}
<!-- Modal Windows: Add Tests & Achievements -->
<div id="editTA{{mpt.id}}" class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4>Edit Test & Achievement</h4>
</div>
<div class="modal-body">
<form action="{{ path('members_edit_personaldetails', {'member' :memid}) }}" method="post" {{ form_enctype(ta) }} id="editFamilyDetails" class="modaledit">
<table class="table modalform table-condensed">
<tbody>
<tr class="hidden">
<th>{{ form_label(ta.id, 'ID*', { 'attr': {'class': 'title'} }) }}</th>
<td>
{{ form_errors(ta.id) }}
{{ form_widget(ta.id, { 'attr': {'class': 'form-control'}}) }}
</td>
</tr>
<tr class="hidden">
<th>{{ form_label(ta.contact, 'Member*', { 'attr': {'class': 'title'} }) }}</th>
<td>
{{ form_errors(ta.contact) }}
{{ form_widget(ta.contact, { 'attr': {'class': 'form-control'}}) }}
</td>
</tr>
<tr>
<th>{{ form_label(ta.testDescription, 'Test*', { 'attr': {'class': 'title'} }) }}</th>
<td>
{{ form_errors(ta.testDescription) }}
{{ form_widget(ta.testDescription, { 'attr': {'class': 'form-control'}}) }}
</td>
</tr>
<tr>
<th>{{ form_label(ta.taken, 'Test Taken*', { 'attr': {'class': 'title'} }) }}</th>
<td>
{{ form_errors(ta.taken) }}
{{ form_widget(ta.taken, { 'attr': {'class': 'form-control'}}) }}
</td>
</tr>
<tr>
<th>{{ form_label(ta.result, 'Result*', { 'attr': {'class': 'title'} }) }}</th>
<td>
{{ form_errors(ta.result) }}
{{ form_widget(ta.result, { 'attr': {'class': 'form-control'}}) }}
</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<input type="submit" value="Save Changes" id="savebuttonta" class="btn btn-success" />
Close
{{ form_rest(ta) }}
</form>
</div>
</div>
</div>
</div>
{% endfor %}
And in the Controller I have this:
// Retrieve Passed Tests For That Member
$passedmembertests = $dm->createQuery('
SELECT mt.id, mt.taken, mt.result, mtd.test
FROM InstructorBundle:MapTests mt
LEFT JOIN InstructorBundle:MapTestDescriptions mtd WHERE mtd.id = mt.testDescription
LEFT JOIN InstructorBundle:MapCentreContacts mc WHERE mc.id = mt.contact
WHERE mc.id = :member
AND mt.result = :passed'
)->setParameters(array(
'member' => $memberint,
'passed' => '1'
));
$mempassedtest = $passedmembertests->getResult();
// Get Tests from Entity for Form use
$memberTA = $dm->getRepository('InstructorBundle:MapTests')->find($memberint);
// Generate Form to edit Tests & Achievements
$ta = $this->createForm( new TaType(), $memberTA);
However, while the modal window is generated each time a record is retrieved, the form doesn't display. What am I missing?
EDIT
This is the TaType() code:
<?php
// src/Acme/MembersBundle/Form/Type/TaType.php
// This is to handle forms for the Members Form
namespace Acme\MembersBundle\Form;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class TaType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('id', 'integer', array('required'=>false));
$builder->add('contact','entity', array('class'=>'Acme\InstructorBundle\Entity\MapCentreContacts', 'property'=>'id'));
$builder->add('testDescription','entity', array('class'=>'Acme\InstructorBundle\Entity\MapTestDescriptions', 'property'=>'test',
'query_builder' => function(EntityRepository $br) {
return $br->createQueryBuilder('mtd')
->where('mtd.active = :active')
->setParameter('active', '1');
}));
$builder->add('taken', 'date', array('years' => range(1998, date('Y')), 'format' => 'dd-MMMM-yyyy'));
$builder->add('result', 'choice', array(
'choices' => array(
'0' => 'Failed',
'1' => 'Passed'
)
));
}
public function getName()
{
return 'ta';
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\InstructorBundle\Entity\MapTests',
'csrf_protection' => false,
'csrf_field_name' => '_token',
// a unique key to help generate the secret token
'intention' => 'task_item',
));
}
}
A form can only be displayed once.
As I see you have the same form and try to display it more than one time (it is inside a for).
Check if the first time you display the fields it works, and the other times you are trying to display it, it should not return any code.
Update: Multiple forms for TAType()
Create a MainType and inside add this
->add("taList","collection",
array(
"type" => new TAType(),
"label" => false,
'options' => array(
"label" =>false,
)
)
)