Need to find something?

Simple-Ajax-Filter-or-Search-for-WordPress

Simple Ajax Filter & Search for WordPress

In this post, I am going to share a simple way of using Ajax filter search for WordPress. I love using Ajax in my projects. It is neat, light and fast. Most importantly the user experience is much better.

The Scenario

We are going to build a search form like the one shown below. This form will search for movies which is a custom post type. We will also filter the result with a few fields – Movie Year, IMDB Rating, Language and Genre.

How Our Ajax Filter Search Works?

Ajax is very simple but can seem very tricky at first. In our scenario, we are going to send data as a request (search keywords, year, rating, language, genre) to the server and it will do a query with the data then return a callback with the results.

Initial Setup

For the purpose our ajax filter search form, we may create a fresh WordPress install and populate dummy data for the trial. We will basically edit 2 files in the theme – functions.php and script.js. As always, please make sure you are using a child theme. I used the Twenty Sixteen Theme’s child theme in my demo. I added a custom post type called movie and created the custom fields with Advanced Custom Fields plugin. You can add a custom post type with the following code added to the functions.php file.

<?php 
function register_custom_post_type_movie() {
    $args = array(
        "label" => __( "Movies", "" ),
        "labels" => array(
            "name" => __( "Movies", "" ),
            "singular_name" => __( "Movie", "" ),
            "featured_image" => __( "Movie Poster", "" ),
            "set_featured_image" => __( "Set Movie Poster", "" ),
            "remove_featured_image" => __( "Remove Movie Poster", "" ),
            "use_featured_image" => __( "Use Movie Poster", "" ),
        ),
        "public" => true,
        "publicly_queryable" => true,
        "show_ui" => true,
        "show_in_rest" => false,
        "has_archive" => false,
        "show_in_menu" => true,
        "exclude_from_search" => false,
        "capability_type" => "post",
        "map_meta_cap" => true,
        "hierarchical" => false,
        "rewrite" => array( "slug" => "movie", "with_front" => true ),
        "query_var" => true,
        "supports" => array( "title", "editor", "thumbnail" ),
        "taxonomies" => array( "category" ),
    );
    register_post_type( "movie", $args );
}
add_action( 'init', 'register_custom_post_type_movie' );Code language: HTML, XML (xml)

Alternatively, you can use a plugin like Custom Post Types UI for adding custom post types with a user interface.

Before we create some movie posts, we need to create the custom fields which are used as filters.

The fields are pretty self-explanatory but if you are confused, here is the exported JSON file of the field group which you can download, unzip and import on ACF.

Download acf-export-2018-04-02.zip

Once you have the custom fields ready, you can start posting some movie posts. The add new movie post page should look something like the following.

You can see, I added some categories. They will work as the genre of the movie. After creating some demo movie posts, we are ready to start coding.

Creating a Shortcode for the Ajax Filter Search

In this step, we are creating a shortcode that will return the form code. So, we can use the shortcode in any part of the website to use the form. Put the following code on functions.php file.

<?php
// Shortcode: [my_ajax_filter_search]
function my_ajax_filter_search_shortcode() {
    ob_start(); ?>
 
    Test Shortcode Output
    <!-- FORM CODE WILL GOES HERE -->
     
    <?php
    return ob_get_clean();
}
 
add_shortcode ('my_ajax_filter_search', 'my_ajax_filter_search_shortcode');Code language: HTML, XML (xml)

Now use the shortcode [my_ajax_filter_search] in any page content and you should see “Test Shortcode Output” as output. As our shortcode is working fine, we are going to put actual form code that we will use the filter/search form.

<?php
// Shortcode: [my_ajax_filter_search]
function my_ajax_filter_search_shortcode() {
    ob_start(); ?>
 
    <div id="my-ajax-filter-search">
        <form action="" method="get">
            <input type="text" name="search" id="search" value="" placeholder="Search Here..">
            <div class="column-wrap">
                <div class="column">
                    <label for="year">Year</label>
                    <input type="number" name="year" id="year">
                </div>
                <div class="column">
                    <label for="rating">IMDB Rating</label>
                    <select name="rating" id="rating">
                        <option value="">Any Rating</option>
                        <option value="9">At least 9</option>
                        <option value="8">At least 8</option>
                        <option value="7">At least 7</option>
                        <option value="6">At least 6</option>
                        <option value="5">At least 5</option>
                        <option value="4">At least 4</option>
                        <option value="3">At least 3</option>
                        <option value="2">At least 2</option>
                        <option value="1">At least 1</option>
                    </select>
                </div>
            </div>
            <div class="column-wrap">
                <div class="column">
                    <label for="language">Language</label>
                    <select name="language" id="language">
                        <option value="">Any Language</option>
                        <option value="english">English</option>
                        <option value="korean">Korean</option>
                        <option value="hindi">Hindi</option>
                        <option value="serbian">Serbian</option>
                        <option value="malayalam">Malayalam</option>
                    </select>
                </div>
                <div class="column">
                    <label for="genre">Genre</label>
                    <select name="genre" id="genre">
                        <option value="">Any Genre</option>
                        <option value="action">Action</option>
                        <option value="comedy">Comedy</option>
                        <option value="drama">Drama</option>
                        <option value="horror">Horror</option>
                        <option value="romance">Romance</option>
                    </select>
                </div>
            </div>
            <input type="submit" id="submit" name="submit" value="Search">
        </form>
        <ul id="ajax_filter_search_results"></ul>
    </div>
     
    <?php
    return ob_get_clean();
}
 
add_shortcode ('my_ajax_filter_search', 'my_ajax_filter_search_shortcode');Code language: HTML, XML (xml)

Here, we added 5 fields. The search as an input field, Year as a number field, Rating, Language and Genre as a select dropdown. The options in the drop-down fields are set based on the option we had in the custom fields. The year field will have 4 digit number so it is ok with as a number field. Rating is set from 1 to 9 as IMDB ratings are like that. Language and Genre are ordinary select fields with matching options from the backend custom field and categories.

Adding Necessary Script

We are going to create a new script.js file in our theme folder for adding our javascript codes. Add the following code before the shortcode function we added earlier on the functions.php file.

<?php
// Scripts for Ajax Filter Search
 
function my_ajax_filter_search_scripts() {
    wp_enqueue_script( 'my_ajax_filter_search', get_stylesheet_directory_uri(). '/script.js', array(), '1.0', true );
    wp_add_inline_script( 'my_ajax_filter_search', 'const ajax_info = '. json_encode( array(
        'ajax_url' => admin_url( 'admin-ajax.php' )
    ) ), 'before' );
}Code language: HTML, XML (xml)

We also used wp_inline_script() for easy use of admin-ajax.php file.

Next thing to do is calling the my_ajax_filter_search_scripts() function inside the my_ajax_filter_search_shortcode() function.

<?php
// Shortcode: [my_ajax_filter_search]
function my_ajax_filter_search_shortcode() {
 
    my_ajax_filter_search_scripts(); // Added here
     
    ob_start(); ?>
  
    <div id="my-ajax-filter-search">
        <form action="" method="get">
 
        ....
        ....Code language: HTML, XML (xml)

This way the scripts needed for the ajax filter/search will load whenever we use the shortcode.

Preparing Data for Sending the Request

Add the following code to the script.js file

$ = jQuery;
 
var mafs = $("#my-ajax-filter-search"); 
var mafsForm = mafs.find("form"); 
 
mafsForm.submit(function(e){
    e.preventDefault(); 
 
    console.log("form submitted");
 
// we will add codes above this line later
});Code language: JavaScript (javascript)

Here we added two variables for ease of use and then a function that fires when the form submit button is pressed. The code e.preventDefault(); part prevents page reload. You will also see output “form submitted” on browser console (Press F12 on Chrome to go to developer tools and then Esc to go to console window).

Now that we see our code is working fine, we can go ahead and prepare the data. Replace console.log(“form submitted”); with the following code (before “});” at the bottom).

if(mafsForm.find("#search").val().length !== 0) {
    var search = mafsForm.find("#search").val();
}
if(mafsForm.find("#year").val().length !== 0) {
    var year = mafsForm.find("#year").val();
}
if(mafsForm.find("#rating").val().length !== 0) {
    var rating = mafsForm.find("#rating").val();
}
if(mafsForm.find("#language").val().length !== 0) {
    var language = mafsForm.find("#language").val();
}
if(mafsForm.find("#genre").val().length !== 0) {
    var genre = mafsForm.find("#genre").val();
}
 
var data = {
    action : "my_ajax_filter_search",
    search : search,
    year : year,
    rating : rating,
    language : language,
    genre : genre
}Code language: JavaScript (javascript)

Here, we are checking on submission, if the fields have value. If they do, we set their respective value on a variable and add all of them to the variable data. The part action : “my_ajax_filter_search” is needed for the callback in the next step as we will be sending data via GET method.

Prepare Callback Function

We have the data ready for the request. Now, we need to configure the callback. Going back to the functions.php file, we will add a new function for the callback.

<?php
 
// Ajax Callback
 
add_action('wp_ajax_my_ajax_filter_search', 'my_ajax_filter_search_callback');
add_action('wp_ajax_nopriv_my_ajax_filter_search', 'my_ajax_filter_search_callback');
 
function my_ajax_filter_search_callback() {
 
    header("Content-Type: application/json"); 
 
    $meta_query = array('relation' => 'AND');
 
    if(isset($_GET['year'])) {
        $year = sanitize_text_field( $_GET['year'] );
        $meta_query[] = array(
            'key' => 'year',
            'value' => $year,
            'compare' => '='
        );
    }
 
    if(isset($_GET['rating'])) {
        $rating = sanitize_text_field( $_GET['rating'] );
        $meta_query[] = array(
            'key' => 'rating',
            'value' => $rating,
            'compare' => '>='
        );
    }
 
    if(isset($_GET['language'])) {
        $language = sanitize_text_field( $_GET['language'] );
        $meta_query[] = array(
            'key' => 'language',
            'value' => $language,
            'compare' => '='
        );
    }
 
    $tax_query = array();
 
    if(isset($_GET['genre'])) {
        $genre = sanitize_text_field( $_GET['genre'] );
        $tax_query[] = array(
            'taxonomy' => 'category',
            'field' => 'slug',
            'terms' => $genre
        );
    }
 
    $args = array(
        'post_type' => 'movie',
        'posts_per_page' => -1,
        'meta_query' => $meta_query,
        'tax_query' => $tax_query
    );
 
    if(isset($_GET['search'])) {
        $search = sanitize_text_field( $_GET['search'] );
        $search_query = new WP_Query( array(
            'post_type' => 'movie',
            'posts_per_page' => -1,
            'meta_query' => $meta_query,
            'tax_query' => $tax_query,
            's' => $search
        ) );
    } else {
        $search_query = new WP_Query( $args );
    }
 
    if ( $search_query->have_posts() ) {
 
        $result = array();
 
        while ( $search_query->have_posts() ) {
            $search_query->the_post();
 
            $cats = strip_tags( get_the_category_list(", ") );
            $result[] = array(
                "id" => get_the_ID(),
                "title" => get_the_title(),
                "content" => get_the_content(),
                "permalink" => get_permalink(),
                "year" => get_field('year'),
                "rating" => get_field('rating'),
                "director" => get_field('director'),
                "language" => get_field('language'),
                "genre" => $cats,
                "poster" => wp_get_attachment_url(get_post_thumbnail_id($post->ID),'full')
            );
        }
        wp_reset_query();
 
        echo json_encode($result);
 
    } else {
        // no posts found
    }
    wp_die();
}Code language: HTML, XML (xml)

The above code block has few important things that I would like to explain.

  • At line 05 and 06, you see we used add_action for the callback function my_ajax_filter_search_callback(). If you have been using a diffrent function name, you can change wp_ajax_my_ajax_filter_search to wp_ajax_YOUR_FUNCTION_NAME. Same thing for wp_ajax_nopriv_my_ajax_filter_search
  • At line 10 we added header(“Content-Type: application/json”); to declare the content type as json because, we are going to use JSON to send result back to the browser.
  • At line 12 we started adding meta_query rules based on our fields. They are checked if they are set from the form submission then, they are sanitized for injection and compared different conditions.
  • At line 41 we added tax_query rules as we used WordPress categories as the Genre of the movies.
  • Finally, at line 52, we combined the arguments for the query but we also need to query for the search keywords passed from the search input. For this, we used ‘s’ => $search. Here the value of $search is checked for relevant results.
  • After the query, at line 95 we echo the result encoded as JSON which we will use in the next step in jQuery Ajax function.

jQuery Ajax Function

Now we are going to use jQuery Ajax function to complete our last step. Add the following code after the previous code (before the bottom “});”) on script.js file.

$.ajax({
        url : ajax_info.ajax_url,
        data : data,
        success : function(response) {
            mafs.find("ul").empty();
            if(response) {
                for(var i = 0 ;  i < response.length ; i++) {
                     var html  = "<li id='movie-" + response[i].id + "'>";
                         html += "  <a href='" + response[i].permalink + "' title='" + response[i].title + "'>";
                         html += "      <img src='" + response[i].poster + "' alt='" + response[i].title + "' />";
                         html += "      <div class='movie-info'>";
                         html += "          <h4>" + response[i].title + "</h4>";
                         html += "          <p>Year: " + response[i].year + "</p>";
                         html += "          <p>Rating: " + response[i].rating + "</p>";
                         html += "          <p>Language: " + response[i].language + "</p>";
                         html += "          <p>Director: " + response[i].director + "</p>";
                         html += "          <p>Genre: " + response[i].genre + "</p>";
                         html += "      </div>";
                         html += "  </a>";
                         html += "</li>";
                     mafs.find("ul").append(html);
                }
            } else {
                var html  = "<li class='no-result'>No matching movies found. Try a different filter or search keyword</li>";
                mafs.find("ul").append(html);
            }
        } 
    });Code language: JavaScript (javascript)

Here you can see we used ajax_info.ajax_url that we defined on the functions.php file. We then used the data variable for data param and for the success we have set a response.

As we are going to search multiple times from the same page, we will need to empty the ul that will contain all the results before appending the results. So we used mafs.find(“ul”).empty();

At last, we did a for loop and prepared the layout of the result to the html variable.

mafs.find(“ul”).append(html); appends the result in the ul.

Let us add some quick CSS so that it all looks good. You can add it to the sytle.css file or custom CSS in customizer.

.column-wrap {
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    margin: 20px 0
}
 
.column-wrap .column {
    width: 49%;
}
 
.column-wrap .column:last-child {
    float: right;
}
 
#my-ajax-filter-search label {
    display: block;
    font-weight: bold;
    font-style: italic;
}
 
#my-ajax-filter-search select {
    width: 100%;
    background-color: #f7f7f7;
    padding: 0.625em 0.4375em;
    border: 1px solid #d1d1d1;
}
 
#ajax_filter_search_results {
    list-style: none;
    display: flex;
    justify-content: start;
    flex-wrap: wrap;
    margin-top: 30px;
}
 
#ajax_filter_search_results li {
    width: 23.5%;
    float: left;
    margin-right: 2%;
    overflow: hidden;
    position: relative;
    margin-bottom: 20px;
}
 
#ajax_filter_search_results li.no-result {
    width: 100%;
    text-align: center;
}
 
#ajax_filter_search_results li:nth-child(4n+4) {
    margin-right: 0;
}
 
.movie-info h4 {
    margin-bottom: 10px;
    color: #fff;
}
 
.movie-info p {
    margin-bottom: 0;
    color: #fff;
    font-size: 13px;
}
 
.movie-info {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    padding: 15px;
    background: rgba(0, 0, 0, 0.85);
    opacity: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    transition: all .3s;
}
 
.movie-info * {
    width: 100%;
    display: block;
}
 
#ajax_filter_search_results li:hover .movie-info {
    opacity: 1;
}Code language: CSS (css)

The Output!

Bonus

A lot of requests came in since this article was published. One of the major requests was to know how to use checkboxes for the filter. So, let me share that with you guys.

To use checkboxes you will need to modify the code in a few areas. First of all, you need to make sure the checkboxes are added properly. If you are going to take multiple values, they need to be prepared so the values can be used in the query.

I am adding an example to the existing setup so you can follow:

First, add a new field in the field group for the checkboxes. Check the screenshot

In the form right before the submit field, let’s add an extra checkbox group

<input class="available" type="checkbox" id="netflix" value="netflix" name="available"><label for="netflix">Netflix</label>
<input class="available" type="checkbox" id="amazon" value="amazon" name="available"><label for="amazon">Amazon</label>
<input class="available" type="checkbox" id="viki" value="viki" name="available"><label for="viki">Viki</label>
<input class="available" type="checkbox" id="blueray" value="blueray" name="available"><label for="blueray">BlueRay</label>Code language: HTML, XML (xml)

Then, let’s add the javascript part. Here we are taking the values of the checkboxes to an array.

var available = [];
$.each($("input[name='available']:checked"), function(){ 
    available.push($(this).val());
});Code language: JavaScript (javascript)

Now inside the my_ajax_filter_search_callback() function before the genre meta_query conditon, let’s add some code

if(isset($_GET['available'])) {
    $available = $_GET['available'];
    foreach( $available as $value ) {
        $meta_query[] = array(
            'key' => 'available_on', // our new added custom field for the checkboxes
            'value' => $value,
            'compare' => 'LIKE'
        );
    }
}Code language: PHP (php)

Now your query should return according to the checkbox checked or unchecked properly.

Simple Ajax Filter Search Checkbox Field Integration
Here you can see, the results are showing only the movie titles that are available in Viki as selected.

Hopefully, this article will help you try Ajax on your next WordPress project and you will be easily adding an ajax filter search form on your website. Feel free to share your feedback below. Happy Coding!

Credits: Banner image from Freepik by macrovector. Movie posters are for demo purposes only. I don’t hold any copyright for the movie posters visible at the screenshots or anywhere else.

Last Updated: September 10, 2022

Al-Mamun Talukder

About Al-Mamun Talukder

WordPress Developer. Minimalist Designer. Tech Enthusiast. Music & Movie Freak. Loves Cars. Founder of WolfDevs.

Connect with me: Upwork, GitHub, Facebook, Twitter

111 comments

  • Jim Poulos

    Hello Al-Mamun,
    This is excellent. Thanks very much. I am currently having 99% success. However, when the search does not match, I am not getting the “no results found” message. For example if I choose a genre which includes 3 results, no problems. I get the 3 movies that match. But if I choose a language or genre that I know has no matches, it does not empty the container and will not show a no results found message. Any ideas?

  • Great Tutorial! Any chance that this could include some pagination on the results?

  • Dimitar

    Very Helpful! Thank you for you work and that you share this!

  • Good Work and Good Example.

    Thank You

  • Vikas Pandey

    Hello,
    How we can add pagination in this example. I need to add paginate links function for pagination
    Appreciate your response
    Thanks

  • Hello,
    how we can display the default results on page load
    Appreciate your response
    Thanks

  • Hussain Saad

    how can i make it custom post type (plugin)
    and i want to add filter by date

    thanks in advance

  • Jon Imms

    awesome tutorial thank you. I was wondering, is there solution like this without having to click the search button? So displays results as soon as you select a dropdown item

  • Saravan

    Can we make the AJAX to trigger on click of the select elements rather than click on Search each time

    • A

      Yes. Just change javascript portion to trigger submission on change of select elements or any other fields that you may require.

  • Shivam gohil

    can you send me that all files please?
    also how can i data show by default

  • Finally found an awesome solution. Thanks for this OP 😀

  • Hi it’s a nice tutorial, everything works fine. but the checkbox code you mentioned as bonus its not working properly. when i check amazon its show both amazon,viki,Netflix results, i uploaded only 3 checkbox with 3 dummy data. problem is, when i check the amazon or any check value it shows all the results which is wrong, it should show only the particular data.kindly share me the functions.php page full code, i think the placement of the checkbox code mistake.

  • Hi bro,
    Great tips, but I want to show all posts before using ajax filter search, what should I do?
    Thank bro!

    • A

      Hi Lucas. Just a default query within the shortcode’s code. For example:

      Replace the following code from the shortcode function..
      [html]<ul id="ajax_filter_search_results"></ul>[/html]

      With
      [php]
      <?php
      $args = array(
      ‘post_type’ => ‘movie’,
      ‘posts_per_page’ => -1,
      );

      $default_query = new WP_Query( $args );
      if ( $default_query->have_posts() ) {
      echo ‘<ul id="ajax_filter_search_results">’;
      while ( $default_query->have_posts() ) {
      $default_query->the_post();
      /** YOUR QUERY LOOP HERE **/
      }
      wp_reset_postdata();
      echo ‘</ul>’;
      }
      ?>
      [/php]

  • hey! I really like what you did here and the way you respond/explain everyone how to use your code, well done!
    The only thing I wanted to ask: in functions.php you have your function my_ajax_filter_search_shortcode(), but you manually add the options for Year, IMDB Rating, Language, Genre. Is it possible to automatically pick up those options from database instead of writing them down? In your ACF plugin you will have your fields, can’t we just list all the values under options dynamically instead of typing them out? Because now – if you will add new Genre in admin, you will have to go and edit this script to make it visible on front end.

  • Heather New

    I’m having a hard time with the callback and ajax portion. I’m not using a CPT, I have a section repeater that has a Q&A faq repeater nested inside. To display acf fields in php I use:

    [html]<a href="” rel="nofollow ugc">

    <a href="” target=”_blank” rel="nofollow ugc">

    <a href="” target=”_blank” rel="nofollow ugc">

    ——————————————
    This is my callback attempt
    function faq_ajax_filter_search_callback() {
    header(“Content-Type: application/json”);
    $meta_query = array(‘relation’ => ‘AND’);
    $args = array(
    ‘post_type’ => ‘page’,
    ‘meta_query’ => $meta_query
    );
    if(isset($_GET[‘search’])) {
    $search = sanitize_text_field( $_GET[‘search’] );
    $search_query = new WP_Query( array(
    ‘post_type’ => ‘page’,
    ‘meta_query’ => $meta_query,
    ‘s’ => $search
    ) );
    } else {
    $search_query = new WP_Query( $args );
    }
    if ( $search_query->have_posts() ) {
    $result = array();
    while ( $search_query->have_posts() ) {
    $search_query->the_post(); ?>

    get_the_ID(),
    “section” => have_rows(‘section’),
    “section_headline” => get_sub_field(‘section_headline’),
    “section_faq” => have_rows(‘section_faq’),
    “headline” => get_sub_field(‘headline’),
    “headline” => get_sub_field(‘headline’),
    “information” => get_sub_field(‘information’),
    “button” => get_sub_field(‘button’),
    );?>
    <?php }
    wp_rest_query();
    ——————-[/html]
    Would be super appreciative for help, I'm learning how to make acf data dynamic

  • hah, no worries. Thank you for sharing this solution, it was a helpful example. I’ve got it in and working my next step is to modify it a bit to work with nested repeaters and using ACF fields on a page instead of through a CPT to create an ajax search for a FAQ page.

  • In the shortcode above there is a ul looks to be misspelled as fitler not filter

  • Alexandr

    For repeater field we need to add this code. Now it works
    add_filter(‘posts_where’, ‘yanco_posts_where’);
    function yanco_posts_where( $where ) {
    $where = str_replace( “meta_key = ‘repeater_machines_$”, “meta_key LIKE ‘repeater_machines_%”, $where );
    $where = str_replace( “meta_key = ‘repeater_machines_$”, “meta_key LIKE ‘repeater_machines_%”, $where );
    return $where;
    }

    Can you help me to handle with the problem ?
    How I can do a search only when all search fields are filled in, we just not need to search until all fields are filled. Now it searches even one field is filled.

    Thanks for your work!

  • Alexandr

    Hello. How I can search by repeater field. With simple txt field search works perfectly, but when I try to add repeater field it doesn’t work. COUNTRY – is the repeater field.
    I think the mistake is in this part:

    if(isset($_GET['country'])) {
    $country = sanitize_text_field( $_GET['country'] );
    $meta_query[] = array(
    'key' => 'country',
    'value' => $country,
    'compare' => '='
    );
    }

    or in this one:

    if( have_rows('repeater_machines') ):
    while ( have_rows('repeater_machines') ) : the_row();
    $country = get_sub_field('country');
    endwhile; endif;
    //wp_reset_query();

    $result[] = array (
    "id" => get_the_ID(),
    "title" => get_the_title(),
    "content" => get_the_content(),
    "permalink" => get_permalink(),
    "year" => get_field('year'),
    "rating" => get_field('rating'),
    "director" => get_field('director'),
    "language" => get_field('language'),
    "test" => get_field('test'),
    "country" => $country,
    "genre" => $cats,
    "poster" => wp_get_attachment_url(get_post_thumbnail_id($post->ID),'full')
    );
    }

    Can you help me, please?

  • Quentin

    No worries ! Thanks a lot !

  • thank you for this tutorial. I can’t resolve an issue. Dev tools keep throwing me an error “data is not defined” in the script.js field, there :
    $.ajax({
    url : ajax_url,
    data : data,

    i can’t understand why.

  • Theresa

    Hi I haven’t tried it yet, but is there a way to have the list showing on the page but it is filtered once you use the form?

  • Quentin

    Hello and thanks for this tutorial !
    I saw on previous comments that you were talking about pagination, I tried a few things but I still can’t manage to set up the pagination (or load more button) system correctly.
    Would it be possible for you to put an example as a bonus?
    Thank you

  • Kamila Bona

    Hi! I’m not good enough at js. Where should I make changes in the code?

  • Hello! Great tutorial.
    I would like to search for movies from date to date. For example, all releases from 1/6/2019 to 1/3/2020. I think I have a problem with the date format.

  • Thank you sir, this helped me a lot!

  • Santanu Patra

    It was my mistake that meta_key was different. It’s now working really smoothly. But now I want to fetch post names in the dropdown from a CPT.
    Customizing the my_ajax_filter_search_shortcode() function to get post categories using get_terms. But not working.

    Sorry, but can’t share with you the URL at this moment. I will try to understand my points.

  • Santanu Patra

    Hei.. Thanks for this amazing concept. I want to use this queries to find post depending on 2 custom field value. I used the above code and customized. But every time all post appear.

    • A

      Hi. Please share the URL so I can check. It should work out of the box. I would suggest you do it first on a clean WordPress install.

  • Hi, thank you so much for this tutorial, helped me a lot.
    I would like to display results in php post loop (probably in the functions.php file), instead of the jquery result. Is there a way for that?
    Thanks

    • A

      If you want to change a post loop, you need to replace that with what we did here. In short, its something different and out of the scope of this tutorial.

  • Thank you for this! How would you use this and turn it into a checkbox filter of categories post?

  • Dmitry Yudin

    Hello, thx a lot for that tutorial! It’s really helpful!
    But checkboxes filter does not work for me.. If I check it all posts are shown.
    Where I am wrong with code?
    Адсорбент
    Все

    [code]
    if(isset($_GET[‘animal’])) {
    $animal = sanitize_text_field( $_GET[‘animal’] );
    $meta_query[] = array(
    ‘key’ => ‘animal’,
    ‘value’ => $animal,
    ‘compare’ => ‘=’
    );
    }
    [/code]

    [code]
    $ = jQuery;

    var mafs = $("#my-ajax-filter-search");
    var mafsForm = mafs.find("form");

    mafsForm.submit(function(e){
    e.preventDefault();

    // console.log("form submitted");
    if(mafsForm.find("#search").val().length !== 0) {
    var search = mafsForm.find("#search").val();
    }
    if(mafsForm.find("#animal").val().length !== 0) {
    var animal = mafsForm.find("#animal").val();
    }

    if(mafsForm.find("#genre").val().length !== 0) {
    var genre = mafsForm.find("#genre").val();
    }

    var data = {
    action : "my_ajax_filter_search",
    search : search,
    animal : animal,
    genre : genre
    }
    [/code]

    When I checked ‘ adsorbent’ field or uncheck it I see only one page with ‘adsorbent’ but when I uncheck it, it shows me only this one page anyway…

    • A

      Hello Dmitry Yudin,

      To use checkboxes you will need to modify the code in a few areas.

      First of all, you need to make sure the checkboxes are added properly. If you are going to take multiple values, they need to be prepared so the values can be used in the query.

      I am adding an example to the existing setup so you can follow:

      First, add a new field in the field group for the checkboxes. Check the screenshot https://imgur.com/a/VOVocHD.

      In the form right before the submit field, let’s add an extra checkbox group

      [html]
      <input class="available" type="checkbox" id="netflix" value="netflix" name="available"><label for="netflix">Netflix</label>
      <input class="available" type="checkbox" id="amazon" value="amazon" name="available"><label for="amazon">Amazon</label>
      <input class="available" type="checkbox" id="viki" value="viki" name="available"><label for="viki">Viki</label>
      <input class="available" type="checkbox" id="blueray" value="blueray" name="available"><label for="blueray">BlueRay</label>
      [/html]

      Then, let’s add the javascript part. Here we are taking the values of the checkboxes to an array.
      [javascript]
      var available = [];
      $.each($("input[name=’available’]:checked"), function(){
      available.push($(this).val());
      });
      [/javascript]

      Now inside the my_ajax_filter_search_callback() function before the genre meta_query conditon, let’s add some code
      [php]
      if(isset($_GET[‘available’])) {
      $available = $_GET[‘available’];
      foreach( $available as $value ) {
      $meta_query[] = array(
      ‘key’ => ‘available_on’, // our new added custom field for the checkboxes
      ‘value’ => $value,
      ‘compare’ => ‘LIKE’
      );
      }
      }
      [/php]

      Now your query should return according to the checkbox checked or unchecked properly.

  • I’m very novice at JS. How would I do that?

    • A

      Add this inside the form
      <input id="reset_form" type="reset" value="Reset">
      Then, add the following in your js file. (after $ = jQuery; line)
      $("#reset_form").click(function(){
      mafs.find("ul").empty();
      });

  • That’s great! Can I have it clear the results Div too so that the search results disappear too?

  • This is great! Is there a way to clear the search and reset fields? Ie a “clear” button? That way users don’t manually have to reset everything between results?

  • Thanks for your response ! I have try some things, but I’m not good enough in Javascript to understand what I have to do to be able separating the form part and the search result part. In this way to be able to put the form somewhere and display the search result (WP_query) somewhere else.

    Will apreciate alot if you could give me some more indication of how to do it.

    kindly,

    Steven

  • Unfortunately is what I have trying. When I take the ul element outsite of the -> “div id=”my-ajax-filter-search”

    The ul is displaying nothing 🙁

    • A

      It is not working outside of the #my-ajax-filter-search because, it is used on the javascript portion of the code. You need to change javascript code so the correct ID is used to perform the ajax request.

  • Hello! Great tutorial, but is there a way to display the “ul -> li elements” somewhere else?
    If u put the “ul ->li elements” somewhere else, it is not working.
    I would like to have the form at the end of my page and the result of the search at the middle.

  • Anatolie

    Hi!
    When the language in WP admin panel is English, the search works correctly but when I switch it to German or German (Austria) for some words or phrases the search results are strange!
    For example, when I search “Es ist was nicht war” having WordPress switched to German, instead of 2 posts (events) I am getting all posts, with different titles.
    Any Idea how to fix this error, Please?

    • A

      If you are searching for “Es ist was nicht war” and your content, title or any meta that you are searching in, has any matching words, it should list the post. Es, ist, was – these can be in regular words so it is normal to show more results. You can tweak the search results by changing the meta compare.

      • Anatolie

        In this special case the search is just in post title (not in post page and not in meta).
        Fragments as Es, ist, was are of course contained in other words, like etwas, Junges etc.
        I have about 300 events but this problem happens only with this title and it does not happen when I switch to English in admin settings.
        There is something additional that WP changes when I change the language..
        For me is important to get correct search response based on event title. Based on it, I get in ‘Next Presentations” block all events with the same title which will take place in future and other places.

  • Anatolie

    Hello and thank you for the tutorial!
    Is it possible to search by text not only in Title and post content but also in meta fiels, such as subtitle 1, subtitle 2?

    • A

      Thanks for your comment. You can easily search meta fields. Just add conditions as you need them. Here is a quick example.


      if(isset($_GET['subtitle_1'])) {
      $subtitle_1 = sanitize_text_field( $_GET['subtitle_1'] );
      $meta_query[] = array(
      'key' => 'subtitle_1',
      'value' => $subtitle_1,
      'compare' => 'LIKE'
      );
      }

      • Anatolie

        Thanks for quick answer!! 🙂
        For this example should be also created corresponding fields in the form, Subtitle 1, Subtitle 2, correct?
        My question is: can we extend the search area of the search field to the meta fields? The keyword inserted in the search filed to be searched in post tile, post content, meta subtitle 1, meta subtitle 2.

        • A

          Yes. You need to create custom fields and add the fields to the form. Then you need to pass the from data, where the query will try to search for similar content (title, content and any other fields you mention).

          • Anatolie

            I have implemented this filter for my Events custom posts. It is working fine. Thank you!
            But I would like to NOT add additional text fields to the form, in order to search in custom fields Subtitle 1, Subtitle 2. What I want is to use just one, existent form field for search in all event text, including meta fields.

            • A

              Then you just need to add the extra meta query for subtitle 1 and subtitle 2 fields, which will search with the existing variable data taken from the form search input.

  • Jonathan THOMAS

    Hi ! Very good job ! Thanks a lot.
    Is there a way that we could add autocompletion when typing for search please ?

    • A

      In the javascript portion of the code where we have

      mafsForm.submit(function(e){
      e.preventDefault();

      you can use this

      $("#search").on('keyup keypress blur change', function() {
      if($(this).val().length > 3) {

      This will trigger the search once a minimum of 4 characters are typed. Don’t forget to adjust the rest of the code accordingly otherwise it will not work.

  • The code works great, but when I entered the wrong movie title, the result didn’t return “No matching movies found. Try a different filter or search keyword”. Can you check it for me please

    • A

      I am using the same code that is given here and it works fine in the demo. Please double check your code to see if there is any difference. Thanks.

      • Thks, i find problem. Jquery new not support it. I tried wordpress default jquery and got it done

  • Thanks for this great tutorial. i am using custom taxonomy in my form for woocommerce products i want to show the taxonomy terms title & want to add “add to cart button” with their link so the user can go to the cart page.

  • I can’t seem to get ajax to kick in – when I do a search, all that happens is the page reloads. What is the best way to dubug an AJAX form to know where the problem is? I’ve tried adding the exact code into my custom them as well as 2016 multiple times…. Thanks!

    • I figured it out!
      The instruction to add:
      my_ajax_filter_search_scripts(); // Added here
      Was very subtle and I missed it! Thanks!

  • WOW! You really help me out of my problem. hehe
    the best tutorial I have read.

  • Emil D.

    Thanks, great tutorial!
    But how do i create a page (for GoogleAds for example) showing only posts with certain filters already on load of the page? Let’s say i want to have a URL which shows all movies from the year 2012 on load – how would i do that? I tried playing around in the URL, as i see the “?search=&year=&rating=&language=&genre=&submit=Search” part there, but nothing happens if i insert “2012” after the “year=” part for example and hit enter.

    • A
      Al-Mamun Talukder

      You need to change the JavaScript code to initiate everything on page load. In this tutorial, I did it on submit. Then it will work the way you want.

  • Great outstanding tutorial! May I know how can I search with multiple keywords like spiderman, xman etc? Would appreciate your response alot

    • A
      Al-Mamun Talukder

      Hello Maria. You will need to modify the WP_Query part of this tutorial to achieve search with multiple keywords. I am using ‘s’ which is the default search. In your case, it will need to be meta_query.

  • Hi, thank you for this great tutorial. I have one question. If etc. director name contains Ö or Ä, it doesn’t show in results, it’s O or A there. How to fix this?

    • A
      Al-Mamun Talukder

      Hello Mary. The director name field is not being searched in this tutorial. I will test the special letters.

      • Thank you for your quick reply 🙂
        I think better way to explain this problem is thinking of option value, which must be lowercase and not containing special characters.
        Etc. Räv return “rav” although it shoud return “Räv” in response[i].animal.
        So how can it set it return “Räv”?
        Hope this helps.

  • Thank you for sharing this post. Its working for me.

    • hi,
      I am facing the issue with custom filed checkbox.
      PLease check here: https://www.whichbroker.com/en/brokers/
      As per your instruction i was followed your comments for checkbox method.
      Here my code:
      in function
      if(isset($_GET[‘mutual_funds’])) {
      $mutual_funds = $_GET[‘mutual_funds’];
      $meta_query[] = array(
      ‘key’ => ‘tradable_assets’, // This needs to be the ACF field key
      ‘value’ => $mutual_funds,
      ‘compare’ => ‘LIKE’
      );
      }
      if(isset($_GET[‘currencies’])) {
      $currencies = $_GET[‘currencies’];
      $meta_query[] = array(
      ‘key’ => ‘tradable_assets’, // This needs to be the ACF field key
      ‘value’ => $currencies,
      ‘compare’ => ‘LIKE’
      );
      }

      ‘compare’ => ‘IN’ => not working for me.
      so i was given ‘compare’ => ‘LIKE’ its showing result but its not correct results.
      please check my form fields for check box. something is missing in my code. please have a look once.

  • Thanks a lot for your work! With the tutorial, I nearly finish my dream filter. Could you please share more thoughts about the pagination or ajax ‘load more’ button? I’ve tried, but it doesn’t work well.
    Beat regards & thanks again.

  • Hi, this is great. Thanks for helping! I do have one question, what if one of the fields were a checkbox group? How would the jquery change from this, for example, if year were a checkbox group?:
    if(mafsForm.find(“#year”).val().length !== 0) {
    var year = mafsForm.find(“#year”).val();
    }

    • A
      Al-Mamun Talukder

      var checkedYear = [];
      $(".year:checkbox:checked").each(function() {
      checkedYear.push($(this).val());
      });

      Something like this. It’s important to note that for checkbox you will need to use array on form element name attribute. For example:

      <label><input type="checkbox" name="year[]" class="year" value="2019"> 2019</label>

      • Thanks! Still having some issues. I’m hoping you can help me out.
        I have this in my form:
        2019
        2020

        ———-and this in the .js file
        var mafs = $(“#my-ajax-filter-search”);
        var mafsForm = mafs.find(“form”);
        var checkedyear = [];

        $(“.year:checkbox:checked”).each(function() {
        checkedyear.push($(this).val());
        });

        However I get the error:
        ReferenceError: year is not defined

        Do you know whey that is? Thanks.

        • A
          Al-Mamun Talukder

          ReferenceError: year is not defined
          This error is because you don’t have the class year on your form checkbox input.

        • If I change the following:
          var data = {
          action : “my_ajax_filter_search”,
          search : search,
          checkedyear : checkedyear,
          }
          I don’t get the reference error, but I get all of the posts rather than just the 2019 posts, for example.

          • A
            Al-Mamun Talukder

            You will need to add extra arguments to the WP_Query function
            if(isset($_GET['checkedyear'])) {
            $year = $_GET['checkedyear'];
            $meta_query[] = array(
            'key' => 'year', // This needs to be the ACF field key
            'value' => $year,
            'compare' => 'IN'
            );
            }

Leave your comment