Symfony2 entity choice issue - php

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

Related

Symfony how to validate EntityType field

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.

Symfony3: form: populate select with related model entries

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

symfony custom form field type error when adding child field

I have an entity Nace that holds hierarchical data. It is mapped as a many-to one association to an entity Organisation.
class Organisation
{
/**
* #ORM\ManyToOne(targetEntity="Pftp\UserBundle\Entity\Nace")
* #ORM\JoinColumn(name="nace_id", referencedColumnName="id")
*/
private $nace;
}
The following form renders the nace property as a drop-down with all records in Nace as expected (showing my starting point).
class OrganisationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('nace')
;
}
}
As Nace contains several hundreds of records, I want to implement a custom FieldType
which adds a second entity choice field with higher level options from the same table (categories)
which populates the main choice field via ajax when the user selects a category
When I add the naceCategory child field and try to render the form, I get the an error related to data mapping.
In order to figure the data flow, I added a ModelTransformer but the methods transform and reverseTransform are never called. Here is my code:
Template
{% block nace_widget %}
{{ form_widget(form) }}
{{ form_widget(form.naceCategory) }}
{% endblock %}
NaceType
class NaceType extends AbstractType
{
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'compound' => true,
'mapped' => true,
'required' => true,
'class' => 'Pftp\UserBundle\Entity\Nace',
'query_builder' => function(NaceRepository $er) {
return $er->createQueryBuilder('node')->where('1=0');
},
));
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add($builder->create('naceCategory', 'entity', array(
'mapped' => false,
'required' => false,
'class' => 'Pftp\UserBundle\Entity\Nace',
'query_builder' => function(NaceRepository $er) {
return $er->getCategoriesQueryBuilder();
}
)))
->addModelTransformer(new NaceTransformer())
;
}
public function getParent()
{
return 'entity';
}
public function getName()
{
return 'nace';
}
}
Error
Expected argument of type "object, array or empty", "string" given
at PropertyPathMapper ->mapDataToForms ('', object(RecursiveIteratorIterator))
in W:\Symfony2\Sources\pftpprod\vendor\symfony\symfony\src\Symfony\Component\Form\Form.php at line 385 +
at Form ->setData (null)
in W:\Symfony2\Sources\pftpprod\vendor\symfony\symfony\src\Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper.php at line 57 +
at PropertyPathMapper ->mapDataToF...
Analogy
Let me try and give you a better idea of what I'm trying to achieve as this Nace thing is pretty unknown.
Basically, I need 2 cascading drop-downs. Imagine you have a list of all the cities of the world in one table and you want the user to choose only 1. As the list is too long, you would want the user to first choose a country from another drop-down (not mapped with your target entity), which should populate your city drop-down with a limited list of cities.
Well, in my case nace corresponds to the city drop-down (initially empty), and naceCategory corresponds to the country drop-down (always populated with the repo method getCategoriesQueryBuilder()). The only difference to the city/country exmaple is, that both drop-downs are hydrated from the same table/entity (Nace), just with values from different hierachy levels.
Does anybody know what I'm missing here?

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...

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