form_errors does not display anything - symfony

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

Related

Removing a label from a Symfony form

I'm using a Symfony form and I am trying to either remove the label that has appeared or change it to a line of text which accepts spaces. The label in this case is Response a, which is the name of the form.
Entity:
protected $responseA;
public function getResponseA()
{
return $this->responseA;
}
public function setResponseA($responseA)
{
$this->task = $responseA;
}
Controller for the form:
$responseA = new Applicant();
$responseA->setResponseA('');
$form = $this->createFormBuilder($responseA)
->add('responseA', ChoiceType::class, array(
'choices' => array(
'Very Acceptable' => '1',
'Acceptable' => '2',
'Inappropriate' => '3',
'Very Inappropriate' => '4'
),
))
->add('save', SubmitType::class, array('label' => 'Create Post'))
->getForm();
What I would like to remove or change:
Set 'label' value to false will suppress the label display.
$responseA = new Applicant();
$responseA->setResponseA('');
$form = $this->createFormBuilder($responseA)
->add('responseA', ChoiceType::class, array(
'choices' => array(
'Very Acceptable' => '1',
'Acceptable' => '2',
'Inappropriate' => '3',
'Very Inappropriate' => '4'
),
'label' => false,
))
->add('save', SubmitType::class, array('label' => 'Create Post'))
->getForm();
You can also do it in the template by ommiting the form_label for some fields:
{{ form_start(form) }}
{{ form_errors(form.responseA) }}
{{ form_widget(form.responseA) }}
{{ form_widget(form.save) }}
{{ form_end(form) }}

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',
),
));
}

email collection (from book), submit buttons collection

I have a problem with collection from symfony documentation. Here is my code:
controller:
$emails = array("first#qwe.com", "second#qwe.com", "third#qwe.com");
$myDForm = $this->createFormBuilder($emails)
->add('emails', 'collection', array('type' => 'email', 'options' => array('required' => false, 'attr' => array('class' => 'email-box')),))
->GetForm();
$myDForm->handleRequest($request);
twig:
{{ form_start(myDForm) }}
{{ form_end(myDForm) }}
As you can see the code looks easy, there are no errors just an empty page...
Could somebody point me where is the problem? I'm a beginner but it's almost exact as code in doc.
I'd like to make several submit buttons on a form this way but I stuck with this.
Thank you.
First:
Change
GetForm
to
getForm
$emails = array("first#qwe.com", "second#qwe.com", "third#qwe.com");
$myDForm = $this->createFormBuilder($emails)
->add(
'emails',
'collection',
array(
'type' => 'email',
'options' => array('required' => false, 'attr' => array('class' => 'email-box')),)
)->getForm();
$myDForm->handleRequest($request);
I don't know what is your point to use emails with collection.
Second:
You are just opening your form. You are not giving any field to print.
{{ form_start(myDForm) }}
{{ form_row(form.emails) }}
{{ form_end(myDForm) }}
http://symfony.com/doc/current/reference/forms/twig_reference.html

Symfony2 form isclicked doesn't work

I'm trying to submit a form with 2 buttons but the method isclicked doesn't work...
$user = $repository->find($id);
$formBuilder = $this->createFormBuilder($user);
$form = $formBuilder->add('username', 'text',array(
'label' => "Pseudo :"))
->add('email', 'text', array(
'label' => "E-mail address :"))
->add('save', 'submit',array(
'label' => 'Save',
'attr' => array( 'class' => 'btn btn-primary')))
->add('reset', 'submit',array(
'label' => 'Reset pwd',
'attr' => array( 'class' => 'btn btn-primary')))
->getForm();
$request = $this->get('request');
if($request->getMethod() == 'POST'){
$value = $form->get('save')->isClicked() ?'save' :'reset';
echo $value;
Below my twig:
<section>
{{ form_start(form) }}
{{form_errors(form) }}
<div class='form_group'>
{{form_row(form.username)}}
{{form_row(form.email)}}
<br>
<div class='testbutton'>
{{form_row(form.save)}}
{{form_row(form.reset)}}
</div>
{{ form_end(form) }}
</div>
</section>
But it doesn't matter which button I pressed this code will always display "reset"...
What is wrong? :/
Thank you in advance !
First thing I noticed that you didn't handleRequest:
$request = $this->get('request');
if($request->getMethod() == 'POST'){
$form->handleRequest($request); // <== THIS
$value = $form->get('save')->isClicked() ?'save' :'reset';
echo $value;
Hope this helps...

Symfony Form, CSRF token missing

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>

Resources