1

I have code that list categories and products by category.

When I click "All" it list all products, but when I go /products page it's not list all products by default and I need to click "All" to get all products. How I can get all products when I go /products page by default without click any category or All -link?

My functions.php

function add_custom_scripts() {
wp_enqueue_script( 'ajax_term', get_stylesheet_directory_uri() . '/ajax/ajax-terms.js', array('jquery'), NULL, true );
wp_localize_script( 'ajax_term', 'wpAjax', array('ajaxUrl' => admin_url('admin-ajax.php')));    
}
add_action( 'wp_enqueue_scripts', 'add_custom_scripts' );

Products.php - /products page

<div class="categories">
<ul class="categories-filter" name="categoryfilter">
    <li><a type="button" data-posttype="product" class="js-filter-item" href="<?php echo home_url(); ?>">All</a></li>
    <?php
    if( $terms = get_terms( array( 
        'taxonomy' => 'product_cat' ) ) ) : 

        foreach ( $terms as $term ) :
        
         ?>
        <li>
            <a type="button" data-category="<?php echo $term->term_id; ?>" 
                data-posttype="product" 
                    data-taxonomy="<?php echo $term->taxonomy; ?>" class="js-filter-item" href="<?php echo $term->term_id; ?>" >
                <?php echo $term->name; ?>
        </a>
        </li>
    <?php 
          endforeach; 
          endif; 
    ?>
</ul>
</div>

<div id="response"></div>

Ajax-terms.js

(function($){

$(document).ready(function(){
    $(document).on('click', '.js-filter-item', function(event){
        (event).preventDefault();

        var category = $(this).data('category');

        $.ajax({
            url: wpAjax.ajaxUrl,
            data: { 
                action: 'filterterm', 
                category: category, 
                taxonomy:  $(this).data('taxonomy'),
                posttype:  $(this).data('posttype')
                },
            type: 'post',
            success: function(result){
                $('#response').html(result);
            },
            error: function(result){
                console.warn(result);
            }
        });
    });
});
})(jQuery);

Callback in functions.php

<?php

add_action('wp_ajax_nopriv_filterterm', 'filter_ajax_term');
add_action('wp_ajax_filterterm', 'filter_ajax_term');

function filter_ajax_term(){

$category = $_POST['category'];

 $args = array(
    'post_type' => 'product', 
    'posts_per_page' => -1, 
    'orderby'   => 'NAME', 
    'order' => 'ASC'
 );

 if(isset($category)) {
    $args['tax_query'] = 
    array( 
        array( 
                'taxonomy' => $_POST['taxonomy'], //or tag or custom taxonomy
                'field' => 'id', 
                'terms' => array((int)$category) 
            ) 
    ); 

}
 
$the_query = new WP_Query( $args ); ?>

    <div class="container">

        <?php if ( $the_query->have_posts() ) : 
            while ( $the_query->have_posts() ) : $the_query->the_post(); 
            
            $category = get_the_category(); 

            the_title('<h2>', '</h2>');
    
        endwhile; endif; ?>

    </div>

<?php

die();
}
?>

1 Answer 1

0

First, you should use the REST API for frontend instead of admin-ajax.
Second, you should not use unfiltered POST values.
And for your products on page load, you should tell your Javascript to fill the ID "response", when the ID is present.
Now, you only load products, when the click event on the class js-filter-item happens.
Try it with a helper function like this.

(function($){$(document).ready(function(){

if ($('#response').length){

  function load_all_products() {
    var category = $(this).data('category');

    $.ajax({
        url: wpAjax.ajaxUrl,
        data: { 
            action: 'filterterm', 
            category: category, 
            taxonomy:  $(this).data('taxonomy'),
            posttype:  $(this).data('posttype')
            },
        type: 'post',
        success: function(result){
            $('#response').html(result);
        },
        error: function(result){
            console.warn(result);
        }
    });
  }

  load_all_products();

  $('.js-filter-item').on('click', function(event){
      (event).preventDefault();
      load_all_products();
  });
}

}); })(jQuery);

This is untestet and will not work by copy and paste, but maybe you get the idea. When the ID "response" is present, call the function load_all_products().
When you click on a filter with the class "js-filter-item", call this function with selected button/filter/whatever.
You may have to change the $(this).data(xxx) calls to correct values.
For pagination you have to add page variable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.