Anchor error on form - Symfony3/Materialize - forms

Using Symfony 3.2 && PhpStorm.2016.3.2 on Ubuntu 16.04
I have a problem that I partially resolved on the phone number field in this twig form.
I use materialize as the framework css for this project and I use the form of this framework.
I would like to be able to anchor the view directly on the form after an error has been spotted. So far it works great with the phone number section but anyone else doesn't work. I tried to tweak my code as much as I can but still I cannot anchor my view on other fields that get an error. It is pretty much frustrating.
here is the form twig in the view
<form class="col m12" method="POST">
{{ form_start(form) }}
<div class="row" id="radio-button-block">
<div class="col m12">
{{ form_row(form.baptismChoice) }}
</div>
</div>
<div class="row">
<div class="input-field col s6 validate" id="last_name" type="text">
{% if form.vars.errors|length %}
{{ form_row(
form.lastName,
form.lastName.vars|merge({'attr': {'autofocus': null}})
)
}}
{% else %}
{{ form_row(form.lastName) }}
{% endif %}
</div>
<div class="input-field col s6 validate" id="first_name" type="text">
{% if form.vars.errors|length %}
{{ form_row(
form.firstName,
form.firstName.vars|merge({'attr': {'autofocus': null}})
)
}}
{% else %}
{{ form_row(form.firstName) }}
{% endif %}
</div>
</div>
<div class="row">
<div class="input-field col s12 validate" id="email" type="email">
{{ form_row(form.authorEmail) }}
</div>
</div>
<div class="row">
<div class="input-field col s12 validate" id="icon_telephone" type="tel">
{{ form_errors(form) }}
{% if form.vars.errors|length %}
{{ form_row(
form.authorPhone,
form.authorPhone.vars|merge({'attr': {'autofocus': null}})
)
}}
{% else %}
{{ form_row(form.authorPhone) }}
{% endif %}
</div>
</div>
<div class="row">
<div class="input-field col s12 validate" id="city" type="text">
{{ form_row(form.city) }}
</div>
</div>
<div class="row" id="comment-block">
<div class="input-field col s12">
<div id="textarea">
{{ form_row(form.comment) }}
</div>
</div>
</div>
<div class="row">
<div class="input-field col s12 center-align">
{{ form_row(form.submit) }}
</div>
</div>
{{ form_end(form) }}
</form>
and here the Form builder in FomrType.php
->add('firstName', TextType::class, array(
'label' => 'Prénom',
'required' => true,
'attr' => array(
'class' => 'validate',
'id' => 'first_name',
),
'constraints' => array(new Regex(
array(
'pattern' => "#^[a-zéèàêâùïüë' -]{2,}$#i",
'message' => 'Oops ! Ce champ n\'est pas bon.'
)
)),
))
->add('lastName', TextType::class, array('constraints' => new Regex("#^[a-zéèàêâùïüë' -]{2,}$#i"),
'label' => 'Nom',
'required' => true,
'attr' => array(
'class' => 'validate',
'id' => 'last_name',
),
))
->add('authorEmail', EmailType::class, array('label' => 'Adresse mail',
'required' => true,
'attr' => array(
'class' => 'validate',
'if' => 'email'
),
))
->add('authorPhone', TextType::class, array(
'label' => 'Numéro de téléphone',
'required' => true,
'error_bubbling' => true,
'attr' => array(
'class' => 'validate',
'id' => 'icon_telephone'
),
'constraints' => array(new Regex(
array(
'pattern' => '#^0[1-9]([-. ]?[0-9]{2}){4}$#',
'message' => 'Oops ! Ce champ n\'est pas bon.'
)
)),
))
does anyone have an idea?

You're checking if the whole form has the errors set {% if form.vars.errors|length %}, but you should check if the specific field has an error {% if form.field_name.vars.errors|length %}.
In your present code, when an error occurs on any one of the fields, then autofocus is set on all of your fields and browser sets and scrolls to the first one.

Related

Form symfony multiple choice

I have a classic form in Symfony and there is one input with 4 different values, I would like to render those 4 values in my twig instead of a drop-down box.
I tried to do it with a loop but I can't do it for an array.
Here is my code :
$isAdmin = !empty($this->getSap()->fetchSapQuery('RECAP_AUTHORITY_ADM', []));
$flux = $this->getSap()->fetchSapQuery('RECAP_FLUX_LIST', []);
$form = $this->createFormBuilder()
->add('Secteur', ChoiceType::class, array(
'choices' => $this->getSap()->fetchSapQuery('RECAP_SECTEUR_LIST', []),
'label' => $this->trans('Secteur'),
'choice_label' => 'LibLong',
'choice_value' => 'SecteurId',
'required' => true,
'placeholder' => '',
'attr' => [
//'data-app-auto-select-unique-option' => 1,
'multiple' => 'multiple', // secteur monoselection
],
))
Here is my Twig :
{% block body %}
<div class="row">
<div class="col-sm-12">
<div class="card-box ">
<h2 class="m-t-0 header-title">{{ pageTitle }}</h2>
<form id="searchForm" class="form-horizontal search-form " role="form" action="{{
path('api_post', {id: odata_search}) }}" method="post">
{#{{ dump(form.Secteur) }}#}
{{ form_row(form.Secteur) }}
{{ form_row(form.Flux) }}
{{ form_row(form.Canal) }}
{{ form_row(form.Periode) }}
{{ form_row(form.CodeExterne) }}
{{ form_row(form.EQART) }}
{{ form_row(form.Division) }}
{{ form_row(form.Username) }}
<div class="form-group">
<div class="col-md-offset-3 col-md-4">
<button id="search" type="submit" class="btn btn-success" data-notification-
clear="true">{{ "Rechercher"|trans }}</button>
{% if isAdmin %}
<button id="btnNew" type="button" class="btn btn-success" disabled><i
class="fa fa-plus-circle"></i> {{ "Creer un rapport vierge"|trans }}
</button>
{% endif %}
</div>

Symfony - Form is not submit

I work with Symfony to build and send a contact form by mail.
I use swiftMailer.
The problem is that my form is not submitted.
So, my swiftmailer can't work because the isSumbitted will stay at false and $mailer->send(message) will not be activate
My controller :
public function index (Request $request, Swift_Mailer $mailer)
{
$form = $this->createForm(ContactType::class);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
$contactData = $form->getData();
$name = $contactData['name'];
$content = $contactData['message'];
$email = $contactData['email'];
$entreprise = $contactData['entreprise'];
$zip = $contactData['zip'];
$message = (new Swift_Message('Vous avez un nouveau message sur le site AMC Industrie.fr'))
->setFrom('test#example.com')
->setTo('test#gmail.com')
->setSubject('Demande d\'information')
->setCharset('utf-8')
->setContentType('text/html')
->setBody(
"
<p> Vous avez reçu un message de <strong>$name</strong>, de l'entreprise <strong>$entreprise</strong>
<br>(code postal : $zip ) <br>
Son email est : <strong>$email</strong>. </p>
<p> Son message :</p>
<p>$content
</p>
"
)
;
$mailer->send($message);
return $this->redirectToRoute('map_contact');
}
return $this->render('contact/map_contact.html.twig', [
'form' => $form->createView()
]);
}
My Form :
{
$builder
->add('name',TextType::class,
['label'=>false,
'constraints' => new NotBlank,
'attr' => [
'class'=> 'form-control',
'placeholder' => 'Nom et prénom',
]
])
->add('email',EmailType::class,
['label'=>false,
'constraints' => new NotBlank,
'attr' => [
'class' => 'form-control',
'placeholder' => 'adresse e-mail'
]
])
->add('entreprise',TextType::class,
['label'=>false,
'constraints' => new NotBlank,
'attr' => [
'class'=> 'form-control',
'placeholder' => 'Nom de votre entreprise'
]
])
->add('zip',NumberType::class,
['label'=>false,
'constraints' => new NotBlank,
'attr' => [
'class'=> 'form-control',
'placeholder' => 'Code postal'
]
])
->add('message',TextareaType::class,
['label'=>false,
'constraints' => new NotBlank,
'attr' => [
'class'=> 'form-control',
'placeholder' => 'Décrivez-nous votre projet'
]
])
->add('save', SubmitType::class,
['label' => 'Envoyer',
'attr'=> [
//'class' => 'waves-effect waves-light btn-large btn btn-primary mt-1 mb-5 lift',
'id' => 'form-submit'
]])
;
}
My template :
<form>
{{ form_start(form) }}
<div class="row">
<div class="col-12 col-md-6">
<div class="form-group mb-5">
{{form_label(form.name, 'Nom et prénom')}}
{{form_widget(form.name)}}
</div>
</div>
<div class="col-12 col-md-6">
<div class="form-group mb-5">
{{form_label(form.email, 'Email') }}
{{form_widget(form.email)}}
</div>
<div class="col-12 col-md-6">
<div class="form-group mb-5">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12 col-md-6">
<div class="form-group mb-5">
{{form_label(form.entreprise, 'Entreprise')}}
{{form_widget(form.entreprise)}}
</div>
</div>
<div class="col-12 col-md-6">
<div class="form-group mb-5">
{{form_label(form.zip, 'Code Postal')}}
{{form_widget(form.zip)}}
</div>
<div class="col-12 col-md-6">
<div class="form-group mb-5">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="form-group">
{{form_label(form.message, 'Comment pouvons-nous vous aider ?')}}
{{form_widget(form.message)}}
</div>
</div>
</div> <!-- / .row -->
<div class="row justify-content-center">
<div class="col-auto py-5">
<!-- Submit -->
<div>
{{form_widget(form.save)}}
</div>
</div>
</div>
{{ form_end(form) }}
</form>
My debug tool :
Form in get parameter OK. I have all my input with informations.
Debug tool - get parameters:
BUT
there is not sumbitted data. form is not submit
debug tool - form is not submit:
I don't understand where is my problem.
Ok, it's resolved !
The problem : I already have a html balise for my form, in my template.
When I delete , it's ok !

How to add wrapper around multiple checkbox on Symfony 4 form

I have a list of checkbox created in a form with the following
->add('ISPreNbStudents', ChoiceType::class, [
'multiple' => false,
'choices' => [
'1' => 1,
'2' => 2,
'3' => 3,
'4' => 4,
'5' => 5,
],
'expanded' => true
])
I can then display this in the twig file with this : {{ form_widget(form.ISOptMonths) }}
The problem is that it now display a list of label and input like this
<input type="radio" id="availability_ISPreNbStudents_0" name="availability[ISPreNbStudents]" value="1">
<label for="availability_ISPreNbStudents_0">1</label>
<input type="radio" id="availability_ISPreNbStudents_1" name="availability[ISPreNbStudents]" value="2">
<label for="availability_ISPreNbStudents_1">2</label>
I need to put wrapper around each label/input like this
<div class="styled-input-single">
<input type="checkbox" name="case-1" id="1" />
<label for="1">1</label>
</div>
<div class="styled-input-single">
<input type="checkbox" name="case-2" id="2" />
<label for="2">2</label>
</div>
How can I achieve this ?
I've finally found the solution :
Here is how you print your list :
{{ form_row(registrationForm.firstRecourse) }}
Now is you want to add wrapper around every option :
<div class="row">
{{ form_label(registrationForm.ISPreNbStudents) }}
{% for checkbox in registrationForm.ISPreNbStudents.children %}
<div class="styled-input-single">
{{ form_widget(checkbox) }}
{{ form_label(checkbox) }}
{{ form_errors(checkbox) }}
</div>
{% endfor %}
</div>
You have to use Symfony Customize Form Rendering.
This way you can access your form field by field, like:
{{ form_start(form) }}
<div class="my-custom-class-for-errors">
{{ form_errors(form) }}
</div>
<div class="row">
<div class="col">
{{ form_row(form.task) }}
</div>
<div class="col" id="some-custom-id">
{{ form_row(form.dueDate) }}
</div>
</div>
{{ form_end(form) }}
You are able to render the fields manually also:
<div class="styled-input-single">
{{ form_widget(form.name_of_form_element) }}
{{ form_label(form.name_of_form_element) }}
<!-- and for errors of this field -->
{{ form_errors(form.name_of_form_element) }}
</div>
For rendering a select or option box manually check this link:
https://symfonycasts.com

How to change label position in a customized twig form theme

I try to override a symfony form theme. It works, that's the good news!
But I'd like to change the position of the label inside.
My form Builder:
$builder->add('phone', IntegerType::class, [
'label' => 'Telefonnummer',
'constraints' => [
new NotBlank(),
],
'attr' => [
'class' => 'input-field__input',
],
'label_attr' => [
'class' => 'input-field__label',
]
]);
My overridden integer_widget:
{% block integer_widget %}
<div class="input-field">
{% set type = type|default('number') %}
{{ block('form_widget_simple') }}
</div>
{% endblock %}
What I expected (shortened example):
<div class="input-field">
<label>Telefonnummer</label>
<input/>
</div>
What I got:
<label>Telefonnummer</label>
<div class="input-field">
<input/>
</div>
The label comes before the div and isn't inside. But I need it inside!
What i tried (works but in my opinion it is a mess):
{% block integer_widget %}
<div class="input-field">
{% block form_label %}
{% endblock %}
<label class="{{ label_attr.class }}">{{ label }}</label>
{% set type = type|default('number') %}
{{ block('form_widget_simple') }}
</div>
{% endblock %}
This way it looks like I expected. But it's just a workaround because i deleted the origin label by adding an empty 'form_label' block.
Is there a better solution to do this within the rules of symfony/twig?
If all you want is this :
<div class="input-field">
<label for="_input-a">Telefonnummer</label>
<input id="_input-a" name="_name" value="_value">
</div>
Then there is no need to bother yourself with a custom integer_widget
Doing this instead is enough :
<div class="input-field">
{{ form_label(form.phone) }}
{{ form_widget(form.phone) }}
</div>
It will render what you want.

This form should not contain extra fields. on multile submite button

I have a two part form in symfony2 of a single table db.
On my edit page i display whole form with two save buttons.
when i edit some field and try to save it that shows the extra field error
my controller code is
$form = $this->createForm(new PatientfullType(), $test, array());
$formadd = $this->createForm(new PatientfulladdType(), $test, array());
.
.
if ($form->get('save')->isClicked()) {
return $this->render('AdminBundle:FormsController:patientformfull.html.twig', array('formadd' => $formadd->createView(),'form' => $form->createView() ));
// probably redirect to the add page again
}
else
{
return $this->render('AdminBundle:FormsController:patientformfull.html.twig', array('formadd' => $formadd->createView(),'form' => $form->createView() ));
}
my twig file has two object
form and formadd
<div class="row" style="margin-bottom: 15px;">
<div class="col-xs-3">
{{ form_label(form.sex) }}
</div>
<div class="col-xs-9 col-sm-4 col-md-3">
{{ form_widget(form.sex, {'attr': {'class': 'form-control'}}) }}
</div>
</div>
<div class="row" style="margin-bottom: 15px;">
<div class="col-xs-3">
{{ form_label(formadd.ChronicDiseases) }}
</div>
<div class="col-xs-9 col-sm-4 col-md-3">
{{ form_widget(formadd.ChronicDiseases, {'attr': {'class': 'form-control'}}) }}
</div>
</div>
</div><div class="col-xs-9 col-sm-5">
{{ form_widget(form.save , {'attr': {'class': 'btn btn-success'}}) }}
{{ form_widget(form.cancel , {'attr': {'onclick': 'cancelRedirect()','class': 'btn btn-default'}}) }}
</div>
</div><div class="col-xs-9 col-sm-5">
{{ form_widget(formadd.save1 , {'attr': {'class': 'btn btn-success'}}) }}
</div>