Get posts with Ajax posts filter with multi select

2019-02-19 16:57发布

问题:

I am trying to achieve an ajax post filter with a form which use muti-selection checkboxes. I have shortened the form with only 3 groups of 4 checkboxes each (instead of 11 groups).

Here my filter have 3 groups (master keys) which are brand, ram and price, and every group have 4 different key / values (checkboxes). Each checkbox in the group can be checked (multi-selection)

Here is the live link for this project, and if you check with your browser console tools, you will see that the data is correctly sent by jQuery and received by my php function.

This is working:
The HTML file with all the checkboxes is working fine with my ajax jQuery script and it sends correctly an array of key/values to my php function. I have correctly registered my jQuery script and used as well as

The array of data received (for 2 checked checkboxes for example of the same group):

$choices = array( 'brand1' => 'Nokia', 'brand3' => 'Sony' );**`wp_localize_script()`**…

What is not working yet:
- Prepare the data for the WP_query()
- The query herself $args array

How to manage call_post() function, after that it get value from JS and disply posts using loop??**

The PHP code in function.php:

add_action('wp_ajax_call_post', 'call_post');
add_action('wp_ajax_nopriv_call_post', 'call_post');
function call_post(){

$choices = $_POST['choices'];
print_r($_POST['choices']);
foreach($choices as $name => $choice)
    $fam = explode('-', $name);
    $family = $fam[0];       
}

$args = array(
    'post_type' => 'post',
        array(
            'key' => 'brand',
            'value' => $brand,
        ) ,
         array(
            'key' => 'ram',
            'value' => $ram,
        ) ,
         array(
            'key' => 'price',
            'value' => $price,
    ) ,
);

$query = new WP_Query($args);
    if( $query->have_posts() ) :
        while( $query->have_posts() ): $query->the_post();
          echo file_get_contents(locate_template("content.php"));
        endwhile;
        wp_reset_query();
    else :
        wp_send_json($query->posts);
    endif;
 die();
}

Script

jQuery(document).ready(function($){
    $('#phones-filter .br').click(function(){

        var choices = {}; // declaring an empty array
        var choice = $(this).attr('name');
        $('.contents').remove();
        $('.filter-output').empty();

        // scanning each checkbox for checked state data
        $('div > li > .br').each(function(index, obj) {
            if($(this).prop('checked')){
                var name = $(this).attr('name'), val = $(this).val();
                choices[name] = val;
            }
        });

        $.ajax({
            url: ajaxobject.ajaxurl,
            type :'POST',
            data : {
                'action' : 'call_post',
                'choices' : choices,
            },
            success: function (result) {
                $(choice).appendTo('.filter-output');
                console.log(result);
                console.log(choices);
            },
            error: function(err){
                console.log(err);
                console.log(choices);
            }
        });
    })
});

Form.php (shortened)

<form  id="phones-filter" >
<div class="brand">
        <li><input type="checkbox" name="brand-1" value="Nokia" class="br"> NOKIA </li>
        <li><input type="checkbox" name="brand-2" value="LG" class="br"> LG </li>
        <li><input type="checkbox" name="brand-3" value="Sony" class="br"> Sony </li>
        <li><input type="checkbox" name="brand-4" value="Apple" class="br"> Apple </li>
</div>
<div class="ram">
        <li> <input type="checkbox" name="ram-1" value="1GB" class="br"> 1 GB  </li>
         <li><input type="checkbox" name="ram-2" value="2GB" class="br"> 1 GB  </li>
         <li><input type="checkbox" name="ram-3" value="3GB" class="br"> 2 GB  </li>
         <li><input type="checkbox" name="ram-3" value="4GB" class="br"> 4 GB    </li>
</div>
<div class="price">
        <li><input type="checkbox" name="price-1" value="$100" class="br"> $100 </li>
        <li><input type="checkbox" name="price-2" value="$200" class="br"> $200 </li>
        <li><input type="checkbox" name="price-3" value="$300" class="br"> $300 </li>
        <li><input type="checkbox" name="price-4" value="$500" class="br"> $400 </li>
</div>
<div class="filter-output"></div>
</form>

content.php

    <div <?php post_class( 'col-lg-2 col-md-2 col-sm-3 col-xs-6 ' ); ?> id="post-<?php the_ID(); ?>">
    <div class="single-post"> 

               <div class="post-thumb" > 
                        <a href="<?php echo esc_url( post_permalink() ); ?>">
                            <?php the_post_thumbnail  ( 'large', array(
                                    'class' => 'img-responsive' 
                            ) ); ?> 
                            </a>
                </div>  

        <div class="post-info">     
            <div class="post-title"><li><a href="<?php echo esc_url( post_permalink() ); ?>"><?php the_title(); ?></a></li></div>                    
            <div class="rs"><p><?php echo get_post_meta( get_the_ID(), 'price', true ); ?><?php _e( '', 'mobilewebsite' ); ?></p></div>         
        </div> 

    </div>                                 
</div>
<?php $item_number++;
 if( $item_number % 2 == 0 ) echo '<div class="clearfix visible-xs-block"></div>';
 if( $item_number % 4 == 0 ) echo '<div class="clearfix visible-sm-block"></div>';
 if( $item_number % 6 == 0 ) echo '<div class="clearfix visible-md-block"></div>'; 
 if( $item_number % 6 == 0 ) echo '<div class="clearfix visible-md-block"></div>'; 
 ?>

回答1:

Try with below code

<form  id='test' >
    <strong>Brand</strong>
    <div class="brand">
            <li><input type="checkbox" name="brand" value="Nokia" class="br"> NOKIA </li>
            <li><input type="checkbox" name="brand" value="LG" class="br"> LG </li>
            <li><input type="checkbox" name="brand" value="Sony" class="br"> Sony </li>
            <li><input type="checkbox" name="brand" value="Apple" class="br"> Apple </li>
    </div>
    <strong>Ram</strong>
    <div class="ram">
            <li> <input type="checkbox" name="ram" value="1GB" class="br"> 1 GB  </li>
             <li><input type="checkbox" name="ram" value="2GB" class="br"> 1 GB  </li>
             <li><input type="checkbox" name="ram" value="3GB" class="br"> 2 GB  </li>
             <li><input type="checkbox" name="ram" value="4GB" class="br"> 4 GB    </li>
    </div>
    <strong>Price</strong>
    <div class="price">
            <li><input type="checkbox" name="price" value="$100" class="br"> $100 </li>
            <li><input type="checkbox" name="price" value="$200" class="br"> $200 </li>
            <li><input type="checkbox" name="price" value="$300" class="br"> $300 </li>
            <li><input type="checkbox" name="price" value="$500" class="br"> $400 </li>
    </div>
</form>




    jQuery(document).ready(function($){
        $('#test .br').click(function(){

            // declaring an array
            var choices = {};

            $('.contents').remove();
            $('.filter-output').empty()

            $('input[type=checkbox]:checked').each(function() {
                if (!choices.hasOwnProperty(this.name)) 
                    choices[this.name] = [this.value];
                else 
                    choices[this.name].push(this.value);
            });


            console.log(choices);
            $.ajax({
                url: ajaxobject.ajaxurl,
                type :'POST',
                data : {
                    'action' : 'call_post', // the php name function
                    'choices' : choices,
                },
                success: function (result) {
                    $('.filter-output').append(result);
                    // just for test - success (you can remove it later)
                    //console.log(result);
                    //console.log(choices);
                },
                error: function(err){
                    // just for test - error (you can remove it later)
                    console.log(err);
                    console.log(choices);
                }
            });
        })
    });




add_action('wp_ajax_call_post', 'call_post');
add_action('wp_ajax_nopriv_call_post', 'call_post');

function call_post(){

    // Getting the ajax data:
    // An array of keys("name")/values of each "checked" checkbox
    $choices = $_POST['choices'];

    $meta_query = array('relation' => 'OR');
    foreach($choices as $Key=>$Value){

        if(count($Value)){
            foreach ($Value as $Inkey => $Invalue) {
                $meta_query[] = array( 'key' => $Key, 'value' => $Invalue, 'compare' => '=' );
            }
        }
    }
    $args = array(
        'post_type' => 'post',
        'meta_query' =>$meta_query
    );

    $query = new WP_Query($args);
     //if( ! empty ($params['template'])) {
         ////$template = $params['template'];
         if( $query->have_posts() ) :
             while( $query->have_posts() ): $query->the_post();
                 get_template_part('content');
             endwhile;
             wp_reset_query();
         else :
             wp_send_json($query->posts);
         endif;
     //}

    die();
}