Atreides78
Atreides78

Reputation: 577

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();
    }
}

Upvotes: 0

Views: 95

Answers (2)

DonCallisto
DonCallisto

Reputation: 29942

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

  • remove assertion(s) from your entity
  • remove required => false from your FormType

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

  • If you tie an object to a form, you don't need to retrieve data from form directly
  • If you want to make a list of available category, you can hadle it passing an entitymanager to your FormType and, if you need, there's the possibility to set default values.

Hope this help

Upvotes: 0

Andras
Andras

Reputation: 692

Why do you remove then add the category field?

I think that is the problem. You should pass the required parameters through the constructor or a setter method and initialize the form corretly for the first time.

Upvotes: 0

Related Questions