This is my file:
<?php
namespace EM\ExpensesBundle\Entity;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\AbstractType;
class ChooseCatType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('name', 'entity', array(
'class' => 'EMMyFriendsBundle:Category',
'property' => 'name',
'empty_value' => 'All items',
'required' => false,
'query_builder' => function ($repository)
{ return $repository->createQueryBuilder('cat')
->select('cat')
->orderBy('cat.name', 'ASC');
}, ));
}
public function getName()
{
return 'choose_category';
}
}
Here I create the form:
namespace EM\ExpensesBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use EM\ExpensesBundle\Entity\Category;
use EM\ExpensesBundle\Entity\ChooseCatType;
class HomeController extends Controller
{
public function indexAction()
{
//Categories
$cat = new Category();
$dd_form = $this->createForm(new ChooseCatType(), $cat);
return $this->render('EMExpensesBundle:Home:index.html.twig', array(
'dd_form' => $dd_form->createView()));
}
}
and template:
{% extends "::base.html.twig" %}
{% block title %}
Expenses
{% endblock %}
{% block body %}
<div class="content">
<p> Choose category: </p>
<form class="cat" action="" method="post" {{ form_enctype(dd_form) }}>
{{ form_widget(dd_form.name) }}
{{ form_rest(dd_form) }}
<input type="submit" value="Show items" />
</form>
Manage Categories
</div>
{% endblock %}
but I get an error:
Fatal error: Declaration of EM\ExpensesBundle\Entity\ChooseCatType::buildForm()
must be compatible with that
of Symfony\Component\Form\FormTypeInterface::buildForm()
in C:\xampp\htdocs\Expenses\src\EM\ExpensesBundle\Entity\ChooseCatType.php
on line 9
Any ideas?
Use FormBuilderInterface in your method signature:
public function buildForm(FormBuilderInterface $builder, array $options)
Related
I've worked through a few of the Forms-Tutorials on the Symfony-Page (especially How to Embed a Collection of Forms, How To use a Form without a Dataclass & CollectionType Field ).
I'm trying to show a form with multiple lead partners which can be edited and submitted back to the system.
But i get a Twig_Runtime_Error saying: ''Variable "lead_partners" does not exist''.
My Twig:
{% block content %}
<div>
{{ form_start(form) }}
{% for partner in lead_partners %}
{{ form_row(partner.name) }}
{% endfor %}
{{ form_end(form) }}
</div>
{% endblock content %}
My Controller Code:
public function overview(Request $request, \App\Utility\LeadPartnerLoader $LeadPartnerLoader)
{
$leadPartnerList = $LeadPartnerLoader->loadAll();
$form = $this->createFormBuilder($leadPartnerList)
->add('lead_partners', CollectionType::class, [
'entry_type' => LeadPartnerFormType::class,
])->getForm();
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid())
{
$data = $form->getData();
}
return $this->render(
'lead_partner_overview2.html.twig',
[
'form' => $form->createView()
]);
}
And the Form Type (LeadPartnerFormType):
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => LeadPartner::class,
));
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('id', HiddenType::class)
->add('name', TextType::class);
}
$leadPartnerList is of type array.
What am i doing wrong/missing here?
Kind Regards
It seems your action overview soesn't return the lead_partners variable you use in your template.
You can try to do this
return $this->render(
'lead_partner_overview2.html.twig',
[
'form' => $form->createView(),
'lead_partners' => $leadPartnerList, // I gess that's the list you want to loop ?
]);
I havenĀ“t found the solution to manually render a form which contains a collection.
Here is my code in twig:
<ul id="document-fields-list" data-prototype="{{ form_widget(formulario.documentos.vars.prototype)|e }}">
<div><button class="pull-right" href="#" id="add-another-document">Agregar documento</button></div>
{% for documento in formulario.documentos %}
<li>
{{ form_label(documento) }}
{{ form_widget(documento) }}
Eliminar
</li>
{% endfor %}
</ul>
FormType
In your case we need to create formType for PersonaDocumento. Imagine, that this entity has field documentName:
class PersonaDocumentoType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
* #SuppressWarnings(unused)
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('documentName', TextType::class, [
'label' => false,
'translation_domain' => 'messages'
])
;
}
/**
* #return string
*/
public function getName()
{
return 'app_persona_documento_type';
}
/**
* #return null|string
*/
public function getBlockPrefix()
{
return 'app_persona_documento';
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => PersonaDocumento::class,
'csrf_protection' => true,
'validation' => true,
));
}
}
Form that contain collection
Consider you entity Formulario. It has a OneToMany relation to PersonaDocumento. And Form will be:
class FormularioFormType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
// ...
$builder
->add('documentos', CollectionType::class, [
'entry_type' => PersonaDocumentoType::class,
'entry_options' => [
'label' => false,
],
'label' => false,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false, // Very important thing!
])
;
}
// ...
}
Widget for collection
We have a form (FormularioFormType) that contain collection of small forms with type PersonaDocumentoType.
New widget you can create in file with standard widgets, and name of the file is fields.html.twig : path_to_your_project/src/AppBundle/Resources/views/Form/fields.html.twig.
Name of the block will be app_persona_documento_widget.
Thus, example of fields.html.twig :
{% trans_default_domain 'messages' %}
{% block app_persona_documento_widget %}
{% spaceless %}
<div class="form-group" {{ block('widget_container_attributes') }}>
<div class="col-sm-12">
{{ form_widget(form.name, {'attr' : { 'placeholder' : 'app.form.label.name'|trans , 'class' : 'form-control' }}) }}
</div>
</div>
{% endspaceless %}
{% endblock app_persona_documento_widget %}
Also pay attention that "app_persona_documento_widget" - assembled from the getBlockPrefix() of you PersonaDocumentoType plus string "_widget"
Register new form themes in config.yml
# Twig Configuration
twig:
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
form_themes:
# other form themes
# ...
- 'AppBundle:Form:fields.html.twig'
Render collection in parent form
{{ form_start(formulario_form) }}
<div class="form-group">
<label for="" class="col-sm-2 control-label">
Label
</label>
<div class="col-sm-10 documentos" data-prototype="{{ form_widget(formulario_form.documentos.vars.prototype)|e('html_attr') }}">
{% for document in formulario_form.documentos %}
<div>
{{ form_widget(document) }}
</div>
{% endfor %}
</div>
</div>
<span>
{{ form_errors(formulario_form) }}
</span>
{# Here you can add another fields of form #}
{{ form_end(formulario_form) }}
Of course, you also need buttons: one "Add another document" button and "Remove" buttons for each "Documento" item.
Symfony documentation suggests that we use JavaScript for this purpose.
You can read more here in official docs
Also you can install Ninsuo/symfony-collection - A jQuery plugin that manages adding, deleting and moving elements from a Symfony collection
I would like to create a function to search for a movie through the query builder
I have a table Movie:
1. Id
2. Titre
3. Content
And i have class MovieRepository :
class MovieRepository extends EntityRepository
{
public function myFindAll()
{
return $this->createQueryBuilder('a')
->getQuery()
->getResult();
}
public function getSearchMovies($movie){
$qb = $this->createQueryBuilder('m')
->where('m.title LIKE :title')
->setParameter('title', '%' . $movie->getTitle() . '%')
->orderBy('m.title', 'DESC')
->getQuery();
}
}
Also i have MovieController :
public function indexAction()
{
$movie = new Movie;
$form = $this->createForm(new SearchMovieType(), $movie);
$request = $this->getRequest();
if ($request->getMethod() == 'POST') {
$form->bind($request);
$movies = $this->getDoctrine()
->getManager()
->getRepository('AreaDownloadBundle:Movie')
->getSearchUsers($movie);
return $this->render('AreaDownloadBundle:Download:index.html.twig', array('form' => $form->createView(),array('movies' => $movies)));
} else {
$movies = $this->getDoctrine()
->getManager()
->getRepository('AreaDownloadBundle:Movie')
->myFindAll();
return $this->render('AreaDownloadBundle:Download:index.html.twig',array('form' => $form->createView(), 'movies' => $movies));
}
}
SearchMovieType :
class SearchMovieType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title','text', array('required' => false, ))
;
}
And i have index.hml.twig, which can display movies with a search bar :
{% extends "::template.html.twig" %}
{% block body %}
<form action="{{ path('area_download_index') }}" method="post">
<div id="bar">
{{ form_widget(form.title) }}
<input type="submit" value="Chercher">
{{ form_rest(form) }}
</div>
</form>
{% for movie in movies %}
{{ movie.title }}
{{ movie.content }}
{% endfor %}
{% endblock %}
when I seized a title of a movie he sends me this error
Variable "movies" does not exist in AreaDownloadBundle:Download:index.html.twig at line 12
Instead of posting it as a comment, it should have been posted as an answer in the correct formatting; like so:
return $this->render(
'AreaDownloadBundle:Download:index.html.twig',
array(
'form' => $form->createView(),
'movies' => $movies
)
);
This definitely should fix the problem!
I'm having trouble rendering individual form fields in a twig template from a Symfony 2 form. In the example below, I'm simply trying to render the first_name form field.
Also, form_errors never renders anything.
Here is my Form object:
namespace ABC\WebsiteBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class LoanApplication extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('first_name', 'text', array('required' => true));
}
public function getName()
{
return 'LoanApplication';
}
public function getDefaultOptions(array $options)
{
return array(
//'data_class' => 'Acme\TaskBundle\Entity\Task',
'csrf_protection' => true,
'csrf_field_name' => '_token',
// a unique key to help generate the secret token
'intention' => 'loan_application',
);
}
}
Here is the controller:
namespace ABC\WebsiteBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use JML\WebsiteBundle\Form\LoanApplication;
use JML\WebsiteBundle\QuickBase as QuickBase;
class ApplyController extends Controller
{
public function indexAction()
{
$form = $this->createForm(new LoanApplication());
return $this->render('ABCWebsiteBundle:Apply:index.html.twig', array(
'form' => $form->createView(),
));
if ($request->getMethod() == 'POST') {
$form->bindRequest($request);
if ($form->isValid()) {
// perform some action, such as saving the task to the database
//return $this->redirect($this->generateUrl('task_success'));
}
}
}
}
And the twig:
<form action="{{ path('apply') }}" method="post" {{ form_enctype(form) }}>
<pre>
{{ dump(form_errors(form)) }} // always empty
</pre>
<div>
{{ form_label(form.first_name) }} // this renders
{{ form_widget(form.first_name) }} //empty
{{ form_row(form.first_name) }} //empty
</div>
<input type="submit" formnovalidate/>
</form>
i need your help please , I want to display my created form in Symfony2. I want to display my created form 92 times becouse i have 92 numbers in my database(every number is a form) , i didn't know how to do it here is my code:
controller:
class DefaultController extends Controller
{
public function QuestionsAction(Request $request)
{
$questions = $this->getDoctrine()->getEntityManager()
->getRepository('Tests\TestsPhpBundle\Entity\Question')
->findAll();
$task = new Question();
$forms = $this->createForm(new QuestionType(), $task);
if ($request->getMethod() == 'POST') {
$forms->bindRequest($request);
if ($forms->isValid())
{
$em = $this->getDoctrine()->getEntityManager();
$em->persist($task);
$em->flush();
}
}
{
return $this->render('TestsTestsPhpBundle:Default:index.html.twig', array(
'questions' => $questions,
'forms' => $forms->createView()
));
}
}
}
my form file:
class QuestionType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('categories', null, array('required' => false,
))
->add('text', 'entity', array(
'class' => 'TestsTestsPhpBundle:Question',
'query_builder' => function($repository) {
return $repository->createQueryBuilder('p')->orderBy('p.id', 'ASC'); },
'property' => 'text'))
;
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'Tests\TestsPhpBundle\Entity\Question',);
}
public function getName()
{
return 'question';
}
}
my twig file:
{% block content %}
<h2>Questions</h2>
{% for question in questions %}
<dl>
<dt>Number</dt>
<dd>{{ question.number }}<dd>
{% for form in forms %}
{{ form_row(forms.categories) }}
{{ form_row(forms.text) }}
</dl>
{% endfor %}
<hr />
{% endfor %}
{% endblock %}
I recommend to read capter: Embedding Controller
http://symfony.com/doc/2.0/book/templating.html
<div id="sidebar">
{% render "AcmeArticleBundle:Article:recentArticles" with {'max': 3} %}
</div>
You can make a for loop within Twig Template and call an action (with parameter if needed) where you render the form. -> QuestionsAction in your case.