I brushed this code off and thought it might be useful to someone as a starting point for a dynamic search page. It has some cool functionality including passing search criteria via Javascript to the controller, search as you type, sorting of results by clicking on the column header plus much more. Hope you find it useful.
Some of the interesting features of the Visualforce page and Apex controller include:
Instead of the typical overhead of using getters/setters in the controller to maintain the variables for the search form, I used Dave Carroll's blog as an example to pass the variables via Javascript.
Since I'm using Javascript to pass my parameters, I can get fancy and make the search form more dynamic by running the search as the user types or selects an option in the picklist. No submit button is required.
Users can click on the column headers to toggle the direction of the search results by using a CommandLink component and passing the column name.
Build the picklist using Dynamic Apex's Describe functionality so that it's maintenance free.
Perform the search against multiple fields including multi-select picklists using dynamic SOQL and preventing SOQL injection attacks.
ContactSearchController
Take a look at the Apex code below. The search interaction is split up between two separate but integral parts. When the search is fired from the Visualforce page via Javascript, the SOQL is constructed in the runSearch() method and is then passed to the runQuery() method to execute. The SOQL string is persisted so that when the user clicks on the table column the same SOQL can be issued again in the toggleSort() method but ordered by a different field name and sort direction.
CustomerSearch Visualforce Page
The Visualforce page has three sections: 1) a search form, 2) a results blockTable and 3) a debug panel displaying the SOQL that was executed.
The search form has a number of fields that fire the Javascript search using the onkeyup and onchange events. Instead of each form field passing the current values to actionFunction's Javascript method, for ease of use, each form field calls the doSearch() function that gathers up the values and submits them. When the actionFunction renders it creates a Javascript function that POSTs the values to the controller in the same manner as CommandLink or CommandButton.
The search results BlockTable is rerendered when the search is submitted to the controller so that the results display properly. Users can click on the column headers to reorder the results of the query. This uses a CommandLink to pass the sort field to the controller and toggle the sort direction.