How to Create an Advanced Search Form for WordPress

So you want to learn how they do those pretty slick WordPress search forms. The ones that have drop downs of categories, filtering through your posts as soon as you press submit. These are most often used in advanced themes such as eCommerce, job posting and real estate themes. These search forms are a real nice addition to your site – making it more usable and user friendly.

I’m going to assume that you are pretty well versed in WordPress theme development. I’m also going to assume that you know what custom post types are, and know how to create them. I’m also assuming that you know what taxonomies are. These two things are crucial to our form. Without them, we don’t have much to work with.
So ready to get started? Let’s roll up our sleeves and begin.

Build the Form

As I’ve mentioned, we are working with custom post types and taxonomies. For this tutorial, we are working with a post type named “Listings”. We have also attached several taxonomies to this post type – named: “Type“, “Rooms“, “Area” and “Price“.
As you can imagine, a Real Estate website will have visitors who wish to search through your listings that match only the ones that are “Single Family“, “3 Bedrooms“, in “Chicago, IL” and “under $100,000“.
So you see how this can be real handy.

So first we write a function that will return html. Let’s use WordPress function get_terms() to populate our select tags. In your functions.php, add the code below:

The above function will run get_terms() on the Taxonomy passed, and will return several option tags with the term slug and name in it. So in your template (where you want your form to appear), create a form and use the function we just created.

Test your form and see your drop down lists populate with the right Taxonomy terms. If not, make sure you’ve added the right terms for each Taxonomy in your blog.
Also note the form action “/listing-search-results/“. This is a page we have yet to build – one that will handle the form processing. We will cover that in the next section.

The Processing

You will need to create a page template – name it “Custom Search Results“. For information on how to create page templates for your theme, click here. Now, on this page – start with the code below:

The code above creates two empty arrays. $item is filled up with each $_POST key and value, and added to the $list array. $cleanArray is a merge with “relation” key with value “AND” to our existing $list array.
So once a user selects items from our drop down lists and submits the form, it should supply the values needed for our arrays. Do a print_r() on the $cleanArray and the output should be similar to below:

Now we have enough to query our database with. Add the lines of code below:

The above code sets up a few more variables. These are the needed arguments we need to pass into the WP_Query object – which does all the querying.
As you see, we’re querying post_type “listings” and returning only 9 items. “paged” is needed for pagination to work, and the main argument “tax_query” – tells the object to query taxonomies. Also note that inside WP_Query is plenty of data sanitation – so data is clean once passed.

The Output

So once data is sent to the WP_Query object, all we need to do is loop through it and display the output. Our WP_Query object (now $the_query) has all the methods to produce the needed results. Add the code below:

The code above behaves like a normal WordPress loop. So insert regular template tags inside the “while” loop and your output should render. Notice the use of post navigation (next_posts_link) in the bottom of the code? It should behave like normal posts pagination in WordPress.

Our results page with formatting etc.

Conclusion

There you have it. An advanced search form that will filter through your custom post types. You can display this search form in any part of your website – ideally in your sidebar or header area. I especially like this treatment because it highlights your custom post type all the more. Making it really stand out from your regular blog posts.

Useful Resources:

Make sure you go through these links to better understand what the code above does.

  1. WordPress Codex – WP_Query
  2. Advanced Taxonomy Queries – Ottopress
  3. Advanced Search Form Filters – WPAnswers

146 Comments

  1. Hi, thank you for this tutorial. I’d like to use it in my website, but I have to add a search field associated with the filters, can you help me please?

    Reply
  2. hi
    i am making a portal for educational resources, and i want to use this theme but instead of listings of property i need a listing of educational resources which can be filtered not by type, rooms and area, but by age subject, interests etc. Also i will need some modification in the single listing template for example i don’t need google maps options etc. as i am no developer, i can not edit yhis theme. can you help me in making such a theme?
    thanks

    Reply
  3. The “paged” functionality does not work when you apply filters. For instance, I have 15 total listings. When I apply a filter, I get 10 listings. But I am viewing each listing 1 by 1 – not 10 at a time. I want to click the “Next Post Button” to view the 2nd result…but clicking the “Next Post Button” resets the filter. Therefore, you see the default page that shows all of the results with no filters. Any help?

    Reply
    • Hello,
      If someone finds this article out, which is really great, I’ve done checkboxes for myslef, so here’s the code:
      So I wanted to have checkboxes for specific taxonomy as provided with IF statement
      Created input checkbox with name of taxonomy and term slug as value I wanted to have an array of checkboxes so added ‘[]’ in the namespaces so php would know about that. Created check variable.
      if($tax == ‘restaurants-features’){
      $x = ”;
      foreach ($terms as $term) {
      $checked = ”;
      if ( in_array( $term->slug, ‘restaurants-features’ ) ) {
      $checked = ‘checked’;
      }
      $x .= ‘slug . ‘” ‘ . $checked . ‘ /> ‘ . $term->name . ‘‘;
      }
      $x .= ”;
      }else(…)
      Then We need to edit a query a little as htmlspeacialchars works only on string, so we could use only one checkbox at time. We had to remove htmlspecialchars from terms, to have an array there but with that our form is not safe, so we make foreach to add htmlspecialchar for the values.
      foreach($_POST as $key => $value){
      if($value != ”){
      $item[‘taxonomy’] = htmlspecialchars($key);
      if($key == ‘restaurants-features’){
      foreach($value as $v) {
      $item[‘terms’][] = htmlspecialchars($v);
      }
      }
      $item[‘terms’] = $value;
      $item[‘field’] = ‘slug’;
      $list[] = $item;
      }
      }
      I hope someone may find this usefull, and thanks for the tutorial.

      Reply
  4. Hi guys,
    I need some help with a custom made advanced search plugin with multiple select fields, where each select is a taxonomy and the option values are categories. Search works fine, but the main issue is when the client ask for a slider with min/max prices values which result can be read in the result page… Really dont know if i’m explaining myself…
    Thanks in advance

    Reply
  5. good post
    I have a blog “http://financiamento100porcento.blogspot.com” and need an advanced search, as you demonstrate for wordpress.
    is there any way to do the same for my blog?
    thank you

    Reply
  6. Hey I have a client that want to build a car listing website, may I use your theme as my starting theme? I see your theme suit my need and just need some modification, and hemmm… your code is very clean… I really love it..)

    Reply
  7. Any chance you will add this as a plugin soon? I am not a programmer, but need this search inside custom post types really bad!

    Reply
  8. Brothr, grt tutorial….I just want to implement your code with a slight change, but when i Use the exact code you used above it is working, But the issue is ‘Paged’ is not working properly. When I use search, First time I am getting Total count of Particular search correctly, but when i click next page link it shows Total Posts count of that Post Type and links ….Can you help me out with this please.

    Reply
    • you’re going to have to filter the id for that taxonomy.
      so inside the foreach – you have to do an if statement.
      foreach ($terms as $term) {
      if($term->id != ‘termid’ || $term->id != ‘termid’){ //add this line
      //regular code here
      } //close new line
      }

      Reply
      • Hi Michael. Your code works perfectly fine if you want to filter terms for a specific tax. What I had in mind if filtering the Tax itself. For example..Image attached, If I want to exclude the last select drop (Cast) from the main list. Is that possible. Thank you. Sam

        Reply
      • My filter is not working? Can I also fliter by name?
        foreach ($terms as $term) {
        if($term->id != ‘7’ || $term->id != ‘6’ || ) {
        $x .= ‘slug . ‘”>’ . $term->name . ”;
        } //close new line
        }
        And how do I add a search field? Thanks!!

        Reply
  9. Hi,
    Thanks for this great tutorial. Its almost what I need but I need something more… I need a Text field as well as Dropdowns. Please see the attached image to understand more easily what I need.
    Your help is much appreciated..

    Reply
      • Hi, I followed your code example to create a custom search form for my project. I need to have a combination of a text field and a few drop-down boxes like the “Search the Directory” mockup above. The text field that I want to add will search for a relevant custom taxonomy from the same custom post type as the drop-down boxes. Can you please give me an example how to modify the query from the text field to merge those values from the drop-down boxes?

        Reply
    • hello abdul,
      i m not good in programming, can you please tell me how you have created the form and what is Do a print_r() on the $cleanArray and where i have to put it ?
      thanks in advance

      Reply
      • Hi Shashi,
        Its a very old comment. I got done what I needed but not sure if I still have that code on my server or computer. Send me an email if you need. I’ll try to find the code & send to you.
        Thanks

        Reply
  10. Is there any way to avoid the “Form Resubmission” dialog if a user performs a search, chooses a post and hits the back button? In Firefox there is an error page and I am concerned that users won’t know that they can refresh the page to go back.

    Reply
  11. Hi, I have solution for this searh to work with wp-pagenavi plugin for pagination. Hope it will help someone :
    Just put this line of code replacing Newer & older entries :
    [?php wp_pagenavi( array( ‘query’ => $the_query) ); ?]
    Thanks

    Reply
  12. Essentially I’ve setup mine search to use multiple selects. Is there a way that I can set the relation to OR instead of AND? $cleanArray = array_merge(array(‘relation’ => ‘OR’), $list);

    Reply
  13. This is a great tutorial and is just what I need but got a problem I can’t seem to figure out… On my site, when I do a search its works and gives me the right amount of posts but once I click the “next button” it shows me every single post. It’s like it’s forgotten the search settings. Can anyone help me please. Much appreciated. Terry

    Reply
  14. Hi, I know nothing about PhP really, but here’s what I want to do. Any help would be excellent.
    I want to create a results listings page where one of the taxonomies is pre-selected ie displays a list of say all properties with 3 bedrooms.
    So I want to make a page that is just called “Three bedroom properties”
    When you visit it it will display all properties with three bedrooms but also have the search box so users can search for something else.
    Please help!

    Reply
    • Hi Niall, did you ever get round to completing your goal of creating pages that filter by taxonomy (i.e. 3 bedrooms). If not I don’t mind to help you with that. Thanks.

      Reply
  15. Is it possible to show the taxonomy-name instead the taxonomy-slug in the first ‘option’? In other languages we need to show the accents and other characters. Thanks!

    Reply
  16. Please, help in one problem!
    I have done, as beside You is described above, all were got!
    But, shall expect such variant.
    If beside me in the base of the site no such variant, which does my visitor. For instance, he wants to find something that corresponds to all parameter, given in “Type”, “Rooms”, “Area” and “Price”.
    But I have no such variant, which corresponds to all four parameters.
    Signifies, I must offer other variants. For instance, “Excuse me, but us have no given on your request, but You may look other variants from “Type” “.
    Is Got that it is necessary to do the repeated request:
    or “new WP_Query”
    or “get_posts”
    or “query_posts()”
    But, two times on one page it is impossible do the request
    “new WP_Query” or “query_posts()”.
    Say, please, as possible do the repeated request, for instance “get_posts”?
    Thank you!

    Reply
  17. Really awesome theme. Everything is working well but When I try to get the search result by selecting options from the drop down menu it shows 404 error. Would you please let me know the reason.
    Thanks

    Reply
  18. HI, I’m trying to get the term Name as the first Item in the drop down, However it just display as blank, I’ve changed the line to
    ucfirst($term->name)

    Reply
  19. brother i did not get you on this line
    ”So once a user selects items from our drop down lists and submits the
    form, it should supply the values needed for our arrays. Do a print_r()
    on the $cleanArray and the output should be similar to below: ”
    how to do print_r()

    Reply
  20. Hi, I thanks for a great tutorial..
    I am relatively new in wordpress and having a problem querying a custom post type.. actually I am a bit confused..
    I want to have a filter search for books which are needed for a
    certain exam.. in my search drop down list, the first one will have the
    list of the universities, when a certain uni is selected, the next
    dropdown will have the list of available courses in that university. and
    the final dropdown will have the semesters names of that course..
    when all of these selected the result will show the list of books that are needed in that course exam..
    the example is in this link..
    http://www.academicbooks.dk/en
    i am very much confused on how to relate them..
    I have taken a custom post types named “books” and taxonomies named
    “uni”, “course”, ”semester” and ”exam”.. but stuck on relating
    them..
    if possible please help..

    Reply
    • From what I understand, you want something like a dynamic drop down list. The values of the next drop down list depends on what is selected from the previous correct?
      If that’s the case – you will need more that just the tutorial above. The tutorial above is a straight query gather all the post types that have the terms you select.
      You need a step before that. Maybe a combination of Javascript / Ajax to get values depending on selected – then submit.

      Reply
  21. Very helpful tutorial, thanks a lot!
    I’m experiencing one issue though: all posts (inside the custom post type) are appearing on the search results page. Always. Any ideas what it could be? I followed all the steps exactly how you explained them.
    I was not 100% at two points:
    1. inserting the last few $args is probably directly under the $list[] = $item; – right?
    2. where it says //add our code here i.e. the_title(); – I inserted php the_title( ”, ” ); (incl. brackets)

    Reply
    • Sorry for the late reply.
      1) – $list[] = $item is simply adding the $item array inside another array called $list. then we finally merge that with another array called $cleanArray.
      2) //add code here is correct. you add the regular template tags there.
      What helps is to stop the code and do a print_r($array) in every step of the way. This way, you will see if the elements are populating correctly.

      Reply
  22. if i have 4 select boxs that are rooms, price,days, and time. how do you exclude the time select box. ive been trying figure this thing out for weeks now and i just cant figure this out. its probablly so simple and i cant get it to work.

    Reply
  23. Not works with pagination, only page one keep the array :
    Array
    (
    [relation] => AND
    [0] => Array
    (
    [taxonomy] => type
    [terms] => condo
    [field] => slug
    )
    [1] => Array
    (
    [taxonomy] => rooms
    [terms] => 2-3-bedrooms
    [field] => slug
    )
    [2] => Array
    (
    [taxonomy] => area
    [terms] => la-crescenta
    [field] => slug
    )
    [3] => Array
    (
    [taxonomy] => price
    [terms] => 300k-400k
    [field] => slug
    )
    )
    but others (eg: /page/3/) the cleanArray is empty and all products are displayed but not the search terms.

    Reply
  24. Hi, I need some help. I need to insert a code for each property, and I managed to do this using get_the_ID() but I can’t make the code wordks on the search of wordpress… The cliente search for the code and the property don’t appear in searches …
    You can help me?
    sorry for my english..

    Reply
  25. Hi ,
    thanks for this great tutorial. please how can i have one of the taxonomy as text field rather than a dropdown.
    I have 2 taxonomy(one as cats and one as tags)
    My tags is for postcode which i want to be a text field.
    my categories is dropdown which is fine.
    please how can i achieve this.
    thanks a lot.

    Reply
  26. I am getting “page not found” after clicking on the submit button.please help me where i is my mistake. As i am follow the tutorial instruction.
    Thanks

    Reply
  27. Thanks for your tutorial, it resolved my theme problem. For several days, I looked for how to create dropdown from wordpress custom taxonomies for custom post type. Great tutorial indeed. 🙂

    Reply
  28. any plugin that can filter taxonomy dynamically, I have used Meta data and Taxonomies filter but its not working now and I so desperately want to create a search box which goes like Branch>>Semester>>Publication>>Subject, all four are taxonomies , I just need a filter 🙁 how can I do that ??
    I would appreciate any help you can provide, any tutorial or something I know very less of php but good with installing and using plugins
    help

    Reply
  29. I tried all the steps you have mentioned but when I click on the search button instead of showing any result it goes to 404 page despite the listing-search-results.php being there and the custom page template properly assigned. Can you help what can be the issue .

    Reply
  30. Wow, great sharing. Do you have an idea where could be found a plugin with both options – filter and search at the same time? I see that this one has the half of the options. Keep up the good job.

    Reply
  31. Hey there:)
    Awesome tutorial! One quick question though: what is this like in terms of SEO? Since it only has one URL: “listing-search-results/”?
    If you had to include locations, and looked up something such as “2 bedroom house in London”, how would it show in Google?

    Reply
    • That’s a very good question. The single url format: “/listing-search-results/” may not be the best in terms of SEO. It would have to be a more specific url such as:
      “/listing-search-result/type/apartment/rooms/3/area/los-angeles”. This would be ideal for SEO.
      But that means we would have to convert the form method to a “GET” – and format the querystring to: “/key/value” vs “?key=value.
      Now you can now bookmark and create links with this approach.

      Reply
      • Hi Michael
        I would like to do this but am unsure what to do, could you please provide a code example for converting the form method and querystring?
        Thanks

        Reply
  32. Michael, I found this post life-saving, after scouring the web for two days looking for this exact technique. I do have a question, though: is it possible to pass a search keyword to the resulting query? Here is what I mean: take a look at http://www.aerotek.com/. I’m building something similar for a job search site. In the “Job Search” box on their homepage, there are three search fields two dropdowns (custom taxonomies from a custom post type). But there’s also a keyword search field that is hooked to the eventual query when populated. I need to implement something like this in addition to your technique above. Any pointers would be appreciated. Thanks!

    Reply
  33. i have a problum with search .. first time i saw working ok but after i list more properties the search not work shows We found no results,.. how can i fix it??

    Reply
    • Yes that’s possible. But I imagine it to be = the steps would be done in the front end (using JavaScript), then finally submitted via the form in the last step.

      Reply
  34. advanced search form question.
    Great post on how to create an advanced search form, it’s exactly what I was looking for. However, I’m having one issue and it seems to be related to the line of code:
    $cleanArray = array_merge(array(‘relation’ => ‘AND’), $list);
    When I leave with AND, it shows no results because I do not have any posts that match all. If I switch that to OR, it shows posts, but breaks down when there are 2 posts of the same taxonomy, but not the third.
    Is there a way to adjust this line so that not all taxonomies have to be selected?

    Reply
    • Found my answer, I realized I am not able to add any additional fields to the form or it will cause problems with the array. This has produced another error in WP with headers already sent that I am trying to work through now.

      Reply
  35. Hi,
    i used this: function buildSelect($tax)
    al works fine exept on touch devices (opencloses inmediately)
    anny idea’s?
    im not and expert.. but not scared to edit some code.. 😉

    Reply
  36. Hi,
    I have three tax select fields. It works fine. Is it possible, when you select one taxonomy, only the available taxonomies in the next select field will show?
    Thank you!

    Reply
        • I don’t have an exact example, but it would be something like, you only display one select. Then as soon as you change it, an ajax call will find out what available tax is under the chosen one. And that’s what you display.

          Reply
  37. Hi Michael,
    Great article, Thanks for it.
    I am using in custom post type plugin as advance search filters but it can not redirect to search result page which is created in plugin.
    May be I am using wrong action url.
    Can you please tell how to use in it?
    Thank you

    Reply
  38. Did anyone ever solve the pagination issue?
    I followed the URL tutorial that people have mentioned and it didn’t work. Whenever I go onto the next page, the array resets and loads all the posts.

    Reply
  39. A great post! Very useful information when deciding which plugin is the best to use for WordPress search module according to our needs. I especially like Relevanssi because it’s a free plugin that replaces the default WordPress search module with a better search engine while offering a plethora of features and configurable options. You’ll get more relevant results and a better presentation of results! We’ve written an article about a similar topic and we would love to have your feedback

    Reply
  40. Thanks for the information, I want to know whether there is any way I can have dropdown style of search forms, as I have large number of post types, it would make it look ugly if I put all of them below search bar.

    Reply

Leave a Reply to Levan Kardava Cancel reply