phpsearchcakephpdrop-down-menu

CakePHP: Automatic search on pre-selected dropdown value


I have a search form which has, a text input box, three checkboxes and a preselected default value in a dropdown based on user data from the database. e.g. If a user lives in commune 1, then 1 is selected as a default value in the dropdown.

I want CakePHP to perform a search in the database filtered by that value, and return a paginated result. That's easy enough when pushing a submit-button, but I want to perform the search on page load without user interaction.

Now, in the controller I've tried to get the commune value from another place than the dropdown with:

if ($this->request->is('post)) {
    //Perform normal search with the other input fields included.    
} else {
    //Do the filtered search only by commune value, which I get from a function.   
}

Problem is, then the pagination will not work. This is expected as pagination uses GET. When I try to change page, it is not a post, and the search conditions will be set to that of only the commune value value again, and I get an error in the SQL statement.

I'm sorry if my explanation above is a bit messy, but you'll have to excuse me since english is not my first language.

I need suggestions of how to do this in another way. Is it at all possible? I suspect there is an easy solution to this, but I'm new to CakePHP, and can't seem to get it.

Performing search

$conditions = $this->setSearchConditions($this->request->data);
$res = $this->paginate('Ad', array($conditions));
$this->set('res', $res);

//limit is set in public $paginate variable

Setting the search conditons

private function setSearchConditions($data) {

    $conditions = array();
   // $this->log('Search: DATA', 'debug');
    //$this->log($data, 'debug');

    if ($this->request->is('post)) { //Submit-button is clicked, performing full search
        //$this->log('Dette er en post', 'debug');

        if ($data['Ad']['searchField']) { //Text searchfield is not empty, adding title or description to search criteria
            $this->log('Søkefeltet er ikke tomt', 'debug');
            $str_search = '%' . $data['Ad']['searchField'] . '%';
            $conditions[] = array(
                'OR' => array(
                    'Ad.title LIKE' => $str_search,
                    'Ad.description LIKE' => $str_search
                )
            );
        }//if

        if ($data['Ad']['commune_id']) { // Commune dropdown is not empty, adding   commune_id to search criteria
            $conditions[] = array(
                'Ad.commune_id' => $data['Ad']['commune_id']
            );
        }//if

        if ($data['Ad']['type_id']) { // Type checkboxes are not empty, adding type_id to search criteria
            $orArray = array();
            foreach ($data['Ad']['type_id'] as $type) {
                $orArray[] = array('Ad.type_id' => $type);
            }
            $conditions[] = array(
                'OR' => $orArray
            );
        }//if
    } else {
       $conditions[] = array(
         'Ad.commune_id' => $this->getDefaultCommune(); 
       ):
    }

    return $conditions;
}

Solution

  • I tried the CakeDC search plugin (See answer to Marks comment in initial question.) and e-mailed a similar question to them. The solution was to set an array with default search criteria, and merge it with the search conditions. Here's the controller code:

    public function view() {
        $this->set('title_for_layout', 'Localtrade Norway');
        $this->set('show_searchbar', true); //Shows searchbar div in view
        $this->log($this->request->data, 'debug');
    
        //Setting users home commune as default filter when the form is not submitted.
        $default_filter = array(
            'Ad.commune_id' => $this->Auth->user('User.commune_id')
        );
    
        $this->Prg->commonProcess(); //Search-plugin
        $this->paginate = array(
            'conditions' => array_merge($default_filter, $this->Ad->parseCriteria($this->passedArgs)), //If Ad.commune_id is empty in second array, then the first will be used.
            'fields' => $this->Ad->setFields(),
            'limit' => 3
        );
        $this->set('res', $this->paginate());
    }