Symfony2 form isclicked doesn't work - symfony

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...

Related

form_errors does not display anything

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

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

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>

Symfony2: setting the default option of a select

I have a form with a dropdown (select) and I would like to choose the option selected by default:
This is the code that generates the select:
$builder->add('language', 'choice', array(
'label' => 'pages.age.gateway.language.label',
'choices' => array(1 => 'first option', 2 => 'second option'),
));
I've tried the following (suggested here, Symfony2 Setting a default choice field selection):
$builder->add('language', 'choice', array(
'label' => 'pages.age.gateway.language.label',
'choices' => array(1 => 'first option', 2 => 'second option'),
'data' => '2'
));
this didn't work with my code (my understanding of symfony2, I might not be in the right direction).
Another alternative would be using 'preferred_choices' but I'd like to avoid this, as I wouldn't like to modify the order in which the options are displayed.
If your form depends of an entity:
/* Action */
public function myAction()
{
$user = new User();
$user->setLanguage(2); // Set the default option
$form = $this->createForm(new UserType(), $user); // Give the user to the form
if ($request->getMethod() == 'POST') {
$form->bindRequest($request);
if ($form->isValid()) {
$user = $form->getData();
// Do something like save / redirect
}
}
return array(
'form' => $form->createView(),
);
}
Also you can set a preferred choice (but not a true default value) thanks to preferred_choices key (it move up the value to the top of the select):
$builder->add('language', 'choice', array(
'label' => 'pages.age.gateway.language.label',
'choices' => array(1 => 'first option', 2 => 'second option'),
'preferred_choices' => 2
));
You want to add option without the value. You can do this with option empty_value.
$builder
->add('gender', 'choice', array(
'label' => 'Gender',
'choices' => array('male', 'female'),
'empty_value' => 'Please select option'
));

Resources