Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Dropdown to filter posts on index/archive templates WordPress

  • SOLVED

Hello,

I need a drop down menu on my index.php (and any other archive template) just above my loop.

This is what I have so far.


<form>
<select>
<option value="newest">Sort by Newest</option> <!-- default -->
<option value="oldest">Sort by Oldest</option>
<option value="views">Sort by Most Viewed</option>
</select>
</form>

<?php if (have_posts()) : ?>

<?php while (have_posts()) : the_post(); ?>


<?php endwhile; ?>

<?php endif; ?>



These are what my queries need to be for each one...

Sort by Newest... <strong>order=DESC</strong>

Sort by Oldest... <strong>order=ASC</strong>

Sort by Most Viewed... <strong>meta_key=views&orderby=meta_value_num&order=DESC</strong>



So simply when the dropdown menu is selected, it filters the posts on the page via my querys above.

But what I'm having trouble getting my head round, is that I am using paginate_links on my index/archive templates...


<?php endwhile;

global $wp_query;
$big = 999999999;
$links = paginate_links( array(
'base' => str_replace( $big, '%#%', get_pagenum_link( $big ) ),
'format' => '?paged=%#%',
'current' => max( 1, get_query_var('paged') ),
'total' => $wp_query->max_num_pages,
'prev_text' => __('&#8592; Newer Articles'),
'next_text' => __('Previous Articles &#8594;'),
'type' => 'array'
));

?>

<?php if (count($links) > 0) { ?>

<div class="post-footer">

<?php foreach($links as $pagination) {
echo $pagination;
} ?>

</div>

<?php } ?>

<?php endif; ?>


I don't really care about the prev_text and next_text wording, I will fix this.

My concern is, if I jump to page 2 - will my dropdown menu and query reset itself? Or will it remember the current dropdown state?

I need it to remember the current dropdown state/query when navigating through paged states. Can someone let me know if this is not posible.


Prize money will go to one person only with the best working solution for me.

I found this, I don't know if this helps, I couldn't figure it out. [[LINK href="http://wordpress.org/support/topic/sort-by-drop-down-with-custom-field-value"]]http://wordpress.org/support/topic/...[[/LINK]]



Thanks in advance!
Josh

Answers (2)

2012-07-13

Arnav Joy answers:

please see this , it will sort the result , for the pagination i am doing it

<?php

if(isset($_REQUEST['sort'])){
if($_REQUEST['sort'] == 'newest' )
$order = "&orderby=title&order=DESC";
else if($_REQUEST['sort'] == 'oldest' )
$order = "&orderby=title&order=ASC";
else if($_REQUEST['views'] == 'oldest' )
$order = "&meta_key=views&orderby=meta_value_num&order=DESC";

}

else
$order = "&orderby=ID&order=DESC";

?>


<form method="post" id="order">

<select name="sort" onchange='this.form.submit()'>

<option value="newest">Sort by Newest</option> <!-- default -->

<option value="oldest">Sort by Oldest</option>

<option value="views">Sort by Most Viewed</option>

</select>

</form>

<?php $posts = query_posts($query_string . $order); ?>

<?php if (have_posts()) : ?>



<?php while (have_posts()) : the_post(); ?>


<?php the_title();?>


<?php endwhile; ?>



<?php endif; ?>


Arnav Joy comments:

here is the full code

<?php

if($_REQUEST['sort'] == 'oldest' )

$order = "&orderby=title&order=ASC";

else if($_REQUEST['views'] == 'oldest' )

$order = "&meta_key=views&orderby=meta_value_num&order=DESC";

else
$order = "&orderby=title&order=DESC";

?>





<form method="post" id="order">



<select name="sort" onchange='this.form.submit()'>



<option value="newest" <?php if(isset($_REQUEST['sort']) && $_REQUEST['sort'] == 'newest' ){ ?> selected="selected" <?php } ?> >Sort by Newest</option> <!-- default -->



<option value="oldest" <?php if(isset($_REQUEST['sort']) && $_REQUEST['sort'] == 'oldest' ){ ?> selected="selected" <?php } ?> >Sort by Oldest</option>



<option value="views" <?php if(isset($_REQUEST['sort']) && $_REQUEST['sort'] == 'views' ){ ?> selected="selected" <?php } ?> >Sort by Most Viewed</option>



</select>



</form>



<?php wp_reset_query(); $posts = query_posts($query_string . $order); ?>



<?php if (have_posts()) : ?>







<?php while (have_posts()) : the_post(); ?>





<?php the_title();?>





<?php endwhile;

global $wp_query;

$big = 999999999;

if(isset($_REQUEST['sort']))
$sort = '&sort='.$_REQUEST['sort'];

$links = paginate_links( array(

'base' => str_replace( $big, '%#%', get_pagenum_link( $big ) ),

'format' => '?paged=%#%'.$sort,

'current' => max( 1, get_query_var('paged') ),

'total' => $wp_query->max_num_pages,

'prev_text' => __('&#8592; Newer Articles'),

'next_text' => __('Previous Articles &#8594;'),

'type' => 'array'

));



if (count($links) > 0) { ?>



<div class="post-footer">



<?php foreach($links as $pagination) {

echo $pagination;

} ?>



</div>



<?php } ?>



<?php endif;wp_reset_query(); ?>


Josh Cranwell comments:

Hello, this seemed promising but I am getting strange results when filtering to 'oldest'

My oldest post 'Hello world' is not appearing first. Weirdly it appears on the page but at the bottom, instead of at the top (on page 1)

Any ideas?

Also, if I select an option from the drop down menu, then refresh the page using browser refresh, I get this...

[[LINK href="http://i.imgur.com/AiUoD.png"]]http://i.imgur.com/AiUoD.png[[/LINK]]


Thanks


Arnav Joy comments:

please look these lines in my code at the top

<?php



if($_REQUEST['sort'] == 'oldest' )



$order = "&orderby=title&order=ASC";



else if($_REQUEST['views'] == 'oldest' )



$order = "&meta_key=views&orderby=meta_value_num&order=DESC";



else

$order = "&orderby=title&order=DESC";



?>



replace them with

<?php



if($_REQUEST['sort'] == 'oldest' )



$order = "&orderby=ID&order=ASC";



else if($_REQUEST['views'] == 'oldest' )



$order = "&meta_key=views&orderby=meta_value_num&order=DESC";



else

$order = "&orderby=ID&order=DESC";



?>




and for the second problem of attached image , that's ok you do not have to worry about that...


Arnav Joy comments:

find this line

else if($_REQUEST['views'] == 'oldest' )

and replace with

else if($_REQUEST['sort'] == 'views' )


Arnav Joy comments:

here is the modified full code

<?php
/**
* @package WordPress
* @subpackage Road_Angel_Live
*/

get_header(); ?>

<div class="column one">

<div class="post-header">

<a href="<?php bloginfo('rss2_url'); ?>" title="Subscribe via RSS">Subscribe via RSS</a>

<?php

if ($_REQUEST['sort'] == 'oldest' )

$order = "&orderby=ID&order=ASC";

else if ($_REQUEST['sort'] == 'views' )

$order = "&meta_key=views&orderby=meta_value_num&order=DESC";

else

$order = "&orderby=ID&order=DESC";

?>


<form method="post" id="order">

<select name="sort" onchange='this.form.submit()'>

<option value="newest" <?php if(isset($_REQUEST['sort']) && $_REQUEST['sort'] == 'newest' ){ ?> selected="selected" <?php } ?> >Sort by Newest</option> <!-- default -->
<option value="oldest" <?php if(isset($_REQUEST['sort']) && $_REQUEST['sort'] == 'oldest' ){ ?> selected="selected" <?php } ?> >Sort by Oldest</option>
<option value="views" <?php if(isset($_REQUEST['sort']) && $_REQUEST['sort'] == 'views' ){ ?> selected="selected" <?php } ?> >Sort by Most Viewed</option>

</select>

</form>

</div>

<?php wp_reset_query(); $posts = query_posts($query_string . $order); ?>

<?php if (have_posts()) : ?>

<?php while (have_posts()) : the_post(); ?>

<div class="post" id="post-<?php the_ID(); ?>">

<div class="shadow-left"></div>

<div class="post-popout">

<a class="post-tab"><img src="<?php bloginfo('template_url'); ?>/images/x.gif" alt="" /></a>

<div class="post-stats">

<div class="post-views"><?php if(function_exists('the_views')) { the_views(); } ?></div>

<div class="post-share">

<span class="text">share this post via</span>

<!-- GOOGLE +1 -->
<div class="g-plusone-box">
<div class="g-plusone" data-size="medium" data-href="<?php the_permalink(); ?>"></div>
</div>

<!-- TWITTER -->
<a href="https://twitter.com/share" class="twitter-share-button" data-url="<?php the_permalink(); ?>" data-via="your_screen_name" data-lang="en">Tweet</a>

<!-- FACEBOOK -->
<div class="fb-like" data-href="<?php the_permalink(); ?>" data-send="false" data-layout="button_count" data-width="450" data-show-faces="false"></div>

<!-- PINTEREST -->
<div class="pinit">
<a href="http://pinterest.com/pin/create/button/?url=<?php the_permalink(); ?>&media=<?php

$pinterest = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'pinterest-thumb' );

if ( has_post_thumbnail() ) {

echo $pinterest[0];

} else {

echo get_bloginfo('home') . '/wp-content/uploads/2012/06/no-image-blur-620x360.jpg';

} ?>" class="pin-it-button share-pinterest" count-layout="none"><img border="0" src="<?php bloginfo('template_url'); ?>/images/x.gif" title="Pin It" /></a>
</div>

</div>

</div>

</div>

<div class="post-wrap">

<h1><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></h1>

<p><?php the_advanced_excerpt('length=370&use_words=0&no_custom=0&ellipsis=%26hellip;&read_more=Read more&add_link=1&exclude_tags=a,img,p,strong,blockquote,iframe'); ?></p>

<?php

$module = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'post-thumb' );

if ( has_post_thumbnail() ) {

echo '<a class="post-thumb" href="' . get_permalink() . '" title="Veiw Full Story"><img src="' . $module[0] . '" alt="' . get_the_title() . '" width="620" height="360" /></a>' ;

} else if ( get_post_meta($post->ID, 'Featured Youtube Video', true) ) {

echo '<div class="post-video">' . get_post_meta($post->ID, 'Featured Youtube Video', true) . '</div>' ;

} else {

echo '<a class="post-thumb" href="' . get_permalink() . '" title="Veiw Full Story"><img src="' . get_bloginfo('home') . '/wp-content/uploads/2012/06/no-image-blur-620x360.jpg" alt="" width="620" height="360" /></a>';

}

?>

<div class="post-info">

<div class="post-meta">Posted in <?php the_category(', '); ?><span>.</span> &nbsp;&nbsp; <strong><?php the_time('j<\s\p\a\n>/</\s\p\a\n>n<\s\p\a\n>/</\s\p\a\n>Y<\s\p\a\n>.</\s\p\a\n>') ?></strong> &nbsp;&nbsp; <?php the_tags('', '<span>,</span> ', '<span>.</span>'); ?></div>

<a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>" class="button view-post"><span>view full article</span></a>

</div>

</div>

</div>

<?php endwhile;

global $wp_query;

$big = 999999999;

if(isset($_REQUEST['sort'])){
$sort = $_REQUEST['sort'];
$links = paginate_links( array(

'base' => str_replace( $big, '%#%', get_pagenum_link( $big ) ),
'format' => '?paged=%#%'.$sort,
'current' => max( 1, get_query_var('paged') ),
'total' => $wp_query->max_num_pages,
'add_args' => array('sort' => $sort ),
'prev_text' => __('&#8592; Newer Articles'),
'next_text' => __('Previous Articles &#8594;'),
'type' => 'array'

));
}
else{
$links = paginate_links( array(

'base' => str_replace( $big, '%#%', get_pagenum_link( $big ) ),
'format' => '?paged=%#%'.$sort,
'current' => max( 1, get_query_var('paged') ),
'total' => $wp_query->max_num_pages,
'prev_text' => __('&#8592; Newer Articles'),
'next_text' => __('Previous Articles &#8594;'),
'type' => 'array'

));
}

if (count($links) > 0) { ?>

<div class="post-footer">

<?php foreach($links as $pagination) {

echo $pagination;

} ?>

</div>

<?php } ?>

<?php endif;wp_reset_query(); ?>

</div>

<?php get_footer(); ?>

2012-07-13

Ivaylo Draganov answers:

Hi,

I've just been doing the same thing :--) I think I can help you.

First, let's start with the form:

<form action="" method="GET">
<select name="sort" id="sort">
<option value="DESC" <?php selected( get_query_var( 'sort' ), 'DESC' ); ?>>Sort by Newest</option>
<option value="ASC" <?php selected( get_query_var( 'sort' ), 'ASC' ); ?>>Sort by Oldest</option>
<option value="views" <?php selected( get_query_var( 'sort' ), 'views' ); ?>>Sort by Most Viewed</option>
</select>
<button type="submit" id="sort-submit">Sort</button>
</form>


Then you have to define your new query var so that WP recognizes it and persists it:

<?php
add_action( 'init', 'custom_rewrite_rules' );

function custom_rewrite_rules() {
// add a news query var
add_rewrite_tag( '%sort%', '([^/]+)' );
}
?>


And then you have to alter the $wp_query object to change the order based on your new query var:

<?php
add_action( 'pre_get_posts', 'custom_pre_get_posts' );

function custom_pre_get_posts( $query ) {

// don't affect wp-admin screens
if ( is_admin() )
return;

// vars
$sort = get_query_var( 'sort' );

/** change the order of posts in the main query */
if ( $query->is_main_query() && $sort ) {
// change 'order' (ASC or DESC)
if ( in_array( $sort, array( 'ASC', 'DESC' ) ) {
$query->set( 'order', $sort );
// most views
} else if ( 'views' == $sort ) {
$query->set( 'orderby', 'meta_value_num' );
$query->set( 'meta_key', $sort );
}
}
}
?>


Hm, that's about it. If you want the form to work without pressing the submit button, then you can add such a piece of JS:

/** On document ready */
jQuery(document).ready(function($) {

/** Sorting of posts without form submission(on select change) */
$('#sort-submit').hide();
$('#sort').change(function() {
$(this).parent('form').submit();
});

});


Josh Cranwell comments:

Hello,

I pasted this in my index.php

But I get php error and white screen. So not really sure whats happening.



<form action="" method="GET">

<select name="sort" id="sort">

<option value="DESC" <?php selected( get_query_var( 'sort' ), 'DESC' ); ?>>Sort by Newest</option>

<option value="ASC" <?php selected( get_query_var( 'sort' ), 'ASC' ); ?>>Sort by Oldest</option>

<option value="views" <?php selected( get_query_var( 'sort' ), 'views' ); ?>>Sort by Most Viewed</option>

</select>

<button type="submit" id="sort-submit">Sort</button>

</form>

<?php

add_action( 'init', 'custom_rewrite_rules' );
function custom_rewrite_rules() {
add_rewrite_tag( '%sort%', '([^/]+)' );
}

add_action( 'pre_get_posts', 'custom_pre_get_posts' );
function custom_pre_get_posts( $query ) {

// don't affect wp-admin screens
if ( is_admin() )
return;

// vars
$sort = get_query_var( 'sort' );

/** change the order of posts in the main query */
if ( $query->is_main_query() && $sort ) {

// change 'order' (ASC or DESC)
if ( in_array( $sort, array( 'ASC', 'DESC' ) ) {

$query->set( 'order', $sort );

// most views
} else if ( 'views' == $sort ) {

$query->set( 'orderby', 'meta_value_num' );
$query->set( 'meta_key', $sort );

}

}

}

?>


Ivaylo Draganov comments:

Sorry, I forgot to say that the PHP code has to go into <em>functions.php</em>.


Ivaylo Draganov comments:

Oh yes! And there's a syntax error on this piece of code:

<?php
add_action( 'pre_get_posts', 'custom_pre_get_posts' );

function custom_pre_get_posts( $query ) {

// don't affect wp-admin screens
if ( is_admin() )
return;

// vars
$sort = get_query_var( 'sort' );

/** change the order of posts in the main query */
if ( $query->is_main_query() && $sort ) {
// change 'order' (ASC or DESC)
if ( in_array( $sort, array( 'ASC', 'DESC' ) ) ) {
$query->set( 'order', $sort );
// most views
} else if ( 'views' == $sort ) {
$query->set( 'orderby', 'meta_value_num' );
$query->set( 'meta_key', $sort );
}
}
}
?>


A missing bracket! :--) Please try again.