添加搜索框以过滤Symfony中的结果列表?

时间:2011-04-06 10:29:41

标签: list search symfony1 filter doctrine

由于Symfony中的典型indexSuccess操作,我需要在对象列表中放置一个搜索框。目标很简单:根据标准过滤列表。

我一直在阅读Zend Lucene approach in Jobeet tutorial,但似乎是用大锤敲打坚果(至少根据我的要求)。

我对自动生成的管理过滤器表单更感兴趣,但我不知道如何在前端实现它。

我可以简单地将搜索框内容传递给操作并构建自定义查询,但还有更好的方法吗?

修改

我忘了提到我想为每个模型属性设置一个通用输入字段而不是输入字段。

谢谢!

2 个答案:

答案 0 :(得分:3)

我正在使用这个解决方案,而不是集成Zend Lucene我设法使用自动生成的Symonfy的过滤器。这就是我这样做的方式:

//module/actions.class.php
public function executeIndex(sfWebRequest $request)
{
      //set the form filter
      $this->searchForm = new EmployeeFormFilter();
      //bind it empty to fetch all data
      $this->searchForm->bind(array());
      //fetch all
      $this->employees = $this->searchForm->getQuery()->execute();
      ...
}

我做了一个搜索动作来进行搜索

public function executeSearch(sfWebRequest $request)
{
  //create filter
  $this->searchForm = new EmployeeFormFilter();
  //bind parameter
  $fields = $request->getParameter($this->searchForm->getName());
  //bind
  $this->searchForm->bind($fields);
  //set paginator
  $this->employees = $this->searchForm->getQuery()->execute();
  ...
  //template
  $this->setTemplate("index");
}

搜索表单转到 mymodule / search 操作非常重要。

实际上,我还使用sfDoctrinePager分页设置直接设置表单生成的查询以获得正确分页的结果。

如果您想在搜索表单中添加更多字段,请选中this:)

答案 1 :(得分:0)

我终于使用Symfony生成的默认MyModuleForm创建了一个自定义表单

public function executeIndex {
    ...
    // Add a form to filter results
    $this->form = new MyModuleForm();
}

但仅显示自定义字段:

<div id="search_box">
    <input type="text" name="criteria" id="search_box_criteria" value="Search..." />
    <?php echo link_to('Search', '@my_module_search?criteria=') ?>
</div>

然后我创建了一个名为@my_module_search的路由链接到索引操作:

my_module_search:
  url:          my_module/search/:criteria
  param:        { module: my_module, action: index }
  requirements: { criteria: .* }  # Terms are optional, show all by default

使用Javascript(在本例中为jQuery),我将输入的文本追加到链接的href属性中的criteria参数:

$('#search_box a').click(function(){
    $(this).attr('href', $(this).attr('href') + $(this).prev().val());
});

最后,回到executeIndex操作,我检测是否输入了文本并向DoctrineQuery对象添加自定义过滤器:

public function executeIndex {
    ...
    // Deal with search criteria
    if ( $text = $request->getParameter('criteria') ) {
        $query = $this->pager->getQuery()
            ->where("MyTable.name LIKE ?", "%$text%")
            ->orWhere("MyTable.remarks LIKE ?", "%$text%")
            ...;
    }

    $this->pager->setQuery($query);

    ...
    // Add a form to filter results
    $this->form = new MyModuleForm();
}

实际上,代码更复杂,因为我在父类中编写了一些部分和一些方法来重用代码。但这是我能想到的最好的。