Creating a search form for custom fields

______UPDATE_______
Though I’m getting more and more votes, and the solution works, but cybmeta’s answer is actually the answer that is nice and WordPress’ way. You should definitely try that.

Step 1

Start by making an Advanced Search Form with which you want your user will interact with the website, and save it with a name (i.e. I saved it as advanced-searchform.php — but don’t save it with searchform.php then it’ll replace the WordPress’ default search form):

<form method="get" id="advanced-searchform" role="search" action="<?php echo esc_url( home_url( "https://wordpress.stackexchange.com/" ) ); ?>">

    <h3><?php _e( 'Advanced Search', 'textdomain' ); ?></h3>

    <!-- PASSING THIS TO TRIGGER THE ADVANCED SEARCH RESULT PAGE FROM functions.php -->
    <input type="hidden" name="search" value="advanced">

    <label for="name" class=""><?php _e( 'Name: ', 'textdomain' ); ?></label><br>
    <input type="text" value="" placeholder="<?php _e( 'Type the Car Name', 'textdomain' ); ?>" name="name" id="name" />

    <label for="model" class=""><?php _e( 'Select a Model: ', 'textdomain' ); ?></label><br>
    <select name="model" id="model">
        <option value=""><?php _e( 'Select one...', 'textdomain' ); ?></option>
        <option value="model1"><?php _e( 'Model 1', 'textdomain' ); ?></option>
        <option value="model2"><?php _e( 'Model 1', 'textdomain' ); ?></option>
    </select>

    <input type="submit" id="searchsubmit" value="Search" />

</form>

Then call the form into your template like the following:

<?php get_template_part( 'advanced', 'searchform' ); ?>

Now your search form is ready, and you can now use the search form and can take user input into the URL.

Step 2

What you just need is: query the database and query the post type and its custom fields as per the search query. Remember your search query is now the URL you got after submission of the form. Now ask WordPress to load your custom search result page when the form is submitted. Place the following function into your functions.php so that it’ll enable your custom search template instead of the default search.php:

<?php
function wpse_load_custom_search_template(){
    if( isset($_REQUEST['search']) == 'advanced' ) {
        require('advanced-search-result.php');
        die();
    }
}
add_action('init','wpse_load_custom_search_template');
?>

I brought the code somewhere from WPSE (I forgot the root), but there’s controversy using the code above. But it actually works (lame excuse of course).

Check another way @G.M. suggested.

Step 3

Make a new file and save it with advanced-search-result.php (because we used this name in functions.php) and now you are free – obviously. Concept is:

  • Grab the data from the URL,
  • Use a simple WP_Query() (if your query is complex then use $wpdb query),
  • Pass the commands within the query, fetch data from db, and
  • Show the result[s]

A sample can be:

<?php
// Get data from URL into variables
$_name = $_GET['name'] != '' ? $_GET['name'] : '';
$_model = $_GET['model'] != '' ? $_GET['model'] : '';

// Start the Query
$v_args = array(
        'post_type'     =>  'vehicle', // your CPT
        's'             =>  $_name, // looks into everything with the keyword from your 'name field'
        'meta_query'    =>  array(
                                array(
                                    'key'     => 'car_model', // assumed your meta_key is 'car_model'
                                    'value'   => $_model,
                                    'compare' => 'LIKE', // finds models that matches 'model' from the select field
                                ),
                            )
    );
$vehicleSearchQuery = new WP_Query( $v_args );

// Open this line to Debug what's query WP has just run
// var_dump($vehicleSearchQuery->request);

// Show the results
if( $vehicleSearchQuery->have_posts() ) :
    while( $vehicleSearchQuery->have_posts() ) : $vehicleSearchQuery->the_post();
        the_title(); // Assumed your cars' names are stored as a CPT post title
    endwhile;
else :
    _e( 'Sorry, nothing matched your search criteria', 'textdomain' );
endif;
wp_reset_postdata();
?>

So, here is your final thing. But still there are many challenges:

  • Alternative Values – an advanced search can be performed with ALL of the fields or ANY of the field, so you have to make sure the Query is taking all the results as per the search and data. You can use $wpdb custom SQL query for complex search result and that will be pure MySQL – WordPress has nothing there.
  • Sanitization & Validation – the texts field and textarea are so vulnerable that can cause mal practice to your site. So passing raw data would be unsafe, you will need to Sanitize and Validate them before passing into the db query. (Data Sanitization and Validation with WordPress – TutsPlus)
  • Designing – you can choose the page.php (or search.php) template and make this page on the basis of that.

So, you got the idea, now it’s your turn to explore and discover the way. Remember, everybody’s way is different. Make yours, so that I can follow you. 🙂

Leave a Comment