2

I am trying to build in a "search" box on a results page in my cakephp app. The page uses the cakePHP pagination component to show and "page" results. This is perfect, but I am having difficulties to get the next part to work.

The desired outcome:

  1. A cakephp form (post) with an input box and a couple of select boxes, including a date selector so that I can select between dates. The user should be able to populate these fields and submit
  2. On submit, the user selection should change the cakePHP pagination conditions in the controller
  3. In the view I want the pagination bar to keep record of the user selection, so that when I filter through different pages, it keeps the users search. I understand this can be achieved using $this->passedArgs, hence why I am using post and not get.

The code:

 // Form:
 <?php 
      echo $this->Form->create('search', array('class' => false));
           echo $this->Form->input('searchFor');
           echo $this->Form->input('dateFrom');
           echo $this->Form->input('dateTo');
      echo $this->Form->end(); 
 ?>

 // Controller:
 if($this->request->is("post")) {
      $filters = $this->request->data["search"];
      $this->passedArgs["searchFor"] = $filters["searchFor"];
      $this->passedArgs["dateFrom"] = $filters["dateFrom"]." 00:00:00";
      $this->passedArgs["dateTo"] = $filters["dateTo"]." 00:00:00";


      // Assign search parameters:
      if($this->passedArgs["searchFor"] != "") {
           $conditions["Model.field LIKE"] = "%".$this->passedArgs["searchFor"]."%";
      }

      $conditions["Model.created >="] = $this->passedArgs["dateFrom"];
      $conditions["Model.created <="] = $this->passedArgs["dateTo"];


 } else {
      $conditions = array("Result.status_id >=" => 12);
 }

 $this->paginate = array(
     'conditions' => $conditions,
     'order' => array('Result.created ASC'),
     'limit' => 20
 );

 $this->set("results",$this->paginate("Model");


 // The view file:
 <?php
      $this->Paginator->options(array('url' => $this->passedArgs));
 ?>

Where I am now:

  1. The initial page loads with all of the results
  2. When I populate the search boxes it does return my results

The problem:

  1. I am convinced the way I am doing it is incorrect as I now need to do 2 checks, a) being if results has been posted and b) check if there is passedArgs available. I am 100% convinced this is not the right way of doing it.
  2. Let's say I have 2 free form fields for search, say name and surname, if I leave surname blank my url would be written as below, and this does not look or appear to be correct. That means I have to assign default values to ensure the items below does not happen, which does not appear to be very dynamic.

    http://localhost/site/controller/action/surname:0/name:John/date:0/

  3. On refresh it says the page does not exist because the posted values is not available anylonger.
4

2 回答 2

6

通常我在控制器中这样进行:

//transform POST into GET
if($this->request->is("post")) {
    $url = array('action'=>'index');
    $filters = array();

    if(isset($this->data['searchFor']) && $this->data['searchFor']){
        //maybe clean up user input here??? or urlencode??
        $filters['searchFor'] = $this->data['searchFor'];
    }
    //redirect user to the index page including the selected filters
    $this->redirect(array_merge($url,$filters)); 
}

$conditions = array();
//check filters on passedArgs
if(isset($this->passedArgs["searchFor"])){
    $conditions["Model.field LIKE"] = "%".$this->passedArgs["searchFor"]."%";
}

//paginate as normal
$this->paginate = array(
     'conditions' => $conditions,
     'order' => array('Result.created ASC'),
     'limit' => 20
 );

这个想法是将表单发送的 POST 转换为 GET。所以你不会有分页器和刷新的问题

希望这可以帮助

于 2012-05-03T09:48:34.007 回答
1

通过使用这个搜索插件,你想要的东西可以做得更简单、更干。

它可以或多或少地自动化您想要的东西,而且它已经可以比您的代码做更多的事情。

所以我建议你直接使用插件或者看看它是如何做到的。:)

于 2012-05-03T09:25:34.287 回答