Symfony 3 embedded forms labels not numbers - php

Is it possible to change those numbers (names of embedded forms) to some other labels (they depend on StatisticField's name property) without using javascript?
StatisticType has StatisticFieldTypes:
$builder->add('statisticFields', CollectionType::class, array(
'entry_type' => StatisticFieldType::class,
'by_reference' => true,
));
StatisticFieldType:
$builder->add('dateSince', DateTimeType::class, [
'widget' => 'single_text',
'label' => 'date.since',
'required' => false,
])
->add('dateTo', DateTimeType::class, [
'widget' => 'single_text',
'label' => 'date.to',
'required' => false,
]);
Thanks.
[EDIT_1]:
My template:
<h1>Statistic creation</h1>
{{ form_start(form) }}
{{ form_widget(form) }}
<input type="submit" value="Create"/>
{{ form_end(form) }}

Try
$builder->add('statisticFields', CollectionType::class, array(
'entry_type' => StatisticFieldType::class,
'entry_options' => array('label' => false),
'by_reference' => true,
));
The numbers came from CollectionType
EDIT:
With Names
$name = 'IamNotANumber';
$builder->add('statisticFields', CollectionType::class, array(
'entry_type' => StatisticFieldType::class,
'entry_options' => array('label' => $name),
'by_reference' => true,
));

The solution was to override buildView method in StatisticFieldType (embedded form type) and get the data from the form :
/**
* {#inheritDoc}
*/
public function buildView(FormView $view, FormInterface $form, array $options)
{
// For Symfony 2.1 and higher:
$view->vars['label'] = $form->getData()->getName();
}

Related

How to fill Smyfony CollectionType with N forms based on Database Rows

I have a CollectionType of EditAnnouncementType typeform I have created. This CollectionType will be used to render a form to handle a user editing some text of an Announcement, where each announcement has its own Edit modal that opens (the modals have unique ID's)
$editForm = $this->createFormBuilder()
->add('editForms', CollectionType::class,
[
'entry_type' => EditAnnouncementType::class,
'allow_add' => true,
'prototype' => true,
'by_reference' => false,
'required' => false,
])
->add('edit', SubmitType::class,
array
(
'label' => 'Save changes',
'attr' => ['class' => 'btn btn-primary']
))
->setData($this->getDoctrine()->getRepository(Announcement::class)->findAll())
->getForm()
;
How do I prefill N number of forms based on N number of rows (aka N announcement entities.)
formtype code
class EditAnnouncementType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('edit', SubmitType::class,
array
(
'label' => 'Save changes',
'attr' => ['class' => 'btn btn-primary']
))
->add('id', HiddenType::class, [])
;
}
/**
* Returns the name of this type.
*
* #return string
*/
public function getName()
{
return 'edit_announcement';
}
}
Try with this
$editForm = $this->createFormBuilder()
->add('editForms', CollectionType::class,
[
'entry_type' => EditAnnouncementType::class,
'allow_add' => true,
'prototype' => true,
'by_reference' => false,
'required' => false,
])
->add('edit', SubmitType::class,
array
(
'label' => 'Save changes',
'attr' => ['class' => 'btn btn-primary']
))
->setData(['editForms' => $this->getDoctrine()->getRepository(Announcement::class)->findAll()])
->getForm()
;

Symfony embedded ChoiceType form updating every entity instance

I have an EditAnnouncementType form which is embedded in a CollectionType form. The embedded form has two ChoiceType forms, one which properly updates the mapped Announcement entity. The other one however, will attempt to update all instances of the entity in my database, resulting in this error.
Type error: Argument 1 passed to AppBundle\Entity\Announcement::setType() must be of the type integer, null given, called in /Users/dperezpe/dev/grand-central/673/grand-central/vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php on line 528
EditAnnouncementType.php The type form is the error one.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('edit', SubmitType::class,
array
(
'label' => 'Save changes',
'attr' => ['class' => 'btn btn-primary']
))
->add('type', ChoiceType::class,
[
'choices' =>
[
'info_type' => 1,
'star_type' => 2,
'alert_type' => 3,
'lightbulb_type' => 4,
'event_type' => 5,
'statement_type' => 6,
'cat_type' => 7,
'hands_type' => 8
],
'expanded' => true,
'multiple' => false,
'required' => true,
'label_attr' => array(
'class' => 'sr-only'
),
])
->add('audience', ChoiceType::class,
[
'choices' =>
[
'Students: anybody with a student level field populated' => 'students',
'Employees: anybody with an employee ID number' => 'employees'
],
'expanded' => true,
'required' => true,
'multiple' => true
])
The CollectionType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('announcements', CollectionType::class,
[
'entry_type' => EditAnnouncementType::class,
'entry_options' => ['label' => false],
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => AnnouncementManager::class
]);
}
I suspect it is related to the difference in the HTML name that was rendered to this, where the type inputs are missing an empty []
<input type="radio"
id="announcement_edit_collection_announcements_221_type_0"
name="announcement_edit_collection[announcements][221][type]"
required="required" value="1">
<input type="checkbox" id="announcement_edit_collection_announcements_221_audience_0"
name="announcement_edit_collection[announcements][221][audience][]
"value="students">

how to add attribute to symfony form collectionType element

My form in php:
class MyType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('configFiles', CollectionType::class, array(
'entry_type' => TextareaType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'prototype' => true
))
}
...
}
My form in twig:
...
<div class="form-group">
{{ form_label(create_lab_form.configFiles) }}
<div class="configFiles" data-prototype="{{ form_widget(create_lab_form.configFiles.vars.prototype)|e('html_attr') }}">
</div>
{{ form_errors(create_lab_form.configFiles) }}
</div>
{% do create_lab_form.configFiles.setRendered %}
</div>
...
How to add attribute (e.g. "rows") for Textarea collection element in example above?
I tried something like this but it does not work:
->add('configFiles', CollectionType::class, array(
'entry_type' => TextareaType::class, array(
'attr' => array('rows' => 10
)),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'prototype' => true
))
Thank you in advance!
Everything is right but you are using the wrong key:
'entry_type' => TextareaType::class,
'entry_options' => array(
'attr' => array(
'rows' => 10
)),
should do the yob

Symfony Form passing variable options from Collection to FormType

i have a collection type:
->add('tipi', CollectionType::class, array(
'entry_type' => TipiType::class,
'allow_add' => true,
'prototype' => true,
'mapped' => false,
'entry_options' => array(
'required' => true,
'label' => false,
)
))
Extend this formtype:
->add('tipi', EntityType::class, array(
'label' => 'Tipo',
'class' => 'AppBundle:Tipi',
'attr' => array('class' => 'form-control'),
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('t')
->innerJoin('t.requests', 'r')
;
},
));
In the first form type i have an options sended from controller in this way:
$idRequest = $request->get('id');
$form = $this->createForm(RequestsType::class, $requests, array(
'id_request' => $idRequest
));
In the first I can use it, but in the child FormType not. I would passing this variable in the collection type. How can I do that?
$form = $this->createForm(new YourForm($options), $class);

Split form field of entity property into several subfields with FormBuilder

I have one superclass which gets extended by two entities. The superclass has a N:M relation with another entity. In the formbuilder of the latter, I need to separate the two subtypes into excluding separate fields.
This is its FormType::buildForm method:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('options_subtype_1', 'entity', [
'class' => 'AcmeExampleBundle:Options',
'expanded' => true,
'multiple' => true,
'property_path'=> 'options',
'query_builder' => /* specific filter 1 */
])
->add('options_subtype_2', 'entity', [
'class' => 'AcmeExampleBundle:Options',
'expanded' => true,
'multiple' => true,
'property_path'=> 'options',
'query_builder' => /* specific filter 2 */
])
;
}
However, no options are saved on form submission, except when I comment one of the two fields above (the one left is saved). I imagine setting property_path to the same property from two fields on the same form does not work.
How can I achieve this?
I'm still searching for the perfect solution by myself. For now I handle this kind of issues with a mapped hidden field and a PRE_SUBMIT Form Event. This could look like
FormType::buildForm
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('options_subtype_1', 'entity', [
'class' => 'AcmeExampleBundle:Options',
'expanded' => true,
'multiple' => true,
'mapped'=> false,
'data' => $builder->getData()->getOptions(),
'query_builder' => /* specific filter 1 */
])
->add('options_subtype_2', 'entity', [
'class' => 'AcmeExampleBundle:Options',
'expanded' => true,
'multiple' => true,
'mapped' => false,
'data' => $builder->getData()->getOptions(),
'query_builder' => /* specific filter 2 */
])
->add('options', 'entity', [
'class' => 'AcmeExampleBundle:Options',
'required' => false,
'multiple' => true,
'attr' => ['style' => 'visibility: hidden;'],
'label' => false
]);
$builder->addEventListener(
FormEvents::PRE_SUBMIT,
function (FormEvent $event) {
$data = $event->getData();
unset($data['options']);
$data['options'] = array_merge($data['options_subtype_1'], $data['options_subtype_2']);
$event->setData($data);
}
);
}

Categories