Symfony 2.4 - Adding dinamically fields in the form - php

I have created a form using Symfony 2.4 that is not linked to any entity because I only want to take the data to create a report. I have created a form using an AbstractType extended class and I need to add several items since the form represents a bill. I know about the allow_add attribute, but it just lets to add a field to the form and I need to do something like I show in the image:
I have no idea at all about how to do it, I have created an item class, and it contains two attributes, but I find nowhere any information about this. Until now this is what I've got:
namespace Abadia\FacturaBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;>
class ReciboCajaType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('ciudad', 'text')
->add('fecha', 'date')
->add('valor', 'number')
->add('recibi_de', 'text')
->add('suma_recibida', 'number')
->add('suma_letras', 'textarea')
->add('bloque', 'text')
->add('numero', 'text')
->add('descripcion', 'textarea')
->add('areas_comunes', 'number')
->add('cuota_extraordinaria', 'number')
->add('saldo', 'number')
->add('cheque', 'number')
->add('otros', 'number')
->add('efectivo', 'number')
->add('generar', 'submit')
;
}
public function getName()
{
return 'abadia_facturabundle_recibocajatype';
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array());
}
}
Thanks in advanced.
UPDATE:
I forgot to mention that I am working with the Twig extension. Just in case knows how to do it using it.

Basically you will need 2 forms. One, call it main form and an another form for an item. Then you can embed the item form type into the main form type multiple times using the collection type. You will need some javascript too for adding and removing an item. It would be very long to write down exactly how to do it, but there is a good example in the docs.

Related

How to pass parameters to build selects in collection of embedded forms in Symfony

Please, I need some advice on Symfony forms and entities.
I have Questionarie(entity) form with number of assigned Rows(entities). Rows objects are assigned to Questionarie object. Each row has select input with options from DB. Options are entities, let's say OptionEntity. Each select is filled with query for OptionEntities based on one parameter.
Each Row stores chosen answer. Each answer is assigned to question. Row knows nothing about question.
So I build a QuestionarieType form with some fields and collection of embedded RowType forms.
The question is how to pass parameters to queries to build options in each row. As Rows objects are assigned to Questionarie object all rows in form are built automatically. So I don't know how map parameters to corresponding rows.
I think about additional field in Row entity to store this paramater but I don't know whether it is bad idea because Row entity is used to store chosen answer and knows nothing about question.
Thank you! Any thoughts are appreciated.
Controller action:
{
$questionarie = new Questionarie(); // just a wrapper for questions with some meta data: userId, timestamp, etc.
/*here I fetch questions from DB somehow and then iterate through them:*/
foreach ($question as $q) {
$row = new FormRow();
$questionarie->addFormRow($row);
}
$form = $this->createForm(QuestionarieType::class, $questionarie);
}
class QuestionarieType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('FormRows', CollectionType::class, array(
'entry_type' => FormRowType::class,
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Sfedu\RatingBundle\Entity\Questionarie',
));
}
}
class FormRowsType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('answer', EntityType::class, array(
'class' => 'SfeduRatingBundle:Answer',
'query_builder' => function (EntityRepository $er) use ($question_id){
return $er->createQueryBuilder('a')
->where('a.question = :question')
->setParameter('question', $question_id); //! here I want to use parameter to filter possible answers for each row
},
));
}
}

Symfony 2 registration form

I'm trying to create a registration form in Symfony 2.4 following the guide here
http://symfony.com/doc/current/cookbook/doctrine/registration_form.html
Lets say I've got 2 FormTypes
PersonType
RegistrationType
PersonType defines all the fields for a specific user.
// PersonType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('firstName','text',['attr'=>['placeholder'=>'First Name']])
->add('lastName','text',['attr'=>['placeholder'=>'Last Name']])
->add('email','email',['attr'=>['placeholder'=>'email#example.com']])
->add('title','choice', ['choices'=>$this->titles, 'required'=>true])
->add('phone','text',['attr'=>['placeholder'=>'(555) 555-1234']])
->add('accountStatus')
->add('organization')
->add('address', 'text',['attr'=>['placeholder'=>'123 Fake St']])
->add('city')
->add('province','choice', ['choices'=>$this->provinces, 'required'=>true])
->add('postalCode','text',['attr'=>['placeholder'=>"A1A 1A1"]])
;
}
RegistrationType adds:
// RegistrationType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$person = new PersonType();
$builder->add('person', $person);
$builder->add('termsAccepted','checkbox');
$builder->add('submit','submit', ['attr'=>['class'=>'btn-primary'], 'label' => "Submit Account Request"]);
}
The issue is - I don't want to include accountStatus on the registration form, as this will be set by code when I persist it to the database. When I output my form it's including the accountStatus.
In Symfony 1.4 to pull this same thing off I simply extended the PersonForm, and unset any widgets I did not require.
Am I going about this wrong? This is my first Symfony 2 project.
EDIT: I found the solution for my case. I wanted accountStatus in my main form, but want to reuse everything except that for my registration form.
I simply added this to my form after rendering all the fields I wanted
{% do form.person.setRendered %}
accountStatus is appearing in the form because of this line:
->add('accountStatus')
remove this line and you won't see it in the form.

Filtering which items to show up in collection field

I have a form using this class type:
class DespesasContainerType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('despesas', 'collection', array(
'type' => new DespesasFamiliasType(),
'by_reference' => false,
))
;
}
// ...
}
This way it shows all items in the despesas attribute of the object.
Is there a way to filter which items to use? Something similar to the query_builder option on the entity field type.
No way from FormTypeInterface, but you can filter this collection before passing it to the Form.
Another tricky tip :
Define a public getter like getFilteredDespeas on your Entity that returns the filtered list of despeas. In your Form, just call the field filteredDespeas instead of despeas. This involves that you specifically manage the form binding, by adding a public setFilteredDespeas to your entity, or any other way...

Symfony2 embedded forms using one class

Is it possible to use an Embedded form without using a separated class for it?
The reason is I've got a lot of form classes already, which most of the time contain a single field, so I wonder if it is possible to define embedded forms inline.
So normally we have something like this:
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('name')
->add('email')
->add('phone')
->add('key', new KeyType())
;
}
The documentation says that I have to create a class for the key field, KeyType for example, where I would set up the form builder for the embedded form. But I would like to, instead of creating the class KeyType, define the fields inline, in the same class. How can I do that?
Yes this is possible.
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('name')
->add('email')
->add('phone')
->add(
$builder->create('key')
->add('someField', 'text')
->add('otherField', 'checkbox')
)
;
}

Symfony 2 Form with select list

How can i create a select list with values from a database table in Symfony 2?
I have 2 entities: Student and Classroom with a ManyToOne relationship and i need to create a form with the folowing fields: name, surname, age, classroom(select list from available classes).
In my Student Form i have
$builder
->add('name')
->add('surname')
->add('age')
->add('classroom', new ClassroomType())
;
In my Classroom Form i have this:
$classrooms =$this->getDoctrine()->getRepository('UdoCatalogBundle:Classroom')->findAll();
$builder
->add('clasa','choice',array('choices' => array($classrooms->getId() => $classrooms->getName())));
I get this following error:
Fatal error: Call to undefined method Udo\CatalogBundle\Form\ClassroomType::getDoctrine() in /var/www/html/pos/src/Udo/CatalogBundle/Form/ClassroomType.php on line 13
Kind Regards,
Cearnau Dan
Not sure if you found an answer yet but I just had to do some digging around to figure this out for my own project.
The form class isn't set up to use Doctrine like the controller is so you can't reference the Entity the same way. What you want to do is use the entity Field Type which is a special choice Field Type allowing you to load options from a Doctrine entity as you are trying to do.
Ok so long story short. Instead of doing what you are doing to create the choice field, do this:
->add('category', 'entity', array(
'class' => 'VendorWhateverBundle:Category',
'query_builder' => function($repository) { return $repository->createQueryBuilder('p')->orderBy('p.id', 'ASC'); },
'property' => 'name',
))
I'm not sure if you could place the query_builder function into a repository or what, I'm kind of swinging wildly as I go. Up to this point the documentation I linked to above is pretty clear on what to do. I guess the next step is to read up on Doctrine's QueryBuilder.
While you're in there I think you want to drop the bit where you are embedding the Classroom form,
->add('classroom', new ClassroomType())
You probably don't want people creating their own classrooms. Unless you do, then yeah.
If the entities are mapped, this is a clean solution for Symfony 2.8+ or 3+
<?php
namespace My\AppBundle\Form\Type;
use My\AppBundle\Entity\Student;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class StudentType extends AbstractType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('surname')
->add('age')
/*
* It will be resolved to EntityType, which acts depending on your doctrine configuration
*/
->add('classroom');
}
/**
* {#inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(['data_class' => Student::class]);
}
}

Categories