skip to Main Content

I am doing filtering posts using ajax.

I wish $ array was different for pages "Products" and "Faq"

If this is executed within an ajax request, is_page() won’t be set. the page you’re making the request from was a previous request. you need to set something on the originating page to pass with your ajax request to let it know it’s for your special case page.

functions.php

function load_scripts() {
    
  wp_enqueue_script( 'ajax', get_template_directory_uri() . '/vendor/jquery/main.js', array( 'jquery' ), NULL, true );
  
  wp_localize_script( 'ajax', 'wp_ajax',
      array( 
          'ajax_url' => admin_url( 'admin-ajax.php' ),
          'is_page'  => is_page( 420 ), // Whatever you want to pass. Add as many key pairs as needed.
          )
  );
  
}
add_action( 'wp_enqueue_scripts', 'load_scripts');

add_action( 'wp_ajax_nopriv_filter', 'filter_ajax' );
add_action( 'wp_ajax_filter', 'filter_ajax' );


function filter_ajax() {
  
$category = $_POST['category'];

if(isset($_POST['is_page']) && $_POST['is_page'] === 'faq'){
      $cat__in = 10;
      print_r(  $_POST );
      echo "FAQ";

  } else{
    $cat__in = 4;
    print_r(  $_POST );
    echo "Products";
  }
  
$args = array(
'post_type' => 'post',
'posts_per_page' => 50,
'category__in' => $cat__in,
);

if(isset($category)) {

  $args['category__in'] = array($category);
}


      $query = new WP_Query($args);

      if($query->have_posts()) :
          while($query->have_posts()) : $query->the_post();
              the_title('<h2>', '</h2>');
              the_content('<p>', '</p>');
          endwhile;
      endif;
          wp_reset_postdata(); 
  die();
}

faq.php

<div class="js-filter">
    <?php
    $args = array(
    'post_type' => 'post',
    'posts_per_page' => 100,
    'child_of' => 10,
    'exclude' => array(1),
    );
    $query = new WP_Query(array( 'cat' => 10 ));

    if($query->have_posts()) :
        while($query->have_posts()) : $query->the_post();
            the_title('<h2>', '</h2>');
            the_content('<p>', '</p>');
        endwhile;
        endif;
    wp_reset_postdata(); ?>
</div>
<div class="categories">

<ul>
    <?php 
        $cat_args = array(
            'exclude' => array(1),
            'child_of' => 10
        );
        ?>

<?php 
global $post;
$category = reset(get_the_category($post->ID));
$category_id = $category->cat_ID;
?>

        <li class="js-filter-item"><a href="#">All</a></li>

        <?php $categories = get_categories($cat_args); foreach($categories as $cat) : ?>
        <li class="js-filter-item"><a data-category="<?= $cat->term_id; ?>" href="<?= get_category_link($cat->term_id); ?>"><?= $cat->name; ?></a></li>
    <?php endforeach; ?>
</ul>
</div>

products.php

<div class="js-filter">
    <?php
    $args = array(
    'post_type' => 'post',
    'posts_per_page' => 100,
    'child_of' => 6,
    'exclude' => array(1,10),
    );

    $query = new WP_Query(array( 'cat' => 6 ));

    if($query->have_posts()) :
        while($query->have_posts()) : $query->the_post();
            the_title('<h2>', '</h2>');
            the_content('<p>', '</p>');
        endwhile;
        endif;
    wp_reset_postdata(); ?>
</div>
<div class="categories">

<ul>
    <?php 
        $cat_args = array(
            'exclude' => array(1,10),
            'child_of' => 6
        );
        ?>

<?php 
global $post;
$category = reset(get_the_category($post->ID));
$category_id = $category->cat_ID;
?>

        <li class="js-filter-item"><a href="#">All</a></li>

        <?php $categories = get_categories($cat_args); foreach($categories as $cat) : ?>
        <li class="js-filter-item"><a data-category="<?= $cat->term_id; ?>" href="<?= get_category_link($cat->term_id); ?>"><?= $cat->name; ?></a></li>
    <?php endforeach; ?>
</ul>
</div>

main.js

 jQuery(function($){
    $(document).on('click', '.js-filter-item > a', function(e){
        e.preventDefault();

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

        $.ajax({
            url: wp_ajax.ajax_url,
            data: {
                action: 'filter',
                is_page: wp_ajax.is_page, // This param will be passed to your ajax function.
                category: category,
                pageslug: location.pathname.replace(///g,'')
            },
            type: 'post',
            success: function(result) {
                $('.js-filter').html(result);
            },
            error: function(result) {
                console.warn(result);
            }
        });
    });
});

do you have any idea how to solve it? After clicking on the "All" button, it displays posts from the "ID = 6" category

2

Answers


  1. is_page() is not supposed to work in wp_ajax_ functions.
    Check this answer: Why doesn’t is_page(id) work in functions.php?

    is_page() relies on a complete global $wp_query object. If you call it before the action template_redirect has been fired, it might be impossible to get that data.

    Instead of using is_page(), you can pass the slug as ajax data array value.

    To pass as slug, edit main.js to replace

    data: { action: 'filter', category: category },
    

    with

    data: { 
      action: 'filter', 
      category: category, 
      pageslug: location.pathname.replace(///g,'') 
    },
    

    Then, in functions.php in filter_ajax() function, replace

    if (is_page('faq'))
    

    with

    if(isset($_POST['pageslug']) && $_POST['pageslug'] === 'faq')
    
    Login or Signup to reply.
  2. You can pass your parameter by using the localize script feature. Since the page isn’t passed to your ajax function, you need to set your params in localize script, then pass to your ajax as part of the localized array.

    function load_scripts() {
        
        wp_enqueue_script( 'ajax', get_template_directory_uri() . '/vendor/jquery/main.js', array( 'jquery' ), NULL, true );
        
        wp_localize_script( 'ajax', 'wp_ajax',
            array( 
                'ajax_url' => admin_url( 'admin-ajax.php' ),
                'is_page'  => is_page( 420 ), // Whatever you want to pass. Add as many key pairs as needed.
                )
        );
        
    }
    add_action( 'wp_enqueue_scripts', 'load_scripts');
    

    In the case above, is_page is either true or false, and will pass to your javascript via the localized script. So in the JS file, wp_ajax.is_page will be either true or false (you can view this by inspecting your js object on the page. It should be a 0 or a 1.

    If you wanted to pass other objects, you can create as many items to your array and then pass to your js template.

    Your AJAX:

    jQuery(function($){
        $(document).on('click', '.js-filter-item > a', function(e){
            e.preventDefault();
    
            var category = $(this).data('category');
    
            $.ajax({
                url: wp_ajax.ajax_url,
                data: {
                    action: 'filter',
                    is_page: wp_ajax.is_page, // This param will be passed to your ajax function.
                    category: category,
                    pageslug: location.pathname.replace(///g,'')
                },
                type: 'post',
                success: function(result) {
                    $('.js-filter').html(result);
                },
                error: function(result) {
                    console.warn(result);
                }
            });
        });
    });
    

    Then in your updated php ajax action.

    function filter_ajax() {
        
        $category = $_POST['category'];
        // If it's page 420... then $_POST['is_page'] will equal a string 1.
        if ( isset( $_POST['is_page'] ) && $_POST['is_page'] === '1' ) {
            $cat__in = 10;
            print_r( $_POST );
            echo "FAQ";
            
        } else {
            $cat__in = 4;
            print_r( $_POST );
            echo "Products";
        }
        // .... rest of function
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search