I have an add form and I want to add a field that will be visible unless if the previous field is checked (it is checkbox type),
the two fields belong to different tables that have a one to one relationship and I work under symfony4
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nom')
->add('prenom')
->add('dateNaissance', BirthdayType::class)
->add('email', EmailType::class)
->add('profession')
->add('typePieceIdentite', ChoiceType::class, [
'choices' => ['Carte National'=>'Carte National' ,
'Permi de conduire' =>'Permi de conduire',
'Passeport' =>'Passeport',]])
->add('numPiece')
->add('aUnVehicule', CheckboxType::class)
->add('vehicule', VehiculeType::class)
;
}
Related
CollectionType field has special 'prototype' variable when 'allow_add' option is set to true. This variable can be used to render prototype html like this:
data-prototype="{{ form_widget(form.collectionfieldname.vars.prototype)|e('html_attr') }}"
It looks like 'prototype' is simply an instance of collection children FormView built with partial data (e.g. name is set to "__name__" while most other vars are left blank).
Where all this magic happens? Is it possible to modify what data is passed to prototype view while building form? For example, I would like to change default value of "value" variable from blank to "__val__" (outside of Twig template).
Answer to own question - values defined in "entry_options" setting are used to build prototype. It is possible to pass these values to form builder like this:
$builder
->add('email', CollectionType::class, array(
...
'entry_options' => array(
'someoption' => 'somevalue',
),
...
))
If this is not enough, default behaviour can be modified by overriding "buildForm" method in "CollectionType" class which is responsible for collecting options and building prototype:
class CollectionType extends AbstractType
{
...
public function buildForm(FormBuilderInterface $builder, array $options)
{
if ($options['allow_add'] && $options['prototype']) {
$prototypeOptions = array_replace(array(
'required' => $options['required'],
'label' => $options['prototype_name'].'label__',
), $options['entry_options']);
if (null !== $options['prototype_data']) {
$prototypeOptions['data'] = $options['prototype_data'];
}
$prototype = $builder->create($options['prototype_name'], $options['entry_type'], $prototypeOptions);
$builder->setAttribute('prototype', $prototype->getForm());
}
...
}
...
}
I was wondering if it were possible to set something like a property path to an annontation constraint where the assertion should be applied on.
Consider this example:
/**
* #ORM\OneToOne(targetEntity="Document", cascade={"persist"})
* #Assert\Image(mimeTypes={"jpeg", "png"}, path="this.file")
*
protected $document;
In this example I would like to apply the Image constraint to the file property which is a child of the Document entity with an attribute like path="this.file"
Is this somehow possible?
I can only think of defining dynamically the constraint in php.
use Symfony\Component\Validator\Constraints\Image;
// [...]
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('document', FileType::class, [
'constraints' => [
new Image([
'mimeTypes' => ["jpeg", "png"],
'path' => $anyVariable
])
],
]);
You could make your own validator as explained in this doc and then apply to any field you want.
Hope it helps
Say, there is a simple many-to-one relations: Model has hair type and eyes color:
/**
* #ORM\Entity
*/
class Model
{
/**
* #ORM\ManyToOne(targetEntity="Hair")
* #ORM\JoinColumn(name="hair_id", referencedColumnName="id")
*/
protected $hair;
/**
* #ORM\ManyToOne(targetEntity="Eyes")
* #ORM\JoinColumn(name="eyes_id", referencedColumnName="id")
*/
protected $eyes;
For example, hair could be: blonde, brown, black, red;
The eyes: blue, green, gray, brown.
In the search form I want user to be able to select multiple hair types and eyes at once. I use 'multiple' property:
class ModelType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('hair', EntityType::class, [
'class' => 'AppBundle:Hair',
'choice_label' => 'name',
'multiple' => true,
])
->add('eyes', EntityType::class, [
'class' => 'AppBundle:Eyes',
'choice_label' => 'name',
'multiple' => true,
])
->getForm();
;
}
The form renders like this:
Of course, when selecting multiple values and submitting it causes an error:
Expected argument of type "AppBundle\Entity\Hair", "Doctrine\Common\Collections\ArrayCollection" given
Perhaps, this is not for using in such a case?
Are any best practices for building search forms in Symfony? Didn't find any...
The problem is not the form but your mapping.
I assume your form is binded with the Model Entity.
That's why the ManyToOne relation accepts only one related entity.
Solution :
Don't bind your form to the Model Entity, just use a form without class :
http://symfony.com/doc/current/form/without_class.html
Model can have many hair color and many eyes color ?
In this case you have to use many-to-many relation instead of many-to-one
If not, you have to remove 'multiple' => true, in you ModelType
In my form builder, using an entity choice field I can retrieve the contents of an entity by:
$builder->add('manufacturer', 'entity', array(
'class' => 'Manufacturer'....
Everything works fine and the selectbox is rendered correctly at the view. However, I would like to add an extra option at the selectbox called "Add new" (it will not be mapped to an entity), which would result at a select box with options of manufacturers plus one at the end with Add new. What is the best Symfony2 way to achieve that?
public function finishView(FormView $view, FormInterface $form, array $options)
{
$new_choice = new ChoiceView(null, 'value', 'label');
$view->children['manufacturer']->vars['choices'][] = $new_choice;
}
I'm trying to place a custom checkbox to form. This checkbox is not referenced to any doctrine2 object field. The checkbox is like "remember me" on signin form.
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('login');
$builder->add('password');
$builder->add('remember_me');
}
No mapping found for field 'remember_me' in class ...
How should I solve this?
Thank you!
Use property_path option as :
$builder->add('remember_me', 'checkbox', array('property_path' =>
false))