Filter and Hooks, Programming, WordPress

jQuery ajax filtering posts with checkboxes

I think most of us are familiar with filtering posts based on categories using ajax. But, if you still want to check out the way to code for filtering the posts continue reading this article.

Let’s say, I have lists of categories in the checkbox and I want to filter posts based on the selected categories. I have three conditions for the categories filter :

  1.  I want to check the “All” checkbox by default and display all the posts accordingly.
  2.  If I check/select the filter other than “All”, the “All” checkbox should be unchecked & the posts of checked categories should be displayed
  3. If I check “All” categories, other selected categories should be unchecked

I begin…

Firstly, list all active categories associated with the posts

                 <div class="checkboxes-group">
                        <input type="checkbox" value="all" name="category[]"  class="js-filter-checkbox" id="all" />
                        <label for="all"><?php echo __('All','app')?></label>
                    </div>
   		<?php
                    $categories = get_categories( ['hide_empty'  => 1]);
                    foreach ($categories as $cat) {
                        ?>
                        <div class="checkboxes-group">
                            <input type="checkbox" value="<?=$cat->term_id?>" name="category[]" class="js-filter-checkbox" id="<?=$cat->term_id?>" />
                            <label for="<?=$cat->term_id?>"><?=$cat->name?></label>
                        </div>
                    <?php } ?>

Add jQuery that tricks the checkbox as per requirement…

function submitCategory() {
        var selectedCategories = [];
        var catInput ="" ;
        var filterCheckbox =   document.querySelectorAll(".js-filter-checkbox");
        if(filterCheckbox.length > 0 )  {
            [].forEach.call(filterCheckbox, function (item) {
                if (item.checked) selectedCategories.push(item.value);
            });
            if(selectedCategories.length > 0) {
                catInput = selectedCategories.join(",");
            }
        }
        var frmData = 'cat='+catInput+'&action=display_news_contents';
        var ajaxURL = "<?=admin_url('admin-ajax.php')?>";
        jQuery.ajax({
            url: ajaxURL,
            data: frmData,
            success: function(response){
                if (response.length > 0) {
                    jQuery(".js-posts-list").html(response);
                }
            }
        });
    }

In the above js code,
1. All the checkbox are selected using querySelectorAll

2. var count = document.querySelectorAll(‘.js-filter-checkbox:checked’).length, gives the number of checked categories.

3. If the checkbox is checked and among the checked categories there is no “All”, “All’ is unchecked

if(inputElement.checked && inputElement.value != 'all'){
    document.querySelector('.js-filter-checkbox[value="all"]').checked = false;
}

4. If one of the checked category is “All”,  all the other checked categories are unchecked

if(inputElement.checked && inputElement.value == 'all'){
    document.querySelectorAll('.js-filter-checkbox:not([value="all"])').forEach(function(item){
    item.checked = false;
  });
}

5. If none of the categories is checked, the “All’ category is checked
if(count == 0) document.querySelector(‘.js-filter-checkbox[value=”all”]’).checked = true;

On page load “All” categories are checked so that all the posts are displayed by default

jQuery( document ).ready(function() {
    jQuery('#all').prop('checked', true);
    submitCategory();
});

Ajax code is added to filter the posts based on checked categories

 function submitCategory() {
        var selectedCategories = [];
        var catInput ="" ;
        var filterCheckbox =   document.querySelectorAll(".js-filter-checkbox");
        if(filterCheckbox.length > 0 )  {
            [].forEach.call(filterCheckbox, function (item) {
                if (item.checked) selectedCategories.push(item.value);
            });
            if(selectedCategories.length > 0) {
                catInput = selectedCategories.join(",");
            }
        }
        var frmData = 'cat='+catInput+'&action=display_posts_contents';
        var ajaxURL = "<?=admin_url('admin-ajax.php')?>";
        jQuery.ajax({
            url: ajaxURL,
            data: frmData,
            success: function(response){
                if (response.length > 0) {
                    jQuery(".js-posts-list").html(response);
                }
            }
        });
    }

The hook that handles our ajax request is added on function.php  :

add_action( 'wp_ajax_display_posts_contents', 'display_posts_contents_callbck' );
add_action( 'wp_ajax_nopriv_display_posts_contents', 'display_posts_contents_callbck' );
function display_posts_contents_callbck() {
    extract($_GET);
    $args = ['post_type' => "post",'posts_per_page'=>-1, 'post_status'=>'publish'];
    if( !empty($_GET['cat']) &&  $_GET['cat']!="all") {
        $args['cat'] = $_GET['cat'];
    }
    $query = new WP_Query($args);
    if ($query->have_posts()) :
        while ($query->have_posts()) : $query->the_post();
            the_title("<h1>","</h1>");
        endwhile;
    endif;
    die();
}

Create a div with the class name ‘js-posts-list’ for holding and displaying the ajax responses.

<div class="js-posts-list"></div>

Finally, posts are filtered based on the selected categories.

Views: 5185

Standard

2 thoughts on “jQuery ajax filtering posts with checkboxes

Comments are closed.