0

A contact form specifies a date, type and distribution center for a set of households. [The set of households is defined as the most recent for that center and is presented via ajax.] The type entity is required and the date must not be in the future. The type constraint is specified in the Contact entity; the date constraint is in a custom validator. If either of these constraints are violated the form is not valid as confirmed in Netbeans debug. Also, the error message appears in Netbeans.. Yet neither of the constraint messages appear in the template. Adding a dump of form_errors to the template provides nothing. I cannot determine why no messages appear.

Contact entity snippet:

namespace Mana\ClientBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Mana\ClientBundle\Validator\Constraints as ManaAssert;

/**
 * Contact
 *
 * @ORM\Table(name="contact", indexes={@ORM\Index(name="idx_contact_household_idx", columns={"household_id"}), @ORM\Index(name="idx_contact_type_idx", columns={"contact_type_id"}), @ORM\Index(name="idx_contact_center_idx", columns={"center_id"})})
 * @ORM\Entity(repositoryClass="Mana\ClientBundle\Entity\ContactRepository")
 * 
 */
class Contact
{
...
    /**
     * @var \Mana\ClientBundle\Entity\ContactType
     *
     * @ORM\ManyToOne(targetEntity="Mana\ClientBundle\Entity\ContactType", inversedBy="contacts")
     * @ORM\JoinColumn(name="contact_type_id", referencedColumnName="id")
     * @Assert\NotBlank(message="Type must be selected")
     */
    private $contactType;
...
    /**
     * @var \DateTime
     *
     * @ORM\Column(name="contact_date", type="date", nullable=true)
     * @ManaAssert\NotFutureDate
     */
    private $contactDate;

ContactController snippet:

/**
 * @Route("/addContacts", name="contacts_add")
 * @Template("ManaClientBundle:Contact:testLatestContacts.html.twig")
 */
public function addContactsAction(Request $request) {
    $form = $this->createForm(new ContactType());
    $form->handleRequest($request);
    $message = "";
    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $households = $this->getRequest()->request->get('contact_household');
        $data = $form->getData();
        $contactDate = $data->getContactDate();
        $contactCenter = $data->getCenter();
        $contactType = $data->getContactType();
        $n = count($households);
        foreach ($households as $id) {
            $household = $em->getRepository('ManaClientBundle:Household')->find($id);
            $houseContacts = $household->getContacts();
            $nContacts = count($houseContacts);
            $first = ($nContacts > 0) ? 0 : 1;
            $county = $contactCenter->getCounty();
            $contact = new Contact();
            $contact->setContactDate($contactDate);
            $contact->setCenter($contactCenter);
            $contact->setContactType($contactType);
            $contact->setCounty($county);
            $contact->setFirst($first);
            $household->addContact($contact);
            $em->persist($household);
        }
        $em->flush();
        $center = $contactCenter->getCenter();
        $desc = $contactType->getContactDesc();
        $message = "$n $desc contacts added for $center";
    }
    return array(
        'form' => $form->createView(),
        'title' => 'Add contacts',
        'message' => $message,
    );
}

Template snippet:

{{ form_errors(form.contactDate) }}
{{ form_errors(form.contactType) }}
<div class="width80">
    <form action="{{ path("contacts_add") }}" method="post">
        <div class="column1">
            <table>
                <tr>
                    <td><b>Date:</b> 
                    <td>{{ form_widget(form.contactDate) }}
                <tr>
                    <td><b>Type:</b> 
                    <td>{{ form_widget(form.contactType) }}
                <tr>
                    <td><b>Center:</b> 
                    <td>{{ form_widget(form.center)}}
            </table>

ContactType:

namespace Mana\ClientBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Doctrine\ORM\EntityRepository;

class ContactType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('contactType', 'entity', array(
                    'class' => 'ManaClientBundle:ContactType',
                    'property' => 'contactDesc',
                    'empty_value' => 'Select contact type',
                    'error_bubbling' => true,
                    'attr' => array("class" => "smallform"),
                    'query_builder' => function(EntityRepository $er) {
                        return $er->createQueryBuilder('c')
                                ->orderBy('c.contactDesc', 'ASC');
                    },
                ))
            ->add('contactDate', 'date', array(
                'data' => date_create(),
                'format' => 'M/d/y',
                'label' => '<b>Date:</b> ',
                'years' => range(date('Y'), date('Y') - 5),
            ))
            ->add('center', 'entity', array(
                    'class' => 'ManaClientBundle:Center',
                    'property' => 'center',
                    'data' => "",
                    'empty_value' => 'Select distribution center',
                    'error_bubbling' => true,
                    'attr' => array("class" => "smallform"),
                    'query_builder' => function(EntityRepository $er) {
                        return $er->createQueryBuilder('c')
                                ->orderBy('c.center', 'ASC');
                    },
                ))
            ->add('household', 'choice', array(
                'mapped' => false,
                'expanded' => true,
                'multiple' => true,
            ))
            ->add('householdId','text',array(
                'mapped' => false,
            ))
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Mana\ClientBundle\Entity\Contact',
            'cascade_validation' => true,
            'csrf_protection' => false,
            'required' => false,
            'error_bubbling' => TRUE,
            ));
    }

    public function getName()
    {
        return 'contact';
    }
}
10
  • 1
    Try $form->getErrorsAsString(), there you should see your errors. They won't show in the template if you are using child form types. Another possibility is that you have not rendered the csrf token, you can do it like this {{ form_end(form) }}. form_end() - Renders the end tag of the form and any fields that have not yet been rendered. This is useful for rendering hidden fields and taking advantage of the automatic CSRF Protection. Commented Sep 11, 2013 at 22:40
  • @lackovic10: $form->getErrorsAsString() in the Controller reveals the validation error messages there. Proves they exist; I'd like them in rendered template. {{ form_end(form) }}, in this case, adds nothing. Commented Sep 11, 2013 at 22:49
  • check this post: stackoverflow.com/questions/11208992/… i think you need to write a custom function to get the errors using $form->getErrors() and $form->getChildren() and then search for errors for each child. You can make a recursive function and then you need to pass the errors to the template manually. that's the best solution i found so far.. Commented Sep 11, 2013 at 22:58
  • also you can try to enable form_bubbling for child form types: symfony.com/doc/current/reference/forms/types/… Commented Sep 11, 2013 at 23:01
  • @lackovic10: Thanks for suggestions. I've added the form type in edit above - there are no child forms (unless I misunderstand the concept). Not sure how best to apply "get the errors using $form->getErrors() and $form->getChildren()". Output of errors as string is "ERROR: Type must be selected contactType: No errors contactDate: ERROR: Date may not be in future". Odd that it sees type error message but no error on contactType! Commented Sep 11, 2013 at 23:14

1 Answer 1

0

The error was due to including the code

'error_bubbling' => true,

Since the form was not a child there was no reason for that code to be there. It was an artifact from an earlier version of the application.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.