admin管理员组

文章数量:1435859

Trying to get a dynamic filter working which will filter a custom post type by custom taxonomies on click of a button. Was getting an error of ajax_url is undefined but I think I have solved that part... however I am now left with something that still doesn't work but no errors! I would like all products to show by default and then to filter them by application and analyser on click This is in my functions.php file :

    function ajax_filter_tests_scripts() {
    wp_enqueue_script( 'ajax_filter_tests', get_stylesheet_directory_uri(). '/src/js/components/_filter.js', array(), '1.0', true  );
    wp_localize_script('ajax_filter_tests', 'ajax_url', admin_url('admin-ajax.php') );
}

function ajax_filter_tests_shortcode() {
    ajax_filter_tests_scripts();
    ob_start(); ?>
    <a href="#"><i class="fas fa-th"></i> All Products</a>
    <?php
        global $post;
        $applications = wp_get_post_terms( $post->ID, 'applications' );
        $thisAnalyser = get_field('select_analyser_for_test_filter');
        foreach ( $applications as $application):
            $tests = new WP_Query(
                array(
                    'post_type' => 'tests',
                    'tax_query' => array(
                        array(
                            'taxonomy' => 'applications',
                            'terms' => array($application->slug),
                            'field' => 'slug'
                        ),
                    ),
                )
            );
     ?>
     <a href="#"><?php echo $application->name; ?></a>
     <?php
        $tests = null;
        wp_reset_postdata();
    endforeach;
    ?>
    <?php
    return ob_get_clean();
}

add_shortcode('ajax_filter_tests', 'ajax_filter_tests_shortcode');

//Ajax Callback

add_action('wp_ajax_ajax_filter_tests', 'ajax_filter_tests_callback');
add_action('wp_ajax_nopriv_ajax_filter_tests', 'ajax_filter_tests_callback');

function ajax_filter_tests_callback() {

    header("Content-Type: application/json");

    $thisAnalyser = get_field('select_analyser_for_test_filter');
    $tax_query = array('relation' => 'AND');

    if(isset($_GET['application'])) {
        $application = sanitize_text_field( $_GET['application'] );
        $tax_query[] = array(
            'taxonomy' => 'applications',
            'field' => 'slug',
            'terms' => $application
        );
    }

    if(isset($thisAnalyser)) {
        $analyser = $thisAnalyser;
        $tax_query[] = array(
            'taxonomy' => 'analyser',
            'field' => 'slug',
            'terms' => $analyser
        );
    }

    $args = array(
        'post_type' => 'tests',
        'posts_per_page' => -1,
        'tax_query' => $tax_query
    );

    $test_query = new WP_Query( $args );

    if( $test_query->have_posts() ) {
        $result = array();

        while ( $test_query->have_posts() ) {
            $test_query->the_post();

            $result[] = array(
                "id" => get_the_ID(),
                "title" => get_field('test_title'),
                "subtitle" => get_field('test_subtitle'),
                "image" => get_field('test_image'),
                "permalink" => the_permalink()
            );
        }
        wp_reset_query();

        echo json_encode($result);

    }
    wp_die();

}

And the following in my _filter.js file:

    $ = jQuery;

var aft = $("#ajax-filter-tests");
var aftLinks = aft.find('a');

aftLinks.click(function(e) {
    e.preventDefault();

    var application = $(e.target).text();
    var application_slug = application.replace(/\s+/g, '_').toLowerCase();
    console.log(application_slug);

    var data = {
        action : "ajax_filter_tests",
        application : application_slug
    }

    $.ajax({
        url : ajax_url,
        data : data,
        success : function(response) {
            aft.find('#filterResults').empty();
            if(response) {
                for(var i = 0; i < response.length; i++) {
                    var html = "<div class='test-filters__results__holder'>";
                        html += "   <div class='test__holder__image'>";
                        html += "       <img src='" + response[i].image + "' alt='" + response[i].title + "' />";
                        html += "   </div>";
                        html += "   <div class='test__holder__text'>";
                        html += "       <h4>" + response[i].title + "</h4>";
                        html += "       <h5>" + response[i].subtitle + "</h5>";
                        html += "       <a href='" + response[i].permalink + "'>Learn More</a>";
                        html += "   </div>";
                        html += "</div>";
                    aft.find('.test-filters__results .row').append(html);
                }
            } else {
                var html = "<div>Sorry, there are no suitable tests here.</div>";
                aft.find('#filterResults').append(html);
            }
        }
    });
});

in case I haven't explained what I am actually trying to do very well here is an image of the finished product

Trying to get a dynamic filter working which will filter a custom post type by custom taxonomies on click of a button. Was getting an error of ajax_url is undefined but I think I have solved that part... however I am now left with something that still doesn't work but no errors! I would like all products to show by default and then to filter them by application and analyser on click This is in my functions.php file :

    function ajax_filter_tests_scripts() {
    wp_enqueue_script( 'ajax_filter_tests', get_stylesheet_directory_uri(). '/src/js/components/_filter.js', array(), '1.0', true  );
    wp_localize_script('ajax_filter_tests', 'ajax_url', admin_url('admin-ajax.php') );
}

function ajax_filter_tests_shortcode() {
    ajax_filter_tests_scripts();
    ob_start(); ?>
    <a href="#"><i class="fas fa-th"></i> All Products</a>
    <?php
        global $post;
        $applications = wp_get_post_terms( $post->ID, 'applications' );
        $thisAnalyser = get_field('select_analyser_for_test_filter');
        foreach ( $applications as $application):
            $tests = new WP_Query(
                array(
                    'post_type' => 'tests',
                    'tax_query' => array(
                        array(
                            'taxonomy' => 'applications',
                            'terms' => array($application->slug),
                            'field' => 'slug'
                        ),
                    ),
                )
            );
     ?>
     <a href="#"><?php echo $application->name; ?></a>
     <?php
        $tests = null;
        wp_reset_postdata();
    endforeach;
    ?>
    <?php
    return ob_get_clean();
}

add_shortcode('ajax_filter_tests', 'ajax_filter_tests_shortcode');

//Ajax Callback

add_action('wp_ajax_ajax_filter_tests', 'ajax_filter_tests_callback');
add_action('wp_ajax_nopriv_ajax_filter_tests', 'ajax_filter_tests_callback');

function ajax_filter_tests_callback() {

    header("Content-Type: application/json");

    $thisAnalyser = get_field('select_analyser_for_test_filter');
    $tax_query = array('relation' => 'AND');

    if(isset($_GET['application'])) {
        $application = sanitize_text_field( $_GET['application'] );
        $tax_query[] = array(
            'taxonomy' => 'applications',
            'field' => 'slug',
            'terms' => $application
        );
    }

    if(isset($thisAnalyser)) {
        $analyser = $thisAnalyser;
        $tax_query[] = array(
            'taxonomy' => 'analyser',
            'field' => 'slug',
            'terms' => $analyser
        );
    }

    $args = array(
        'post_type' => 'tests',
        'posts_per_page' => -1,
        'tax_query' => $tax_query
    );

    $test_query = new WP_Query( $args );

    if( $test_query->have_posts() ) {
        $result = array();

        while ( $test_query->have_posts() ) {
            $test_query->the_post();

            $result[] = array(
                "id" => get_the_ID(),
                "title" => get_field('test_title'),
                "subtitle" => get_field('test_subtitle'),
                "image" => get_field('test_image'),
                "permalink" => the_permalink()
            );
        }
        wp_reset_query();

        echo json_encode($result);

    }
    wp_die();

}

And the following in my _filter.js file:

    $ = jQuery;

var aft = $("#ajax-filter-tests");
var aftLinks = aft.find('a');

aftLinks.click(function(e) {
    e.preventDefault();

    var application = $(e.target).text();
    var application_slug = application.replace(/\s+/g, '_').toLowerCase();
    console.log(application_slug);

    var data = {
        action : "ajax_filter_tests",
        application : application_slug
    }

    $.ajax({
        url : ajax_url,
        data : data,
        success : function(response) {
            aft.find('#filterResults').empty();
            if(response) {
                for(var i = 0; i < response.length; i++) {
                    var html = "<div class='test-filters__results__holder'>";
                        html += "   <div class='test__holder__image'>";
                        html += "       <img src='" + response[i].image + "' alt='" + response[i].title + "' />";
                        html += "   </div>";
                        html += "   <div class='test__holder__text'>";
                        html += "       <h4>" + response[i].title + "</h4>";
                        html += "       <h5>" + response[i].subtitle + "</h5>";
                        html += "       <a href='" + response[i].permalink + "'>Learn More</a>";
                        html += "   </div>";
                        html += "</div>";
                    aft.find('.test-filters__results .row').append(html);
                }
            } else {
                var html = "<div>Sorry, there are no suitable tests here.</div>";
                aft.find('#filterResults').append(html);
            }
        }
    });
});

in case I haven't explained what I am actually trying to do very well here is an image of the finished product

Share Improve this question asked Mar 26, 2019 at 14:40 Jaimee PageJaimee Page 761 silver badge6 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

I cannot test everything since there are some dependencies on certain markup and functionality, but here's what I found so far.

Wrap your script in the following instead of $ = jQuery;. This is a better way to handle possible conflicts.

(function($){
    // your code here
})(jQuery);

While the way you're enqueuing scripts works, it may be better to register them ahead of time and enqueue them in the shortcode. You also want to set jQuery as a dependency of ajax_filter_tests. Something like this:

function ajax_filter_tests_scripts() {
    wp_register_script( 'ajax_filter_tests', get_stylesheet_directory_uri() . '/src/js/components/_filter.js', array('jquery'), '1.0', true );
    wp_localize_script( 'ajax_filter_tests', 'ajax_url', admin_url( 'admin-ajax.php' ) );
}
add_action('wp_enqueue_scripts', 'ajax_filter_tests_scripts');

function ajax_filter_tests_shortcode() {
    wp_enqueue_script( 'ajax_filter_tests' );
    // ...the rest of your code
}

You also want to check to make sure you're calling $.ajax correctly according to the version of jQuery you're using. From the documentation:

Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHRplete() callbacks are removed as of jQuery 3.0. You can use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.

var jqxhr = $.ajax({
    url : ajax_url,
    data : data
}).done(function() {
    alert( "success" );
}).fail(function() {
    alert( "error" );
}).always(function() {
    alert( "complete" );
});

This will make sure your script is always firing no matter what the ajax response might be. There may be other issues here, for example using the_permalink() instead of get_permalink(), but this will give you a good start.

Last thing, the issue might be with php instead of javascript. Make sure you turn on debug and check to make sure you're not getting errors with the rest of your code.

本文标签: No errors in the console but Ajax call doesn39t seem to be working