3

I am trying to achieve an ajax post filter with a form which use muti-selection through groups of checkboxes.

This filter have 5 groups (master keys) which are brand, ram, camera, price and feature. Every group have between 4 and 5 different key / value (checkboxes).

For the moment, this works in mono-selection mode only: If I chose 2 checkboxes of the same group, nothing is displayed…

How can I enable multi-selection for this groups of checkboxes?

Here is the php function that make the Ajax query:

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

function call_post(){

$choices = $_POST['choices'];

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

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

$query = new WP_Query($args);
     if( $query->have_posts() ) :
         while( $query->have_posts() ): $query->the_post();
             get_template_part('content');
         endwhile;
         wp_reset_query();
     else :
  _e('Sorry, no posts matched your criteria.');
         wp_send_json($query->posts);
     endif;
die();
}
?>

Here are the html form and the javascript, that are used in this thread:
Get posts with Ajax posts filter with multi selection checkboxes

Thanks

1 Answer 1

1

To achieve this you need:

  • to group actions data by groups (selected checkboxes)
  • to include in each group of arrays a 'relation' => 'OR' (only if the group has more than one check-box selected)

Your php function will be like this:

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

function call_post(){

    $choices = $_POST['choices'];

    // Defining here your fields groups
    $groups = array('brand', 'ram', 'camera', 'price', 'feature');

    // Grouping data by group
    foreach($choices as $Key => $Value){
        foreach ($Value as $Inkey => $Invalue) {
            switch ($Key) {

                // One block for each group defined in $groups array

                case $groups[0]:
                    $grp[0][] = array( 'key' => $Key, 'value' => $Invalue, 'compare' => 'like' );
                    break;

                case $groups[1]:
                    $grp[1][] = array( 'key' => $Key, 'value' => $Invalue, 'compare' => 'like' );
                    break;

                case $groups[2]:
                    $grp[2][] = array( 'key' => $Key, 'value' => $Invalue, 'compare' => 'like' );;
                    break;

                case $groups[3]:
                    $grp[3][] = array( 'key' => $Key, 'value' => $Invalue, 'compare' => 'like' );
                    break;

                case $groups[4]:
                    $grp[4][] = array( 'key' => $Key, 'value' => $Invalue, 'compare' => 'like' );
                    break;
            }
        }
    }

    $grp_arr = array();

    // Adding ('relation' => 'OR') to each group with a length > 1
    foreach ($grp as $key_grp => $grp_values) {
        if(count($grp_values) > 1){
            $grp_arr[$key_grp] = array('relation' => 'OR');
        }
        foreach ($grp_values as $grp_val) {
            $grp_arr[$key_grp][] = $grp_val;
        }
    }
    
    // Compiling it all
    $meta_query = array('relation' => 'AND');
    foreach ($grp_arr as $grp_arr_val) {
        $meta_query[] = $grp_arr_val;
    }

    // The query (compiled)
    $query = new WP_Query( array(
        'post_type'     => 'post',
        'meta_query'    => $meta_query
    ) );

    // The Loop
    if( $query->have_posts() ) :
        while( $query->have_posts() ): $query->the_post();
            get_template_part('content');
        endwhile;
        wp_reset_query();!
    else :
        _e('Sorry, no posts matched your criteria.');
        wp_send_json($query->posts);
    endif;

    die();
}

So you will get this kind of formatted array:

$query = array(
    'post_type'    => 'product',
    'meta_query'   => array(
        'relation' => 'AND',
        array(
            'relation' => 'OR',
            array(
                'key'     => 'brand',
                'value'   => 'Nokia',
                'compare' => 'like',
            ),
            array(
                'key'     => 'brand',
                'value'   => 'LG',
                'compare' => 'like',
            ),
        ),
        array(
            'relation' => 'OR',
            array(
                'key'     => 'ram',
                'value'   => '1GB',
                'compare' => 'like',
            ),
            array(
                'key'     => 'ram',
                'value'   => '2GB',
                'compare' => 'like',
            ),
        ),
    ),
);

So This should work as expected, to enable multi-selection by group of checkboxes…

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.