sm1215
sm1215

Reputation: 436

Wordpress Custom Column Default Ordering

I have a custom post type named "Team Members" along with some custom columns - one specifically set up to use for ordering the custom posts. I've set it up so that when you first visit the Team Members tab, the posts are sorted (ASC) by the "Team Order" column. This is working great, however, I've run into a small problem where if I click the Team Order column to reverse the sorting to DESC, it doesn't seem like Wordpress recognizes that they were already sorted when the page initially loaded. Instead, it queries the posts again and returns them in ASC order a second time. Then, if column title is clicked again it returns the posts in DESC order. How can I get rid of the need to click twice? The posts are already sorted in ascending order when the page first loads. Why does Wordpress miss this and return them in ascending order a second time before finally moving on to DESC?

Here is my code, let me know if you would like to see anything more. Thanks

//team_members Post Type: sortable columns
add_filter( 'manage_edit-team_members_sortable_columns', 'team_members_sortable_columns' );
function team_members_sortable_columns( $columns ){
    $columns['team_order'] = 'team_order';

    return $columns;
}

//team_members Post Type: sortable columns orderby
add_action( 'pre_get_posts', 'team_members_orderby_columns', 1 );
function team_members_orderby_columns( $query ){
    if( !is_admin() ){
        return;
    }

    $order = $query->get( 'team_order' );

    if( $query->is_main_query() ){

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

        if( $order == '' ){
            $query->set( 'order', 'ASC' );   
        }

    }
}

Upvotes: 1

Views: 1702

Answers (2)

moritzgvt
moritzgvt

Reputation: 444

That's a long time ago but maybe my solution to this will help someone:

To enable column ordering on page load one need to check if $orderby = $query->get( 'orderby' ) is set. If not set your custom ordering. Similar to this:

 $orderby = $query->get('orderby');

    if ($orderby === 'team_order') {
        $query->set('meta_key','team_order');
        $query->set('orderby','meta_value_num');
        return;
    }

    if ($orderby === '') {
        $query->set('meta_key','team_order');
        $query->set('orderby','meta_value_num');
    
        if ($query->get('order') === '') {
            $query->set( 'order', 'DESC' );
        }
        return;
    }

Or add another case to the switch condition in @sastra-nababans answer:

case '': // If orderby is empty
    $query->set('meta_key', 'team_order' );
    $query->set('orderby', 'meta_value_num' );
    if ($query->get('order') === '')                
        $query->set('order', 'DESC');   
    }
    break;

Upvotes: 1

Sastra Nababan
Sastra Nababan

Reputation: 304

Try this

    //team_members Post Type: sortable columns orderby
    add_action( 'pre_get_posts', 'team_members_orderby_columns', 1 );
   function team_members_orderby_columns( $query ){
        if( !is_admin() ){
            return;
        }

     $order = $query->get( 'team_order' );
     if ( $query->is_main_query() && ( $orderby = $query->get( 'orderby' ) ) ) {
      switch( $orderby ) {
        case 'team_order':
            $query->set( 'meta_key', 'team_order' );
            $query->set( 'orderby', 'meta_value_num' );
            if ( ! in_array( $order, array( 'ASC', 'DESC' ) ) )                
             $query->set( 'order', 'ASC' );   
            }
        break;    
      }
     }
   }

Upvotes: 1

Related Questions