具有多个标准的搜索表单,Symfony2

时间:2014-11-09 19:12:09

标签: php symfony doctrine-orm

我尝试创建一个包含多个条件的搜索表单,但它不起作用,我认为控制器没有收到表单,因为当我单击Button Submit时页面只会重新加载。

这是控制器

/**
* @ParamConverter("agence", options={"mapping": {"agence_slug":"slug"}})
*/
public function indexAction(Agence $agence, Request $request)
{

    $form = $this->createForm(new SearchTravelType());

    $request = $this->getRequest();

    $em = $this->getDoctrine()->getManager();

    if ($request->getMethod() == 'POST')
    {
        $form->bind($request);

        if ($form->isValid())
        {
            $criteria = $form->getData();
            $listTravels = $em->getRepository('ProjectTravelBundle:Travel')->getListBy($criteria, $agence); 

        }
    }

    $listTravels = $em->getRepository('ProjectTravelBundle:Travel')->findByAgence($agence);

    return $this->render('ProjectDashboardBundle:Travel:index.html.twig',
    array(
        'listTravels' => $listTravels,
        'agence' => $agence,
        'form' => $form->createView() ,
    ));
}

这是 queryBuilder

class TravelRepository extends EntityRepository
{

public function getListBy($criteria, $agence)
{
    $qb = $this->createQueryBuilder('t');
    $qb = $this->whereAgence($qb, $agence);
    $qb ->leftJoin('t.airport', 'a')
        ->addSelect('a');

    foreach ($criteria as $field => $value) {
        if (!$this->getClassMetadata()->hasField($field)) {
            // Make sure we only use existing fields (avoid any injection)
            continue;
        }

        $qb ->andWhere($qb->expr()->eq('t.'.$field, ':t_'.$field))
            ->setParameter('t_'.$field, $value);
    }

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

public function whereAgence (\Doctrine\ORM\QueryBuilder $qb, $agence)
{
    $qb->where('a.agence = :agence')
       ->setParameter('agence', $agence);

    return $qb;
}   

}

这是页面树枝和表格

<form class="form-horizontal" role="form"  method="post" >
   <td>{{ form_widget(form.id) }}</td>
   <td class="center">-</td>
   <td>{{ form_widget(form.title) }}</td>
   <td>{{ form_widget(form.country) }}</td>
   <td>{{ form_widget(form.destination) }}</td>
   <td>{{ form_widget(form.airport) }}</td>
   <td>{{ form_widget(form.departureDate) }}</td>
   <td>{{ form_widget(form.returnDate) }}</td>
   <td>{{ form_widget(form.price) }}</td>
   <td>{{ form_widget(form.enabled) }}</td>
   <td><span class="input-group-btn">
   <button type="submit" class="btn btn-purple btn-sm">Search
   <i class="icon-search icon-on-right bigger-110"></i></button>
  </span>
</form>

我认为第一个问题是控制器中没有恢复表单,我尝试使用

$listTravels = $em->getRepository('ProjectTravelBundle:Travel')->find(1);

而不是

getListBy($criteria, $agence)

看看给出了什么。控制器忽略表单,它直接进入以下查询

$listTravels = $em->getRepository('ProjectTravelBundle:Travel')->findByAgence($agence);

2 个答案:

答案 0 :(得分:2)

  1. 您可以在将REquest对象传递给此操作时从操作中删除$request = $this->getRequest();;
  2. 您需要在表单中添加操作
  3. 像这样:

    $this->createForm(new SearchTravelType(), null, [
        'action' => $this->generateUrl('ROUT')
    ]);
    

    或者像这样:

    <form class="form-horizontal" role="form"  method="post" action="{{ path('ROUT') }}" >
    

    修改

    我们使用GET方法创建过滤器表单(您应该使用POST方法插入数据库,而不是用于获取结果),禁用CSRF保护。我们创建了一个控制器动作:

    public function indexAction(Agence $agence, Request $request)
    {
    
        $form = $this->createForm(new SearchTravelType(), null, [
            'action' => $this->generateUrl('ROUTE'),
            'method' => 'GET'
        ]);
    
        $form->handleRequest($request);
    
        if ($form->isValid())
        {
            $em = $this->getDoctrine()->getManager();
    
            $criteria = explode('&', $request->query->get($form->getName())); // I didn't test this line, you should check it..
    
            $listTravels = $em->getRepository('ProjectTravelBundle:Travel')->getListBy($criteria, $agence);
    
            // Terminate the request
            return $this->render('ProjectDashboardBundle:Travel:index.html.twig',
            array(
                'listTravels' => $listTravels,
                'agence' => $agence,
                'form' => $form->createView() ,
            ));
        }
    
        $listTravels = $em->getRepository('ProjectTravelBundle:Travel')->findByAgence($agence);
    
        return $this->render('ProjectDashboardBundle:Travel:index.html.twig',
        array(
            'listTravels' => $listTravels,
            'agence' => $agence,
            'form' => $form->createView() ,
        ));
    }
    

答案 1 :(得分:1)

你可以试试这个包:

https://github.com/petkopara/PetkoparaMultiSearchBundle

为Doctrine Entity中的多标准搜索提供表单或服务。 在您的情况下,表单解决方案将解决您的问题:

首先在表单类型中添加MultiSearchType

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('search', MultiSearchType::class, array(
            'class' => 'ProjectTravelBundle:Travel'));
}

然后在您的Controller中添加以下代码

   public function indexAction(Request $request)
{
    $search = $request->get('search');
    $em = $this->getDoctrine()->getManager();
    $queryBuilder = $em->getRepository('ProjectTravel:Travel')->createQueryBuilder('e');
    $filterForm = $this->createForm('ProjectTravelBundle\Form\TravelType');

    // Bind values from the request
    $filterForm->handleRequest($request);

    if ($filterForm->isValid()) {
        // Build the query from the given form object
        $queryBuilder = $this->get('petkopara_multi_search.builder')->searchForm($queryBuilder, $filterForm->get('search'));
    }

    ..
}

最后在模板中渲染您的旅行表单

{{form_render(filter_form)}}