Multiple Symfony forms on one page - symfony

is it possible have 3 or more forms on the same page with same class in ez publish 5 ?
when i put 3 form like this
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
render only first form not others.
and the second question , i want use one class for multiple forms in ez publish, is it possible ?
any link or suggest would be helpful for me

You can use form in form.
Example Form 1:
class MyRegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('firstname', TextType::class, array(
'label_attr' => ['style' => 'display:none'],
'attr' => ['placeholder' => 'form.profile.firstname']
));
}
}
Example Form 2:
class RegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Add Self Form
$builder
->add('email', EmailType::class, array(
'attr' => ['placeholder' => 'form.email'],
'label_attr' => ['style' => 'display:none'],
'translation_domain' => 'FOSUserBundle',
));
// Include First Form
$builder->add('Profile', MyRegistrationType::class, array(
'mapped' => true,
'label' => false,
'required' => true
));
}
}
Using Form in Controller:
// Create Form
$form = $this->createForm(RegistrationType::class);
Render Twig:
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}

Related

how can I not display a part of my form in symfony?

I have to show or not a part of my form depending on the value that a variable assumes in my database.
Here is my form:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('assetClass',ChoiceType::class, array(
'placeholder' => 'Select asset class',
'choices' => array(
'a' => '1',
'b' => '2',
'c' => '3'
)))
->add('code')
->add('name')
->add('note',TextareaType::class,array('required' => false))
->add('route', HiddenType::class);
}
I need to show or not the ChoiceType.
Any idea for doing that?
In twig :
{{ form_start(form, {'method': 'POST'}) }}
{% if condition %}
{{ form_widget(form.assetClass) }}
{% endif %}
{{ form_widget(form.code) }}
{{ form_widget(form.name) }}
{{ form_widget(form.note) }}
{{ form_widget(form.route) }}
{{ form_widget(form._token) }}
{{ form_end(form, {'render_rest': false}) }}
With {'render_rest': false}, you don't render the rest of your form.
If you do that, dont forget to render the CSRF token.
Let us know.
You can use the form events, i feel like this page can help you : https://symfony.com/doc/4.4/form/dynamic_form_modification.html
Something like that:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$test = $event->getData();
$form = $event->getForm();
if (your condition) {
$form->add('assetClass',ChoiceType::class, array(
'placeholder' => 'Select asset class',
'choices' => array(
'a' => '1',
'b' => '2',
'c' => '3'
)))
}
}
$builder
->add('code')
->add('name')
->add('note',TextareaType::class,array('required' => false))
->add('route', HiddenType::class);
}
I guess you can then loop threw your form fields in twig to display them but i haven't figured that part for now, working on it

Symfony2, call part of a form in an Ajax query

I have a form in Symfony.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('volume', IntegerType::class, array())
;
$builder->add('product', ChoiceType::class, array(
'data' => '1',
'mapped' => false,
'choices' => array(
'1' => 'One',
'2' => 'Two',
),
)
);
$builder->add('deliveryType', ChoiceType::class, array(
'expanded' => true,
'data' => 1,
'choices' => array(
Command::STANDARD_DELIVERY => 'Standard',
Command::EXPRESS_DELIVERY => 'Express',
),
));
}
But the field deliveryType is loaded in another template called with an ajax request.
But of corse I have this error:
Variable "form" does not exist in ... at line 26
How can I put a part of a form in another template?
Here is my main template:
<div class="panel-body">
{{ form_start(form)}}
{{ form_errors(form) }}
<div class="row">
<div class="col-sm-12">
{{ form_row(form.product) }}
{{ form_row(form.volume, {'attr': {'class': 'form-control'}}) }}
{{ form_row(form.town) }}
</div>
</div>
<div id="content-delivery-range"><!-- Block loaded by ajax --></div>
<br>
<button type="submit" class="btn btn-primary btn-block">Continuer </button>
{{ form_end(form) }}
</div>
And now my template called with an Ajax request:
{{ deliveryRange|first|date('d M') }}
{{ deliveryRange|last|date('d M') }}
{% for d in deliveryRange %}
{{ d|date('l') }} <br>
<small>{{ d|intl_date('d') }} {{ d|date('M') }}</small>
{% endfor %}
{{ form_row(form.deliveryType) }}
It might be easier to include the "deliveryType" form element as part of the initial form render.
Then, your ajax call could just return the necessary values which you insert using jquery/javascript/etc.
Found it:
I have used an event listener with PRE_SUBMIT:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('volume', IntegerType::class, array())
;
$builder->add('product', ChoiceType::class, array(
'data' => '1',
'mapped' => false,
'choices' => array(
'1' => 'One',
'2' => 'Two',
),
)
);
$builder->addEventListener(FormEvents::PRE_SUBMIT, array($this, 'onPreSubmit'));
}
public function onPreSubmit(FormEvent $event)
{
$form = $event->getForm();
$form->add('deliveryType', ChoiceType::class, array(
'expanded' => true,
'data' => Command::STANDARD_DELIVERY,
'choices' => array(
Command::STANDARD_DELIVERY => 'Standard',
Command::EXPRESS_DELIVERY => 'Express',
),
));
}

Sonata Admin date choice wrapping

I'm (obviously) new to Symfony/Sonata, I have a problem where Sonata admin is wrapping my date choice onto 3 lines.
php:
$form = $this->createFormBuilder($statsForm)
->add('startDate', 'date', array('years' => range(2015, date('Y')), 'format' => 'y-M-d', 'widget' => 'choice'))
->add('endDate', 'date', array('years' => range(2015, date('Y')), 'format' => 'y-M-d', 'widget' => 'choice'))
->getForm();
twig:
{{ form_start(form) }}
<div class="col-md-3">
{{ form_widget(form) }}
</div>
{{ form_end(form) }}
screen:
In your case you have to choose the sonata_type_date_picker type in your form:
$datagridMapper
->add('startDate', 'sonata_type_date_picker')
->add('endDate', 'sonata_type_date_picker')
;
The documentation reference:
https://sonata-project.org/bundles/core/master/doc/reference/form_types.html

Symfony2 Form with multiple collection

I'm trying to integrate two collections into one form.
this is my code:
FormType.php
$builder
->add('Depart', 'collection', array('type' => new DepartType(), 'allow_add' => true, 'allow_delete' => true))
->add('Options', 'collection', array('type' => new OptionsType(), 'allow_add' => true, 'allow_delete' => true))
;
View.twig
{{ form(form.Options) }}
{{ form(form.Depart) }}
But, when I post the form, only the first collection: options is sent to the control.
View.twig
{{ form(form.Depart) }}
{{ form(form.Options) }}
if I change the order as above, the collection:Depart is sent, how to resolve the problem?
Thanks
Hope it will work for you:
{{ form_start(form) }}
{{ form_row(form.Depart) }}
{{ form_row(form.Options) }}
{{ form_end(form) }}

FOSUserBundle : Overriding a Twig template : adding HTML elements

I'm using FOSUserBundle, and I want to add a few HTML elements to the registration form. Actually, I did and I can see the added properties to the User class in my form. The issue is that I want those fields (first name, last name, date of birth, etc..) to get the look and feel of my CSS template (bootstrap).
I succeeded to do that for the login page by overriding it, since the HTML are explicitly declared. I want to do the same for the register page, however it seems confused to me, because here's the content of :
register.html.twig
{% extends "FOSUserBundle::layout.html.twig" %}
{% block fos_user_content %}
{% include "FOSUserBundle:Registration:register_content.html.twig" %}
{% endblock fos_user_content %}
register_content.html.twig
{% trans_default_domain 'FOSUserBundle' %}
{{ form_widget(form) }}
How can I access to the elements that I see in the page from this code ?
Try this
<div class="form-group {% if form.plainPassword.first.vars.errors %}has-error{% endif %}">
<label class="col-lg-2 control-label">Password:</label>
<div class="col-lg-5">
{{ form_widget(form.plainPassword.first, {'attr': {'class': 'form-control input-lg', 'placeholder': 'Enter password', 'required': 'required'}}) }}
{% for errorItem in form.plainPassword.first.vars.errors %}
<label class="control-label has-error" for="{{ form.plainPassword.vars.id }}">{{ errorItem.message }}</label>
{% endfor %}
</div>
<div class="col-lg-5">
{{ form_widget(form.plainPassword.second, {'attr': {'class': 'form-control input-lg', 'placeholder': 'Enter password again', 'required': 'required'}}) }}
</div>
</div>
It works for me.
Please see the official documentation here: "Overriding Forms". You will need to create a custom registration form type class, declare it as a service, and tell FOSUserBundle to use it.
To customize the template, see "Overriding Templates". In your case, you could create app/Resources/FOSUserBundle/views/Registration/register.html.twig.
replace form_widget(form) with something like:
form_widget(form.username)
form_widget(form.email)
form_widget(form.plainPassword)
form_widget(form.myField)
form_rest(form)
in your custom RegistrationFormType class, you could add a class to the username field with:
$builder
->add('username', null, array('label' => 'form.username', 'translation_domain' => 'FOSUserBundle', 'attr' => array('class'=>'myClass')))
also see form docs on rendering fields by hand: http://symfony.com/doc/current/book/forms.html#rendering-a-form-in-a-template
Here is how I addressed this problem using FOSUserBundle, PUGXMultiUserBundle & BraincraftedBoostrapBundle:
Per FOSUserBundle documentation, add a UserBundle as a child of FOSUser. Create a custom RegistrationFormType that includes the following, where only the attr and label_attr arrays are added:
$builder
->add('email', 'email', array(
'label' => 'form.email',
'translation_domain' => 'FOSUserBundle',
'attr' => array(
'placeholder' => 'E-mail',
),
'label_attr' => array(
'class' => 'sr-only',
)))
->add('username', null, array(
'label' => 'form.username',
'translation_domain' => 'FOSUserBundle',
'attr' => array(
'placeholder' => 'Username',
),
'label_attr' => array(
'class' => 'sr-only',
)))
->add('plainPassword', 'repeated', array(
'type' => 'password',
'options' => array('translation_domain' => 'FOSUserBundle'),
'first_options' => array('label' => 'form.password',
'attr' => array(
'placeholder' => 'Password',
),
'label_attr' => array(
'class' => 'sr-only',
)),
'second_options' => array('label' => 'form.password_confirmation',
'attr' => array(
'placeholder' => 'Confirm password',
),
'label_attr' => array(
'class' => 'sr-only',
)),
'invalid_message' => 'fos_user.password.mismatch',
))
;
The registration form template then looks like this:
<form action="{{ path('volunteer_registration') }}" method="POST" class="form-inline">
{{ bootstrap_set_style('form-inline') }}
{{ form_row(form.firstName) }}
{{ form_row(form.lastName) }}
{{ form_row(form.username) }}
{{ form_row(form.email) }}
<br/>
{{ form_row(form.plainPassword) }}
{{ form_row(form.plainPassword.second) }}
{{ bootstrap_set_style('') }}

Resources