Written by James McDonald

July 30, 2022

Sometimes you want to provide a multi-value search form

This form POST’s to

Thenthe lookupSearch action filters the POST data and redirects to the lookup action with the search terms in the query string

The lookup action then takes the query string and turns it into a CakePHP query condition and filters the list of displayed items.

Create an action (lookupSearch) that takes the POST request from the above form

This action takes all the POST’ed form data and strips the empty values then redirects back to the action (lookup) that will display the list of filtered items based on the params entered in the search form.

// src/Controller/PalletsController.php

public function lookupSearch()
        // build a URL with all the search elements in it
        // filter out the empty values
        // the resulting URL will be
        // example.com/pallets/lookup?shipment_id=3243&shipment=SO-M003567&pl_ref=2919456

        $url = collection($this->request->getData())
            // remove empty
            ->map(function ($item) {
                // remove whitespace
                return trim($item);

        $url = array_map('trim', array_filter($this->request->getData()));

        // redirect the user to the url
        return $this->redirect(['action' => 'lookup', '?' => $url]);

Set $this->paginate to contain the search conditions. See the formatLookupActionConditions function below to see how the

// src/Controller/PalletsController.php

  public function lookup()
        $this->paginate = [
            'contain'    => [
            'limit'    => Configure::read('PalletsLookup.limit'),
            'maxLimit' => Configure::read('PalletsLookup.maxLimit'),
            'order'    => [
                'id' => 'DESC',

        $this->paginate['conditions'] = $this->Pallets->formatLookupActionConditions(

        $searchForm = new LookupSearchForm();

        $pallets = $this->paginate($this->Pallets);

        $statuses = $this->Pallets->InventoryStatuses->find('list');

        $locations = $this->Pallets->Locations
            ->where(['active' => 1])
            ->order(['Locations.location' => 'ASC']);


Customizing the search conditions based on database field types

Here I want to be able to search on a substring of sscc number so use "sscc LIKE %{$searchValue}%"

// src/Model/Table/PalletsTable.php

    public function formatLookupActionConditions($passedArgs = [])
        $conditions = [];

        foreach ($passedArgs as $searchKey => $searchValue) {
            // only interested in Lookup.xxx not page=2 etc
            switch ($searchKey) {
                case 'sscc':
                    $conditions[] = ['sscc LIKE' => "%{$searchValue}%"];
                    // dd($options);
                case 'shipment_id':
                    $conditions[] = ['shipment_id' => $searchValue];
                case 'item_id_select':
                    $conditions[] = ['item' => $searchValue];
                case 'production_date':
                    $conditions[] = [$searchKey . ' LIKE ' => $searchValue . '%'];
                case 'page':
                    // skip standard search keys because they are
                    // for paginate not conditions
                case 'sort':
                case 'direction':
                case 'shipment':
                case 'limit':
                    $conditions[] = [$searchKey => $searchValue];

       // remove the top level of the $conditions array
        $conditions = array_merge(...$conditions);
        // dd($conditions);
        return $conditions;


Submit a Comment

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

The reCAPTCHA verification period has expired. Please reload the page.

You May Also Like…