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',
),
));
}
Related
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
I'm having a hard time displaying errors from forms validation. Nothing is displayed when I fill the form incorrectly.
Here is my controller :
public function Register(Request $request){
$user = new User();
// Accounts must be enabled manually
$authenticator = new GoogleAuthenticator();
$user->setEnabled(false);
$user->setAdmin(false);
$user->setSecret($authenticator->createSecret());
$form = $this->createFormBuilder($user)
->add('email', TextType::class)
->add('email', RepeatedType::class)
->add('password', PasswordType::class)
->add('password', RepeatedType::class)
->add('phone', TelType::class)
->add('secret', HiddenType::class)
->add('save', SubmitType::class, array('label' => 'Register'))
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// $form->getData() holds the submitted values
// but, the original `$task` variable has also been updated
$user = $form->getData();
// ... perform some action, such as saving the task to the database
// for example, if Task is a Doctrine entity, save it!
// $entityManager = $this->getDoctrine()->getManager();
// $entityManager->persist($task);
// $entityManager->flush();
return $this->redirectToRoute('register_success');
}
return $this->render('register.html.twig', array(
'form' => $form->createView()
));
}
And my template
{{ form_start(form) }}
{{ form_errors(form) }}
<div>
{{ form_errors(form.email) }}
{{ form_label(form.email) }} :
{{ form_widget(form.email.first, { 'attr' : {'placeholder' : 'Email address'}})}}
{{ form_widget(form.email.second, { 'attr' : {'placeholder' : 'Email address (again)'}})}}
</div>
<div>
{{ form_errors(form.password) }}
{{ form_label(form.password) }} :
{{ form_widget(form.password.first, { 'attr' : {'placeholder' : 'Password'}})}}
{{ form_widget(form.password.second, { 'attr' : {'placeholder' : 'Password (again)'}})}}
</div>
<div>
{{ form_errors(form.phone) }}
{{ form_label(form.phone) }} :
{{ form_widget(form.phone, { 'attr' : {'placeholder' : 'International format (+33)'}}) }}
</div>
<div>
{{ form_widget(form.save) }}
</div>
{{ form_end(form) }}
The forms reload with data pre-filled but no errors are displayed (empty line in source code only)
Waiting for your hints
Thanks
One need to setup validators (and therefore error messages) for them to be displayed.
Thanks for your help.
First of all, you do not need to "repeat" your already defined as RepeatedType fields, email and password.
Change to:
$form = $this->createFormBuilder($user)
->add('email', RepeatedType::class, array(
'type' => TextType::class,
'invalid_message' => 'The email fields must match.',
'options' => array('attr' => array('class' => 'email-field')),
'required' => true,
'first_options' => array('label' => 'Email'),
'second_options' => array('label' => 'Repeat Email'),
))
->add('password', RepeatedType::class, array(
'type' => PasswordType::class,
'invalid_message' => 'The password fields must match.',
'options' => array('attr' => array('class' => 'password-field')),
'required' => true,
'first_options' => array('label' => 'Password'),
'second_options' => array('label' => 'Repeat Password'),
));
To display the errors, use:
{{ form_errors(form.email.first)}}
{{ form_errors(form.email.second)}}
{{ form_errors(form.password.first)}}
{{ form_errors(form.password.second)}}
References
Symfony 4 RepeatedType field documentation
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) }}
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
Like in the topic, i have problem with CSRF token missing. This is my form:
$builder
->add('email', 'email', array(
'label' => 'Adres e-mail'
))
->add('userFirstname', 'text', array(
'label' => 'Imię',
'required' => false
))
->add('userLastname', 'text', array(
'label' => 'Nazwisko',
'required' => false
))
->add('userBusiness', 'entity', array(
'label' => 'Firma',
'required' => false,
'class' => 'Cloud\CrmBundle\Entity\RelationContact',
'query_builder' => function(EntityRepository $er) {
return $er->createQueryBuilder('u')->where("u.type = 'b'");
},
'empty_value' => true
))
->add('old_password', 'password', array(
'label' => 'Stare hasło',
'mapped' => false,
'required' => false
))
->add('new_password', 'repeated', array(
'first_options' => array(
'label' => 'Nowe hasło'),
'second_options' => array(
'label' => 'Powtórz nowe hasło'),
'mapped' => false,
'required' => false,
'type' => 'password'
));
My view:
<div class="form-horizontal">
{{ form_row(form.email) }}
{{ form_row(form.userFirstname) }}
{{ form_row(form.userLastname) }}
{{ form_row(form.userBusiness) }}
{{ form_row(form.old_password) }}
{{ form_row(form.new_password) }}
</div>
</div>
What's wrong guys? Any ideas? :( I just don't understand this strange error... What could cause that ?
Probably you've to add this _token by hand because you're trying to display form manually:
{{ form_widget(form._token) }}
Symfony2 set a hidden field with the required informations. For this you have to include the hidden fields with:
{{ form_widget(form._token) }}
if you don't want the CSRF-Protection then you can disable the dunction in your parameters file.
Disable symfony 2 csrf token protection on ajax submit
If you use form_start and form_end symfony will add the token field to the form automatically
<div class="form-horizontal">
{{ form_start(form) }}
{{ form_row(form.email) }}
{{ form_row(form.userFirstname) }}
{{ form_row(form.userLastname) }}
{{ form_row(form.userBusiness) }}
{{ form_row(form.old_password) }}
{{ form_row(form.new_password) }}
{{ form_end(form) }}
</div>