phpsymfonysymfony-forms

Symfony 2: Create overview page with possibility to search - always got errors from form "should not be blank"


I defined the form:

class OrganizationSearchType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', 'text', array('label' => 'Name', 'required' => false))
            ->add('category', 'text', array('label' => 'Kategorie', 'required' => false))
            ->add('street', 'text', array('label' => 'Strasse', 'required' => false))
            ->add('zip', 'text', array('label' => 'PLZ', 'required' => false))
            ->add('city', 'text', array('label' => 'Ort', 'required' => false))
            ->add('search', 'submit', array('label' => 'Suchen'));

    }

    public function getName()
    {
        return 'organization';
    }
}

TWIG: {# app/Resources/views/organization/overview.html.twig #}

{% extends 'base.html.twig' %}

{% block body %}
    <h2>Organistationen</h2>
    {{ form_start(searchForm) }}
    {{ form_errors(searchForm) }}
    <div>
        {{ form_label(searchForm.name) }}
        {{ form_widget(searchForm.name) }}
    </div>
    <div>
        {{ form_label(searchForm.category) }}
        {{ form_widget(searchForm.category) }}
    </div>
    <div>
        {{ form_label(searchForm.street) }}
        {{ form_widget(searchForm.street) }}
    </div>
    <div>
        {{ form_label(searchForm.zip) }}
        {{ form_widget(searchForm.zip) }}
    </div>
    <div>
        {{ form_label(searchForm.city) }}
        {{ form_widget(searchForm.city) }}
    </div>

    {{ form_end(searchForm) }}

    {% if searchDone %}
    {% if table|length > 0 %}

Conroller:

/**
     * @Route("/organization")
     */
    public function showAll(Request $request)
    {
        $searchOrganization = new Organization();
        $repository = $this->getDoctrine()->getRepository('AppBundle:Organization');
        $availableCategories = $repository->getDistinctCategories();

        $selectCategories = array();
        for ($i=0; $i<count($availableCategories); $i++) {
            array_push($selectCategories, $availableCategories[$i]['category']);
        }

        $searchForm = $this->createForm(new OrganizationSearchType(), $searchOrganization);
        $searchForm->remove('category');
        $searchForm->add('category','choice', array('choice_list' => new ChoiceList($selectCategories, $selectCategories), 'label' => 'Kategorie', 'required' => false));
        $searchForm->handleRequest($request);

        if ($searchForm->isSubmitted()) {
            $name = $searchForm["name"]->getData();
            $category = $searchForm["category"]->getData();
            $street = $searchForm["street"]->getData();
            $zip = $searchForm["zip"]->getData();
            $city = $searchForm["city"]->getData();

            $searchOrganization = $repository->getBasicSearch($name, $category, $street, $zip, $city);
        } else {
            $searchOrganization = '';
        }

        return $this->render(
            'organization/overview.html.twig',
            array(
                'table' => $searchOrganization,
                'searchForm' => $searchForm->createView(),
                'searchDone' => $searchForm->isSubmitted(),
            )
        );
    }

All fields are optional - if they have no content the like-Statement searches for '%'. But I always get Errors - cannot find a possiblity to remove them.

category [choice]

Errors

Message Origin  Cause
This value should not be blank. category    Symfony\Component\Validator\ConstraintViolation
Object(Symfony\Component\Form\Form).data.category = null

city [text]

Errors

Message Origin  Cause
This value should not be blank. city    Symfony\Component\Validator\ConstraintViolation
Object(Symfony\Component\Form\Form).data.city = null

Class Organization:

<?php
// src/AppBundle/Entity/Product.php

namespace AppBundle\Entity;

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

/**
 * @ORM\Entity(repositoryClass="AppBundle\Entity\OrganizationRepository")
 * @ORM\Table(name="organization")
 */
class Organization
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @Assert\NotBlank()
     * @ORM\Column(type="string", length=150)
     */
    protected $name;

    /** 
     * @Assert\NotBlank()
     * @ORM\Column(type="string", length=100)
     */
    protected $category;

    /**
     * @Assert\NotBlank() 
     * @ORM\Column(type="string", length=100)
     */
    protected $street;

    /**
     * @Assert\NotBlank()
     * @ORM\Column(type="string", length=20)
     */
    protected $zip;

    /**
     * @Assert\NotBlank()
     * @ORM\Column(type="string", length=100)
     */
    protected $city;

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Organization
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set category
     *
     * @param string $category
     * @return Organization
     */
    public function setCategory($category)
    {
        $this->category = $category;

        return $this;
    }

    /**
     * Get category
     *
     * @return string 
     */
    public function getCategory()
    {
        return $this->category;
    }

    /**
     * Set street
     *
     * @param string $street
     * @return Organization
     */
    public function setStreet($street)
    {
        $this->street = $street;

        return $this;
    }

    /**
     * Get street
     *
     * @return string 
     */
    public function getStreet()
    {
        return $this->street;
    }

    /**
     * Set zip
     *
     * @param string $zip
     * @return Organization
     */
    public function setZip($zip)
    {
        $this->zip = $zip;

        return $this;
    }

    /**
     * Get zip
     *
     * @return string 
     */
    public function getZip()
    {
        return $this->zip;
    }

    /**
     * Set city
     *
     * @param string $city
     * @return Organization
     */
    public function setCity($city)
    {
        $this->city = $city;

        return $this;
    }

    /**
     * Get city
     *
     * @return string 
     */
    public function getCity()
    {
        return $this->city;
    }
}

class OrganizationRepository extends EntityRepository
{
    public function getBasicSearch($name, $category, $street, $zip, $city) {
        $qb = $this->createQueryBuilder('organization');
        if ($name == '') {
            $name = '%';
        }
        if ($category == '') {
            $category = '%';
        }
        if($street == '') {
            $street = '%';
        }
        if($zip == '') {
            $zip = '%';
        }
        if($city == '') {
            $city = '%';
        }
        $qb->where(
            $qb->expr()->andX(
                $qb->expr()->like('organization.category', ':category'),
                $qb->expr()->like('organization.name', ':name'),
                $qb->expr()->like('organization.street', ':street'),
                $qb->expr()->like('organization.zip', ':zip'),
                $qb->expr()->like('organization.city', ':city')
            )
        )->setParameters(array('category' => $category, 'name' => $name, 'street' => $street, 'zip' => $zip, 'city' => $city));

        $res = $qb->getQuery();
        return $res->getResult();
    }

    public function getDistinctCategories() {
        $qb = $this->createQueryBuilder('organization');
        $qb->select(array('organization.category'));
        $qb->addGroupBy('organization.category');
        $qb->orderBy('organization.category');
        $res = $qb->getQuery();
        return $res->getResult();
    }
}

Solution

  • The error come from the assertion onto your entity

    /** 
     * @Assert\NotBlank()
     * @ORM\Column(type="string", length=100)
     */
    protected $category
    

    Regardless what you put onto your form, every time you call isValid() onto a form tied to an entity, entity assertions are checked aswell. And this perfectly make sens.

    You have to fix your code

    Moreover, you're doing some extra work that isn't necessary and you're doing it in the wrong way.

    Hope this help