I have this EntityType field on my UserType's form:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('country', EntityType::class, array(
'class' => Country::class,
'choice_label' => 'nicename'
));
}
How can i use validation constraints to validate this type of field in the way that user can only select a value in the range of all rows of country's table? I think that I should use Choice constraint with callback, and call the getAllCountries function inside my CountryRepository class. So what's the best way to manage this scenario?
Somethins like this:
// UserEntity.php
class User {
/**
* #Assert\Choice(callback="App\Repository\CountryRepository", "getAllCountries")
* #ORM\ManyToOne(targetEntity="App\Entity\Country", inversedBy="users")
*/
protected $country;
}
But CountryRepository is not a static function!!
Entity field doesn't allow to select invalid value (if you have invalid value it would't find the entity -> wouldn't be able to send form). This is as well behaviour of choice type.
But for callback, there is special callback constraint - https://symfony.com/doc/current/reference/constraints/Callback.html which can be used to call constraint function.
Related
I have a little problem in my Symfony form.
This is my code:
class ProfileFormType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('adress',null,array('label' => 'form.adress', 'translation_domain' => 'FOSUserBundle'))
->add('niveau','entity',array(
'class'=>'EnsajAdministrationBundle:Niveau',
'property'=>'libelle'
,'multiple'=>false)
)
The problem is that normally it returns all rows for the named Entity, but I want to return just the 2 first rows from the "niveau" ("level") table, to be used as the choices for my form.
What is the solution for this problem?
You have (at least) a couple of options here, but the obvious one is to supply a QueryBuilder to the field which provides the required rows (see Symfony docs on EntityType Field)
E.g.
//Create function which accepts EntityRepository and returns required QueryBuilder
$qbFunction = function(EntityRepository $er) {
return $er->createQueryBuilder('n')
//->orderBy() //If you need to, to get the correct 2 rows!
->setMaxResults(2); //Just two rows
};
$builder->add('adress',null,array('label' => 'form.adress', 'translation_domain' => 'FOSUserBundle'))
->add('niveau','entity',array(
'class'=>'EnsajAdministrationBundle:Niveau',
'property'=>'libelle'
,'multiple'=>false
,'query_builder' => $qbFunction) //give function to field
)
You can make the query more complex if you need to, e.g. add joins
I have two models, topic and user. Both are related by many-to-one relationship (a topic is defined by only one user) such as:
class User
{
private $idUser;
private $username;
}
class Topic
{
private $idTopic;
private $topicName;
private $idUser;
}
MAIN CONCERN: I would like (using symfony-forms) to create a creation form for the topic model. The form would contain:
a topic name input
a user select (list populated by the existing users in the database. The displayed value would be the username of course).
I have created a TopicType class that will build the topic creation form:
class TopicType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->
->add('topicName')
->add(/* 'idUser', 'choice', 'THE USER LIST ???*/)
}
public function configureOptions(FormBuilderInterface $builder, array $options)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Topic'
));
}
}
How can I retrieve the list of users and populate the choices considering I don't have access to the entity manager in TopicType context?
Could I pass a $users array in the controller as a parameter when invoking createForm method ? If so, how ?
If you understood what I'm trying to do, Is there a better/simplier way to get it done ? Am I missing something ?
I know this question might look similar but all the solutions I found on related topics are somehow deprecated in Symfony3
Any help would be much appreciated.
Have a good day to you all.
you should try something like this (you must adapt the code):
->add('User', EntityType::class, array(
'class' => 'xxxBundle\Entity\User',
'choice_label' => 'username',
'required' => true,
'multiple' => false,
))
do not forget :
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
More info here : http://symfony.com/doc/current/reference/forms/types/entity.html
I have an entity form field in my Symfony2 project.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('productId', 'genemu_jquerychosen_entity', array(
'class' => 'EMRSabaBundle:Product',
'property' => 'name'
))
;
}
The Product entity has some objects like price, name, mode, & id
I want to let user choose the product by name & see chosen produc's price, then submit product ID, not name.
Is there any soloution?
As per the documentation for this bundle:
You can use all the core choice types from Symfony (choice, country,
...) and Doctrine (ORM and ODM), you just have to prefix the type name
with genemu_jqueryselect2_*
This means you are using a "regular" entity field. You can do what you want by skipping the definition of property and relying on the __toString() method from EMRSabaBundle:Product:
[property]
This is the property that should be used for displaying the entities
as text in the HTML element. If left blank, the entity object will be
cast into a string and so must have a __toString() method.
Change your code to:
$builder->add('productId', 'genemu_jquerychosen_entity', array(
'class' => 'EMRSabaBundle:Product'
))
And define the _toString() method in your EMRSabaBundle:Product object as follow:
public function __toString()
{
return $this->name . ' (' . $this->price . ')';
}
http://symfony.com/doc/current/reference/forms/types/entity.html#property
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...
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]);
}
}