6
votes

I am debugging a form i have created in symfony3 with twig as template engine. For some reason if i use {{ form_errors(form) }} (which should return all errors of the form) i only get partial result (some errors are not shown in the message box).

The interesting part comes in when i look into symfony3 debug panel, i can see all those errors showing there: some are on the form level (those 6 i can see in my twig template) and some on the form level (those 2 i cannot see on the form level) enter image description here

My question is: how do i move phone and gender level errors from field level to form level (or vice versa) and how come some errors are shown at form level and some at field level.

This is my FormType

    <?php
namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;

class SubscriberType extends AbstractType {
    /**
     * @param FormBuilderInterface $builder
     * @param array                $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options) {

        $builder
            ->add('firstname', null, array(
                'label' => false,
                'required' => true,
                'attr' => array(
                    'placeholder' => 'First Name',
                    'class' => 'form-field-set'
                )))
            ->add('lastname', null, array(
                'label' => false,
                'required' => true,
                'attr' => array(
                    'placeholder' => 'Last Name',
                    'class' => 'form-field-set'
                )))
            ->add('emailaddress', EmailType::class, array(
                'label' => false,
                'required' => true,
                'attr' => array(
                    'placeholder' => 'Email Address',
                    'pattern'     => '.{2,}', //minlength
                    'class' => 'form-field-set'
                )))  
            ->add('phone', TextType::class, array(
                'label' => false,
                'required' => true,
                'attr' => array(
                    'placeholder' => 'Mobile Phone',
                    'pattern'     => '.{2,}', //minlength
                    'class' => 'form-field-set'
                )))
            ->add('gender', ChoiceType::class, array(
                'choices' => array('Male' => 1, 'Female' => 2, 'Refuce to answer' => 0),
                'label' => false,
                'required' => true,
                'placeholder' => 'Gender',
                'attr' => array(
                    'class' => 'form-field-set'
                )))
            ->add('agreeterms', CheckboxType::class, array(
                'label' => '',
                'required' => true))
            ->add('agreeemails', CheckboxType::class, array(
                'label' => '',
                'required' => true))
            ->add('agreepartners', CheckboxType::class, array(
                'label' => '',
                'required' => true))
            ->add('submit', SubmitType::class, array(
                'label' => 'Sign Up', 
                'attr' => array(
                    'class' => 'sub-btn'
                )))
             ;
    }

    /**
    * @param OptionsResolverInterface $resolver
    */
    public function configureOptions(OptionsResolver $resolver) {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Subscriber'
        ));
    }
    /**
     * @return string
     */
    public function getName() {
        return 'subscriber';
    }
}

and this is my Entity

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use DateTime;

/**
 * Subscriber
 *
 * @ORM\Entity(repositoryClass="AppBundle\Repository\SubscriberRepository")
 * @ORM\Table(name="MediaBay_Master", uniqueConstraints={@ORM\UniqueConstraint(name="subscriber_pkey", columns={"id"})})
 */
class Subscriber
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     * 
     * @Assert\NotBlank (message="Complete First Name field")
     * @ORM\Column(name="first_name", type="string", length=255, nullable=false)
     */
    private $firstName;

    /**
     * @var string
     * 
     * @Assert\NotBlank (message="Complete Last Name field")
     * @ORM\Column(name="last_name", type="string", length=50, nullable=false)
     */
    private $lastName;

    /**
     * @var string
     * 
     * @Assert\NotBlank (message="Complete Email Address field")
     * @ORM\Column(name="email_address", type="string", length=100, nullable=false)
     * @Assert\Email(
     *     message = "The email '{{ value }}' is not a valid email.",
     *     checkMX = true,
     *     checkHost = true
     * )
     */
    private $emailAddress;

    /**
     * @var string
     * 
     * @Assert\NotBlank (message="Complete Mobile Phone field")
     * @Assert\Length(min=5) (message="Phone lenght must be over 5 characters")
     * @ORM\Column(name="phone", type="string", length=50, nullable=false)
     */
    private $phone;

    /**
     * @var int
     * @Assert\GreaterThanOrEqual("18")
     * @ORM\Column(name="age", type="smallint", nullable=true)
     */
    private $age;

    /**
     * @var int
     *
     * @Assert\NotBlank (message="Complete Gender field")
     * @ORM\Column(name="gender", type="smallint", nullable=false)
     */
    private $gender;

    /**
     * @var int
     * @ORM\Column(name="education_level_id", type="smallint", nullable=true)
     */
    private $educationLevelId;

    /**
     * @var int
     *
     * @ORM\Column(name="resource_id", type="smallint")
     */
    private $resourceId;

    /**
     * @var bool
     * @Assert\NotBlank (message ="Please select this field")
     * @ORM\Column(name="agree_terms", type="boolean")
     */
    private $agreeTerms;

    /**
     * @var bool
     * @Assert\NotBlank (message ="please select this field")
     * @ORM\Column(name="agree_emails", type="boolean")
     */
    private $agreeEmails;

    /**
     * @var bool
     * @Assert\NotBlank (message ="please select this field")
     * @ORM\Column(name="agree_partners", type="boolean", nullable=true)
     */
    private $agreePartners;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="subscription_date", type="datetime")
     */
    private $subscriptionDate;

    /**
     * @var string
     *
     * @ORM\Column(name="subscription_ip", type="string", length=50)
     */
    private $subscriptionIp;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="unsubscription_date", type="datetime", nullable=true)
     */
    private $unsubscriptionDate;

    /**
     * @var string
     *
     * @ORM\Column(name="unsubscription_ip", type="string", length=50, nullable=true)
     */
    private $unsubscriptionIp;

    /**
     * @var string
     *
     * @ORM\Column(name="continent_code", type="string", length=2, nullable=true)
     */
    private $continentCode;

    /**
     * @var string
     *
     * @ORM\Column(name="country_name", type="string", length=59, nullable=true)
     */
    private $countryName;

    /**
     * @var string
     *
     * @ORM\Column(name="region", type="string", length=255, nullable=true)
     */
    private $region;

    /**
     * @var string
     *
     * @ORM\Column(name="city", type="string", length=255, nullable=true)
     */
    private $city;

    /**
     * @var string
     *
     * @ORM\Column(name="postal_code", type="string", length=50, nullable=true)
     */
    private $postalCode;

    /**
     * @var string
     *
     * @ORM\Column(name="latitude", type="string", length=50, nullable=true)
     */
    private $latitude;

    /**
     * @var string
     *
     * @ORM\Column(name="longitude", type="string", length=50, nullable=true)
     */
    private $longitude;

    /**
     * @var string
     *
     * @ORM\Column(name="dma_code", type="string", length=50, nullable=true)
     */
    private $dmaCode;

    /**
     * @var string
     *
     * @ORM\Column(name="area_code", type="string", length=50, nullable=true)
     */
    private $areaCode;

    /**
     * @var string
     *
     * @ORM\Column(name="hash", type="string", length=255)
     */
    private $hash;

}

these are some of the resource i have already been through but they do not quite answer the question of why some errors are shown on form level and some on field level:

form_errors(form) not showing any errors in Symfony Twig

Get global form errors from the FormView in twig template

this is my twig temaplte:

<div class="window-BG" id="alert">
    <div class="window">
        <div id="alert-title" class="win-img-text">{{ 'Please solve below errors'|trans }}:</div>
        <div id="alert-text" class="win-text">
            {% if error %}
                <ul>
                    <li>
                        {{ 'please check if you wrote correct data'|trans }}
                    </li>
                </ul>
            {% endif %}
            <div style="color: white">
               {{ form_errors(form) }}
            </div>    
        </div>
        <div class="window-close win-close-2">{{ 'Close'|trans }}</div>
    </div>
</div>

When using {{ form_errors(form) }} it brings up form level errors (6 of those)

I have also tried including each of the error field separately (please see below) but that only brings field level errors:

<div class="window-BG" id="alert">
        <div class="window">
            <div id="alert-title" class="win-img-text">{{ 'Please solve below errors'|trans }}:</div>
            <div id="alert-text" class="win-text">
                {% if error %}
                    <ul>
                        <li>
                            {{ 'please check if you wrote correct data'|trans }}
                        </li>
                    </ul>
                {% endif %}
                <div style="color: white">
                    {{ form_errors(form.firstname) }}
                    {{ form_errors(form.lastname) }}
                    {{ form_errors(form.emailaddress) }}
                    {{ form_errors(form.phone) }}
                    {{ form_errors(form.gender) }}
                    {{ form_errors(form.agreeterms) }}
                    {{ form_errors(form.agreeemails) }}
                    {{ form_errors(form.agreepartners) }}
                </div>    
            </div>
            <div class="window-close win-close-2">{{ 'Close'|trans }}</div>
        </div>
    </div>

I have also tried Any advice will be highly appreciated

1
Let's see your twig template.galeaspablo
Updated initial comment with 2 variation of twig template, both yield different results. I am trying to understand why do some errors are shown on form level and some on field level while all of those fields are set up in a similar manorSky21.86

1 Answers

16
votes
{{ form_errors(form) }}

will display the errors at the form level


{{form_errors(form.field) }}

will display the errors at that field


By default, errors stay on the field they happen at, unless you set error_bubbling to true. E.g.

->add('phone', TextType::class, array(
                'label' => false,
                'required' => true,
                /* 
                 * Errors in phone will go to the form, 
                 * instead of staying in the field
                 */
                'error_bubbling' => true,
                'attr' => array(
                    'placeholder' => 'Mobile Phone',
                    'pattern'     => '.{2,}', //minlength
                    'class' => 'form-field-set'
                )))

With error_bubbling=>true, on every field, you can then simply use

{{ form_errors(form) }}

in your twig template, to display all the errors. I.e. every error will bubble to the form, instead of staying at the field level.