Jump to content

How to sort post by meta values in WordPress using a Select and Ajax


Kirasiris

Recommended Posts

FIRST OF ALL , THIS POST IS GOING TO BE LONG. Thanks for helping.

Hello I'm trying to build an "really" advanced search page for my WordPress template.

So far I have created the my page with the following code:

<?php 
/*
Template Name: Direcotorio
Template Post Type: page
*/
?>
<?php get_header(); ?>
	<div class="container">
    	<div class="row">
        	

<div id="my-adv-search">
<!-- Post Type -->
<div class="col-md-3">
    <div class="form-group">
        <label for="q_post_type">Tipo</label>
        <select class="form-control" id="q_post_type">
            <option selected>Selecciona una opcion</option>
            <?php
			$args = array(
				'public'	=> true,
				'_builtin' => false,
			);
			$post_types = get_post_types($args);
				foreach( $post_types as $post_type ) {
					echo '<option>' . $post_type . '</option>' ;	
				}
			?>
        </select>
    </div>
</div>

<!-- Genero -->
<div class="col-md-3">
    <div class="form-group">
        <label for="q_taxonomy">Genero</label>
        <select class="form-control" multiple id="q_taxonomy">
            <option value="any" selected>Selecciona una opcion</option>
			<?php 
            $args = array(
              'public'   => true,
              '_builtin' => false
            ); 
            $output = 'names'; // or objects
            $operator = 'and'; // 'and' or 'or'
            $taxonomies = get_taxonomies( $args, $output, $operator ); 
            if ( $taxonomies ) {
              foreach ( $taxonomies  as $taxonomy ) {
                echo '<option>' . $taxonomy . '</option>';
              }
            }
            ?>
        </select>
    </div>
</div>

<!-- Estado -->
<div class="col-md-3">
    <div class="form-group">
        <label for="q_orderby">Estado</label>
        <select class="form-control" id="q_orderby">
            <option value="any" selected>Selecciona una opcion</option>
            <?php
            foreach ( [
            //  'author'        => 'Author',
            //  'comment_count' => 'Popularity (# of Comments)',
            //  'year'          => 'Year',
              'en_emision'   => 'Emision',
              'en_final'   => 'Finalizado',
              //'order'         => 'ASC ? DESC',
            ] as $value => $label ) {
              printf( '<option value="%s">%s</option>',
                esc_attr( $value ), esc_html( $label ) );
            }
            ?>
        </select>
    </div>
</div>


<!-- Year -->
<div class="col-md-3">
    <div class="form-group">
        <label for="q_year">Año</label>
        <select class="form-control" id="q_year">
            <option value="any" selected>Selecciona una opcion</option>
            <?php
			$args = array(
				'public'	=> true,
				'_builtin'	=> false,
				'type'		=> 'yearly',
				'format'	=> 'option',
			);
			wp_get_archives($args);
			?>
        </select>
    </div>
    
</div>


<!-- Nonce field. -->
<?php wp_nonce_field( 'my-adv-search', 'q_nonce' ); ?>

<!-- Search Button -->
<div class="col-md-12">
    <input type="submit" class="btn btn-success" id="buscar_btn" value="Search">
    <br><br>
    <noscript><b>Tu buscador no soporta Javascript, haciendo imposible mostrar los posts.</b></noscript>
    <div id="resultados"><div class="cargando_medio"></div></div>
</div>
</div><!-- End #my-adv-search -->



        </div>
    </div>

<?php get_footer(); ?>
<script type="text/javascript">
jQuery( function( $ ){
    var ajaxurl = '/wptests/wp-admin/admin-ajax.php';

    function searchPosts( btn ) {
        var _btn_text = btn.value;//, q_order;

        btn.disabled = true;
        btn.value = 'Searching..';

//        q_order = $( '#q_order-asc' ).is( ':checked' ) ?
//            'ASC' : 'DESC';

        return $.post( ajaxurl, {
            action: 'my_adv_search',
            q_nonce: $( '#q_nonce' ).val(),
            q_post_type: $( '#q_post_type' ).val(),
            q_taxonomy: $( '#q_taxonomy' ).val(),
            q_year: $( '#q_year' ).val(),
            q_orderby: $( '#q_orderby' ).val(),
//            q_order: q_order,
        } ).done( function( s ){
            if ( 'session_expired' === s ) {
                location.reload();
                return;
            }

            $( '#resultados' ).html( s );
        } ).always( function(){
            btn.value = _btn_text;
            btn.disabled = false;
        } );
    }

    $( '#buscar_btn', '#my-adv-search' ).on( 'click', function( e ){
        e.preventDefault();

        // Run AJAX search.
        searchPosts( this );

        // Remove button focus.
        this.blur();
    } );
} );
</script>

 

Now I already have a function that works pretty well. I only need to make some changes on it but I have been unable to figure out why isn't working(as you will see there are few comments which I have made on it).

I'm trying to display the posts by two meta values that comes from a custom field called "estado_de_video" and the two meta values from it are "en_emision and en_final". I pretty much I have everything done but I just don't know why is not working.

Can somebody help me, please?

Quote

 

NOTE(NOT NECESSARY) : If somebody can help me to modify the custom post type and taxonomy selects with Ajax to make it look like this.

<select> for post types : animes, peliculas

<select> for taxonomy: load taxonomies() from selected post type

Depending on what post type is selected make it appear taxonomy not hierarchical or hierarchical.

 

Thanks in advanced.
 

add_action( 'wp_ajax_my_adv_search', 'ajax_my_adv_search' );
add_action( 'wp_ajax_nopriv_my_adv_search', 'ajax_my_adv_search' );
function ajax_my_adv_search() {
    if ( ! check_ajax_referer( 'my-adv-search', 'q_nonce', false ) ) {
        echo 'session_expired';
        wp_die();
    }

    $post_type = isset( $_POST['q_post_type'] ) ? $_POST['q_post_type'] : '';
    $taxonomy = isset( $_POST['q_taxonomy'] ) ? $_POST['q_taxonomy'] : [];
    $year = isset( $_POST['q_year'] ) ? $_POST['q_year'] : '';
    $orderby = isset( $_POST['q_orderby'] ) ? $_POST['q_orderby'] : [];
    $order = isset( $_POST['q_order'] ) ? $_POST['q_order'] : '';


    // Note that if $post_type is 'any', all post statuses will be included. In
    // that case, you may want to set specific post statuses below.
    $post_status = 'publish';

    // by Taxonomy
    $taxonomy = array_filter( (array) $taxonomy );
    if ( ! in_array( 'any', $taxonomy ) ) {
        $taxonomy = array_unique( array_map( 'trim', $taxonomy ) );

        add_filter( 'posts_join', function( $c ) use ( $taxonomy ) {
            if ( ! empty( $taxonomy ) ) {
                global $wpdb;
                // 1 below is one/number and not the lowercase of L
                $c .= " INNER JOIN {$wpdb->term_relationships} AS ctr1 ON ctr1.object_id = {$wpdb->posts}.ID" .
                    " INNER JOIN {$wpdb->term_taxonomy} AS ctt1 ON ctt1.term_taxonomy_id = ctr1.term_taxonomy_id";
            }
            return $c;
        } );

        add_filter( 'posts_where', function( $c ) use ( $taxonomy ) {
            if ( ! empty( $taxonomy ) ) {
                $tax_list = array_map( 'esc_sql', $taxonomy );
                $tax_list = "'" . implode( "', '", $tax_list ) . "'";

                // 1 below is one/number and not the lowercase of L
                $c .= " AND ( ctt1.taxonomy IN ($tax_list) )";
            }
            return $c;
        } );
    }

    // by Custom Field Value - Metadata
    $orderby = array_filter( (array) $orderby );
    if ( in_array( 'any', $orderby ) ) {
        // Don't sort by post date.
        $orderby2 = false;
    } else {
        $orderby = array_unique( array_map( 'trim', $orderby ) );

        // TRUE if we're sorting by year.
        $ob_year = false;

        foreach ( $orderby as $i => $s ) {
            // Sort posts by year.
            if ( 'year' === $s ) {
                $ob_year = true;
                unset( $orderby[ $i ] );
            }
//// HERE BEGINS
            // Sort posts by meta value en_emision from meta key estado_de_video. Note that this would only return
            // posts that have the custom field 'en_emision'.
            if ( 'en_emision' === $s ) {
                $meta_key = 'en_emision';
                $orderby2 = 'meta_value';
                unset( $orderby[ $i ] );
            }

            // Sort posts by meta value en_final from meta key estado_de_video. Note that this would only return
            // posts that have the custom field 'en_final'.
            if ( 'en_final' === $s ) {
                $meta_key = 'en_final';
                $orderby2 = 'meta_value';
                unset( $orderby[ $i ] );
            }

//// HERE ENDS
        }

        add_filter( 'posts_orderby', function( $c, $q ) use ( $ob_year ) {
            if ( $ob_year ) {
                global $wpdb;

                // Use the value parsed by WP_Query.
                $order = $q->get( 'order' );

                $c .= $c ? ', ' : '';
                $c .= "YEAR({$wpdb->posts}.post_date) $order";
            }
            return $c;
        }, 10, 2 );

        $ok = isset( $orderby2 );
        if ( ! $ok && empty( $orderby ) ) {
            // Don't sort by post date.
            $orderby2 = false;
        } elseif ( ! $ok ) {
            // Pass to WP_Query as a string.
            $orderby2 = implode( ' ', $orderby );
        }
    }

    // by Year
    if ( ! is_numeric( $year ) ) {
        $year = '';
    }

    


    $q = new WP_Query( [
        'post_status' => $post_status,
        'post_type'   => array($post_type),
        'posts_per_page' => -1,
        'post_parent' => 0,
        'year'        => $year,
        'meta_key'    => isset( $meta_key ) ? $meta_key : '',
        'orderby'     => $orderby2,
        'order'       => $order,


    ] );

    if ( $q->have_posts() ) {
        echo '<ul>';
        while ( $q->have_posts() ) {
            $q->the_post();
            ?>
            <li><a href="<?php the_permalink(); ?>"><?php the_title() ?></a></li>
            <?php
        }
        echo '</ul>';
    } else {
        echo '<div class="alert alert-danger">Ningun Resultado</div>';
    }

    wp_die();
}

vvv

Link to comment
Share on other sites

14 hours ago, Kirasiris said:

FIRST OF ALL , THIS POST IS GOING TO BE LONG. Thanks for helping.

Thanks an understatement :).  Note only is your post long, your functions are as well and they should be smaller.  Also, see about separating the HTML script from the other functionality.  Even if you get this working, I expect it will be buggy.  Which parts is not working?  Are you not getting data from the database?  If so, echo the query and manually try it.  If something else, perform similar "reality checks".

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.