Home › Toolset Professional Support › [Waiting for user confirmation] Adding a range filter to a view
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.
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| - | 10:00 – 13:00 | 10:00 – 13:00 | 10:00 – 13:00 | 10:00 – 13:00 | 10:00 – 13:00 | - |
| - | 14:00 – 18:00 | 14:00 – 18:00 | 14:00 – 18:00 | 14:00 – 18:00 | 14:00 – 18:00 | - |
Supporter timezone: Asia/Kolkata (GMT+05:30)
This topic contains 13 replies, has 1 voice.
Last updated by Minesh 3 days, 13 hours ago.
Assisted by: Minesh.
Our Rides content type has 3 custom fields to define the distance of the ride. The fields are mileage1, mileage2, and mileage3. We have 3 because each ride can have multiple options for the number of miles. We offer different paces with many of our rides and each pace can have its own distance.
We have a full list of our rides present on a Ride Maps page where people can currently choose the ride from a dropdown of ride titles or by a filter set on the Ride County field.
We are interested in adding another filter here based on the Ride Distance (the 3 mileage fields). We want to offer selectable range options and have the filter check if ANY of the three mileage fields fall within this range. For example, we'd have the range options set as
Up to 20 miles
21-30 miles
31-40 miles
41-50 miles
Over 50 miles
And the results would show all rides where ANY of the three mileage fields fall within the range option chosen by the end user on the front end.
I did find a question similar to this here:
https://toolset.com/forums/topic/adding-price-range-filter-to-a-view/
But our case is more complicated with the filter needing to check if ANY of the contents of three different fields fall within the chosen range. I understand this will require custom code in some form to accomplish.
Thanks in advance for any assistance you can provide.
Hello. Thank you for contacting the Toolset support.
Can you please share problem URL where I can see the view you added with filters and admin access details.
Setup one ride with test data and I will try to give you solution based on the selected filter option.
*** Please make a FULL BACKUP of your database and website.***
I would also eventually need to request temporary access (WP-Admin and FTP) to your site. Preferably to a test site where the problem has been replicated if possible in order to be of better help and check if some configurations might need to be changed.
I have set the next reply to private which means only you and I have access to it.
Ok - Can you give me the mileage range options and how you want to display it as dropdown select or something else?
Up to 20 miles
21-30 miles
31-40 miles
41-50 miles
Over 50 miles
We should probably set it up as checkboxes so people can select more than one option unless that complicates things too much. If it is not a lot of extra effort, go with that. If it's much easier to use a dropdown where people can only choose one option, then that's OK.
Thanks a bunch if we can get this. A range filter is definitely a feature that I think many sites could use so I hope you'll be able to incorporate this into the plugin at some point in the future.
I've added the following code to "Custom Code" section offered by Toolset with the code snippet namely "custom-range-filter-for-ride":
=> hidden link
add_filter( 'wpv_filter_query', 'toolset_mileage_range_filter_2059', 999, 3 );
function toolset_mileage_range_filter_2059( $query_args, $view_settings, $view_id ) {
// Only View 2059.
if ( 2059 !== (int) $view_id ) {
return $query_args;
}
$selected_range = sanitize_text_field(
wp_unslash( $_GET['wpv-wpcf-mileage1'] ?? '' )
);
if ( '' === $selected_range ) {
return $query_args;
}
/*
* Remove Toolset's original mileage1 filter.
*/
if ( ! empty( $query_args['meta_query'] ) && is_array( $query_args['meta_query'] ) ) {
foreach ( $query_args['meta_query'] as $key => $meta_query ) {
if (
is_array( $meta_query )
&& isset( $meta_query['key'] )
&& 'wpcf-mileage1' === $meta_query['key']
) {
unset( $query_args['meta_query'][ $key ] );
}
}
$query_args['meta_query'] = array_values( $query_args['meta_query'] );
}
$ranges = array(
'0-20' => array( 0, 20 ),
'21-30' => array( 21, 30 ),
'31-40' => array( 31, 40 ),
'41-50' => array( 41, 50 ),
'>50' => array(50)
);
$fields = array(
'wpcf-mileage1',
'wpcf-mileage2',
'wpcf-mileage3',
);
$unique_post_ids = array();
foreach ( $fields as $field ) {
if ( isset( $ranges[ $selected_range ] ) ) {
list( $min, $max ) = $ranges[ $selected_range ];
if ( '>50' === $selected_range ) {
$condition[] = array(
array(
'key' => $field,
'compare' => 'EXISTS'),
array('key' => $field,
'value' => str_replace('>','',$selected_range),
'compare' => '>',
'type' => 'NUMERIC')
);
}else{
$condition[] = array(
array(
'key' => $field,
'compare' => 'EXISTS'),
array('key' => $field,
'value' => array( $min, $max ),
'compare' => 'BETWEEN',
'type' => 'NUMERIC')
);
}
$found_rides = get_posts(
array(
'post_type' => 'ride',
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids',
'meta_query' => $condition
));
$unique_post_ids = array_merge($unique_post_ids,$found_rides);
}
}
$query_args['post__in'] = ! empty( $unique_post_ids )
? $unique_post_ids
: array( 0 );
return $query_args;
}
To your view I've added the followig filter:
=> hidden link
<div class="form-group"> <label for="wpv-wpcf-mileage1">[wpml-string context="wpv-views"]Mileage1[/wpml-string]</label> [wpv-control-postmeta type="select" field="wpcf-mileage1" source="custom" url_param="wpv-wpcf-mileage1" values=",0-20,21-30,31-40,41-50,>50" display_values="Please Select,Up to 20 miles,21-30 miles,31-40 miles,41-50 miles,Over 50 miles"] </div>
Can you please check now: hidden link
This is an excellent start! Thanks so much!
But I don't think it is checking the mileage2 or mileage3 fields. Go to the page and select the 21-30 mile range on the dropdown and submit that. The results are perfect for using mileage1 as the field being checked.
But then look at the Chapin Station Picnic Ride result. It has mileage options of 28, 34, and 47 miles. So if you change the filter dropdown to show 31-40 mile rides, this Chapin Station Picnic Ride should also show up on the results for that range because the mileage2 field meets the 31-40 miles criteria. But Chapin Station Picnic Ride is not showing up in the results when you filter using 31-40 miles.
That's the part where I feared this might get too complicated because it needs to look at 3 different fields. Is it too much to ask to get it to check all three fields? What you've provided is definitely something we can use and keep on there as is, but having it check all three mileage fields would be perfection for what we're ideally going for with this. This way people can get results for all the rides we have with their desired range as at least one of the options provided.
One other thing to ask about with the custom code. How would I make this code also work on another view?
This page also uses the following view:
7458 Ride Maps - Mobile View
hidden link
I set that up so the results would display well on a mobile phone. The wide table view for the results is great for desktops and tablets, but a different approach was needed for phones. If you can add something in the custom code to tell it to execute on view 7458 as well as 2059, I should be able to just duplicate everything you've done within the 2059 view once it is complete and add that to view 7458. Or I guess I could just duplicate this code snippet completely and just change the view number to 7458 on the second one. Would that work? I'm just not sure of how to change this code:
// Only View 2059.
if ( 2059 !== (int) $view_id ) {
...to where it will work on both views. Thanks HUGELY for this help!!! You guys continue to amaze me with what you're willing to provide to assist with using Toolset.
Can you please check now: hidden link
I've adjusted the code as given under for the code snippet "custom-range-filter-for-ride":
=> hidden link
add_filter( 'wpv_filter_query', 'toolset_mileage_range_filter_2059', 999, 3 );
function toolset_mileage_range_filter_2059( $query_args, $view_settings, $view_id ) {
// target view ids
$target_view_ids = array(7458,2059);
if ( in_array($view_id,$target_view_ids) ) {
return $query_args;
}
$selected_range = sanitize_text_field(
wp_unslash( $_GET['wpv-wpcf-mileage1'] ?? '' )
);
if ( '' === $selected_range ) {
return $query_args;
}
/*
* Remove Toolset's original mileage1 filter.
*/
if ( ! empty( $query_args['meta_query'] ) && is_array( $query_args['meta_query'] ) ) {
foreach ( $query_args['meta_query'] as $key => $meta_query ) {
if (
is_array( $meta_query )
&& isset( $meta_query['key'] )
&& 'wpcf-mileage1' === $meta_query['key']
) {
unset( $query_args['meta_query'][ $key ] );
}
}
$query_args['meta_query'] = array_values( $query_args['meta_query'] );
}
$ranges = array(
'0-20' => array( 0, 20 ),
'21-30' => array( 21, 30 ),
'31-40' => array( 31, 40 ),
'41-50' => array( 41, 50 ),
'>50' => array(50)
);
$fields = array('wpcf-mileage1','wpcf-mileage2','wpcf-mileage3');
$unique_post_ids = array();
foreach ( $fields as $field ) {
if ( isset( $ranges[ $selected_range ] ) ) {
list( $min, $max ) = $ranges[ $selected_range ];
if ( '>50' === $selected_range ) {
$condition = array(
array(
'key' => $field,
'compare' => 'EXISTS'),
array('key' => $field,
'value' => str_replace('>','',$selected_range),
'compare' => '>',
'type' => 'NUMERIC')
);
}else{
$condition = array(
array(
'key' => $field,
'compare' => 'EXISTS'),
array('key' => $field,
'value' => array( $min, $max ),
'compare' => 'BETWEEN',
'type' => 'NUMERIC')
);
}
$found_rides = get_posts(
array(
'post_type' => 'ride',
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids',
'meta_query' => $condition
));
$unique_post_ids = array_merge($unique_post_ids,$found_rides);
}
}
$query_args['post__in'] = ! empty( $unique_post_ids )
? $unique_post_ids
: array( 0 );
return $query_args;
}
Something is off with this now. The range chosen in the filter is not producing the expected results.
When I choose "Up to 20 miles" I get no results.
When I choose 21-30 miles, it looks like it is giving me the results that should come up when "Up to 20 miles" is chosen.
When I choose 31-40 miles, it looks like it is giving me everything under 30 miles. It's not giving me ones that are 21-30 miles because there are some in here that are under 20.
When I choose 41-50 miles, it looks like it is giving me everything under 40 miles. It's not giving me ones that are 31-40 miles because the ones that are under 30 are here too. So it's not that the filter is one off. Something isn't right with the ranges assigned to each filter option.
When I choose over 50 miles, it is giving me no results.
It seems there is a cache issueas well as multiple wpv_query_filters were added to "Custom Code" section.
It seems that the current site is the live site. Can you please share staging site where I can disable the cache and troubleshoot further.
*** Please make a FULL BACKUP of your database and website.***
I would also eventually need to request temporary access (WP-Admin and FTP) to your site. Preferably to a test site where the problem has been replicated if possible in order to be of better help and check if some configurations might need to be changed.
I have set the next reply to private which means only you and I have access to it.
Ok here is the updated code added to the "Custom Code" section:
add_filter( 'wpv_filter_query', 'func_custom_mileage_range_filter', 999, 3 );
function func_custom_mileage_range_filter( $query_args, $view_settings, $view_id ) {
// target view ids
$target_view_ids = array(7458,2059);
if(in_array($view_id,$target_view_ids) ) {
$selected_range = sanitize_text_field(
wp_unslash( $_GET['wpv-wpcf-mileage1'] ?? '' )
);
if ( '' === $selected_range ) {
return $query_args;
}
/*
* Remove Toolset's original mileage1 filter.
*/
if ( ! empty( $query_args['meta_query'] ) && is_array( $query_args['meta_query'] ) ) {
foreach ( $query_args['meta_query'] as $key => $meta_query ) {
if (
is_array( $meta_query )
&& isset( $meta_query['key'] )
&& 'wpcf-mileage1' === $meta_query['key']
) {
unset( $query_args['meta_query'][ $key ] );
}
}
$query_args['meta_query'] = array_values( $query_args['meta_query'] );
}
$ranges = array(
'0-20' => array( 0, 20 ),
'21-30' => array( 21, 30 ),
'31-40' => array( 31, 40 ),
'41-50' => array( 41, 50 ),
'>50' => array(50)
);
$fields = array('wpcf-mileage1','wpcf-mileage2','wpcf-mileage3');
$unique_post_ids = array();
$condition = array();
$tax_query = $query_args['tax_query'];
foreach ( $fields as $field ) {
if ( isset( $ranges[ $selected_range ] ) ) {
list( $min, $max ) = $ranges[ $selected_range ];
if ( '>50' === $selected_range ) {
$condition = array('relation'=>'AND',
array(
'key' => $field,
'compare' => 'EXISTS'),
array('key' => $field,
'value' => str_replace('>','',$selected_range),
'compare' => '>',
'type' => 'NUMERIC')
);
}else{
$condition = array('relation'=>'AND',
array(
'key' => $field,
'compare' => 'EXISTS'),
array(
'key' => $field,
'value' => '',
'compare' => '!=',
),
array('key' => $field,
'value' => array( $min, $max ),
'compare' => 'BETWEEN',
'type' => 'NUMERIC'),
);
}
//// get_posts arguments
$get_posts_args = array(
'post_type' => 'ride',
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids',
'meta_query' => $condition,
'tax_query' => $tax_query,
);
/// get the get_posts for found rides
$found_rides = get_posts($get_posts_args);
/// unique ids with found rides post
$unique_post_ids = array_unique(array_merge($unique_post_ids,$found_rides));
$query_args['tax_query'] = array();
}
}
if(!empty($unique_post_ids)){
$query_args['post__in'] = $unique_post_ids;
}
} // end in_array view_id
return $query_args;
}
Can you please check now:
- hidden link
I hope this time it should work as expected.
This is working perfectly in showing the correct ride results!!! Thanks so much! Do you still need me to set up a staging site? I didn't provide all the info because I'm assuming that's not needed now that it is working great. I may have to add some language explaining that the results will show any ride that has the desired distance range as at least one of the mileage options, but I don't need assistance with that. I think it's working great. Thanks again.
Great and glad to know that the sulution I shared help you to resolve your issue.
You are welcome to mark resolve this ticket. Have a great time.
Oops. I'm afraid I have to ask for one more thing. I tried to add this to the mobile view figuring that would be easy enough for me to handle. I added the code to the search and pagination section as needed. But unfortunately, I couldn't figure out how you added the "Filter based on the frontend search filter by Mileage1." bit to the custom field filter section. I clicked to add a filter, but I didn't see mileage1 in the field options. I see mileage2 and mileage3, but not mileage1. I'm assuming that's due to the section of your custom code that you labeled as
/*
* Remove Toolset's original mileage1 filter.
*/
But that leaves me unsure of how to get this filter into the mobile view.
The mobile view is here:
hidden link
New threads created by Minesh and linked to this one are listed below:
https://toolset.com/forums/topic/split-adding-a-range-filter-to-a-view-for-mobile-view/
We can not continue like this. As per our support policy, we entertain only one question per ticket.
In future - can you please open a new ticket with every new question you may have. This will help other user's searching on the forum as well as help us to write correct problem resolution summery.
For now, I will split the ticket and you can mark resolve this ticket. Here is the split ticket and I will follow up there.
- https://toolset.com/forums/topic/split-adding-a-range-filter-to-a-view-for-mobile-view/