Skip Navigation

[Resolved] Sort the search view results by address distance and custom date field

This thread is resolved. Here is a description of the problem and solution.

Problem:

A Toolset View listing in-person workshop “event” posts needed conditional, multi-level sorting: if the user didn’t enter an origin address, results should sort by a custom “start date” field; if the user did enter an origin, results should sort by Toolset Maps distance and then by the same start-date field. The user attempted to do this via toolset_views_query_args, but it didn’t affect the View output.

Solution:

Toolset Views ordering must be adjusted via the wpv_filter_query hook (not toolset_views_query_args). Use wpv_filter_query to detect whether the distance search parameter is set; if not, force ordering by the start date meta field; if yes, apply a compound orderby with distance first and the start date second.

Hook: add_filter( 'wpv_filter_query', ... )

If toolset_maps_distance_radius is empty → orderby = meta_value_num, meta_key = wpcf-start-date, order = ASC

Else → orderby = array( 'distance' => 'ASC', 'wpcf-start-date' => 'ASC' )

Relevant Documentation:

https://toolset.com/documentation/programmer-reference/views-filters/

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

This topic contains 3 replies, has 1 voice.

Last updated by christineH-9 1 week, 1 day ago.

Assisted by: Christopher Amirian.

Author
Posts
#2839578

I have a view that returns search results for in-person workshop events that take place in several different locations and several different dates.
hidden link

The default sorting option is based on distance from the user, but there are several problems:

- If a user has not entered a location into the search, the results are sorted alphabetically by address.
- If a user enters an address into the search, the results are sorted by distance but they are not sorted by the event date when there are multiple events at the same location.
- When I add a sorting filter to the view results, my only options are to sort by address (alphabetically, not by distance), or to sort by the event's start date (ignoring distance).
- And when I enter an address into the search, the sorting filter does not work at all.

What I would like to have is one view that can sort by two custom fields:
- If the origin address is empty always sort by date.
- If the origin address is known then give the user an option to sort by distance, then date; or sort by date, then distance. (Never sort the address alphabetically.)

Thank you for your assistance with this matter.

#2839866

Christopher Amirian
Supporter

Languages: English (English )

Hi,

Welcome to Toolset support. Toolset does not support such secondary filtering for Addresses.

If I understood the need, I think you can handle it with two views.

Here are the steps to create two views:

Create View A

- Go to Toolset → Views → Add New and create a View for your Events CPT.
Toolset
- In the View settings, set Sorting to your event start date custom field (ascending).
Toolset
- Add your loop output (same layout you already use).

Create View B (origin entered → sort by distance)

- Go to Toolset → Views → Add New and create another View for the same Events CPT.
Toolset
- Add the Distance search filter (Toolset Maps distance search).
- In the View settings, set Sorting to “As a distance from …” (distance ordering).

Put both Views on the page and show the right one

- Edit the page where the search results appear and insert both Views.
- Wrap them with a conditional that checks if the origin parameter is empty.

Example:

[wpv-conditional if="( URL_PARAM('toolset_maps_distance_center') eq '' )"]
  [wpv-view name="VIEW_A_SORT_BY_DATE"]
[/wpv-conditional]

[wpv-conditional if="( URL_PARAM('toolset_maps_distance_center') neq '' )"]
  [wpv-view name="VIEW_B_SORT_BY_DISTANCE"]
[/wpv-conditional]

For more information:

https://toolset.com/forums/topic/distance-filter-3/
https://toolset.com/course-lesson/passing-arguments-to-views/

Thanks.

#2840015

Thank you, that approach will help to make the results a little better than what I have now.

I have been working on a custom sorting code for this view, but I think that there is an error in how I'm initiating the function. I'm not seeing any difference in the results with this code activated or not.
I would appreciate any guidance you can offer.

function custom_workshop_sorting( $query_args, $view_settings, $view_id, $view_slug ) {
if ( ( isset($view_settings['view_id']) && $view_settings['view_id'] == 233717) ) {

// ----------------------------------------------------------------------
// 1. CONFIGURATION: UPDATED VALUES
// ----------------------------------------------------------------------

// The slug and ID of your specific Toolset View
$target_view_slug = 'workshop-search-in-person-2';
$target_view_id = 233717;

// The raw meta key for your Workshop's Start Date custom field (e.g., 'wpcf-start-date')
$start_date_meta_key = 'wpcf-start-date';

// The URL parameter used when an origin address is known
$origin_address_param_name = 'toolset_maps_distance_center';

// The name of the query parameter Toolset uses to pass the user's explicit sort choice.
$user_sort_param_name = 'wpv_sort_orderby';

// The value Toolset uses in the URL when the user selects the date sort option.
$date_sort_option_value = 'field-' . $start_date_meta_key;

// ----------------------------------------------------------------------

// Get input values from the URL query string ($_GET)
$origin_address_center = isset( $_GET[ $origin_address_param_name ] ) ? sanitize_text_field( $_GET[ $origin_address_param_name ] ) : '';
$has_origin_address = ! empty( $origin_address_center );

$user_sort_choice = isset( $_GET[ $user_sort_param_name ] ) ? sanitize_key( $_GET[ $user_sort_param_name ] ) : '';

// CHECK 1: Has the user explicitly selected the Date sort option?
$user_selected_date_sort = ( $user_sort_choice === $date_sort_option_value );

// --- CONDITION 1: No origin address provided ($origin_address_param_name is empty) ---
if ( ! $has_origin_address ) {
// Sort results by start date (numerically, for timestamp/date format)
$query_args['orderby'] = 'meta_value_num';
$query_args['meta_key'] = $start_date_meta_key;
$query_args['order'] = 'ASC';
return $query_args;
}

// --- Conditions where an origin address IS provided ($has_origin_address is TRUE) ---

// Clear conflicting sorting keys when using compound sorting array
$query_args['order'] = '';
$query_args['meta_key'] = '';

if ( $user_selected_date_sort ) {
// --- CONDITION 3: Address entered AND user chose to sort by start date (via dropdown) ---
// Sort by Start Date (Primary), then by Distance (Secondary)
$query_args['orderby'] = array(
$start_date_meta_key => 'ASC', // Primary: Start Date (uses raw meta key for WP_Query)
'distance' => 'ASC' // Secondary: Distance (Toolset internal)
);

} else {
// --- CONDITION 2: Address entered AND user chose the default/address string sort ---
// This is the fallback for all non-date choices when an address is present.
// Sort by Distance (Primary), then by Start Date (Secondary)
$query_args['orderby'] = array(
'distance' => 'ASC', // Primary: Distance (Toolset internal calculation)
$start_date_meta_key => 'ASC' // Secondary: Start Date (uses raw meta key for WP_Query)
);
}

}
return $query_args;
}
add_filter( 'toolset_views_query_args', 'custom_workshop_sorting', 10, 4 );

#2840112

Christopher Amirian
Supporter

Languages: English (English )

Hi,

We are unable to delve into the custom code to know what might be wrong. This is outside of our support scope.

What I have found, skimming over your code, is that Toolset Views uses wpv_filter_query (3 args). Your toolset_views_query_args hook won’t run for Views ordering.

For more information:
https://toolset.com/documentation/programmer-reference/views-filters/

So something like this:

add_filter( 'wpv_filter_query', 'chr_workshop_sorting', 99, 3 );
function chr_workshop_sorting( $query_args, $view_settings, $view_id ) {

    if ( (int) $view_id !== 233717 ) {
        return $query_args;
    }

    $start_date_meta_key = 'wpcf-start-date';
    $origin_param        = 'toolset_maps_distance_center';

    $origin = isset( $_GET[ $origin_param ] ) ? trim( $_GET[ $origin_param ] ) : '';

    // If origin is empty -> sort by date
    if ( $origin === '' ) {
        $query_args['meta_key'] = $start_date_meta_key;
        $query_args['orderby']  = 'meta_value_num';
        $query_args['order']    = 'ASC';
    }

    // If origin is present -> keep the View's distance ordering (Toolset Maps)
    return $query_args;
}

- wpv_filter_query hook + signature
- Toolset confirms distance + secondary sort isn’t available via View settings (custom code needed; common workaround is switching sort only when distance isn’t used)

For more information:
https://toolset.com/forums/topic/secondary-sort-with-distance-sort/

Please consider that the code above is not test and it is an attempt to help for a cusotm code that is outside of our support scope.

Thanks.

#2840153

Thank you for pointing me in the right direction. I was able to achieve the result I wanted with a modification of the script you linked to:

add_filter( 'wpv_filter_query', 'wpv_filter_query_func', 1000 , 3 );
function wpv_filter_query_func( $query_args, $view_settings ) {
// process if specific view
if ( ( isset($view_settings['view_id']) && $view_settings['view_id'] == 233717) ) {
// if distance search is not set
if(empty($_GET['toolset_maps_distance_radius'])) {
// set order by title
$query_args['orderby'] = 'meta_value_num';
$query_args['meta_key'] = 'wpcf-start-date';
$query_args['order'] = 'ASC';
} else {
$query_args['orderby'] = array(
'distance' => 'ASC',
'wpcf-start-date' => 'ASC'
);
}
}
return $query_args;
}