Home › Toolset Professional Support › [Resolved] Filter posts via comparing field numeric value – 3 checkboxes filtering options
Problem:
Client has a numeric custom field used as a filter in a View, but wants to present the filter as three checkboxes for ranges (i.e. less than x, more than y, between x and y), while still being able to use other filters on the same View.
Solution:
This requires custom code.
See below for the proposed solution, which is particular to this site but which can be adapted as required:
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 |
---|---|---|---|---|---|---|
- | 7:00 – 14:00 | 7:00 – 14:00 | 7:00 – 14:00 | 7:00 – 14:00 | 7:00 – 14:00 | - |
- | 15:00 – 16:00 | 15:00 – 16:00 | 15:00 – 16:00 | 15:00 – 16:00 | 15:00 – 16:00 | - |
Supporter timezone: Europe/London (GMT+01:00)
Tagged: Custom search, Views plugin
Related documentation:
This topic contains 9 replies, has 2 voices.
Last updated by hendrikH 6 years, 1 month ago.
Assisted by: Nigel.
What i am trying to do:
I have 2 post types "Individual bike tours" and "Guided bike tours". Both of there post types have separate custom fields (text field) called "Metres of Elevation Individual Tour" and "Metres of Elevation Guided Tour". Those fields are populated with a numbers representing *meters*.
I am trying to filter those posts like this with 3 checkboxes:
If the value of the field is less than 200
If the value of the field is between 200-500
If the value of the field is greater than 500
My goal is to make the filter work without the need to manually check an additional taxomony.
Is there a way to automatically fit the post in a certain taxonomy based on the value of one field?
I have followed the Toolset documentation. The filters currently work but in addition of the field value, i have to check one taxonomy term.
The link to the site:
hidden link
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+01:00)
Hi Hendrick
If you have one custom field—e.g. "metres of elevation"—then you can have one filter for that field, e.g. "less than the value entered".
To do what you are looking to do, have a dropdown with 3 options, below 200 metres, between 200-500 metres, and above 500 metres, you are going to need to manipulate the query using wpv_filter_query according to what the user selects.
So you will first need to add the filter in such a way that it is displayed as a select dropdown using some placeholder values that you will test for in your PHP code, as shown in the screenshot where each case has a value of 1, 2, or 3.
A minor gotcha when you come to insert the View filter is that you need to manually set the Custom Search Settings so that it Always shows all values for inputs.
Then you need to add code that hooks into wpv_filter_query to modify the meta_query according to what was selected by the user.
I would encourage you to do this yourself, though if you are adding several filters and not just this one (which I think you are) it is a little tricky, so let me suggest the following code to you. Please read through it and try to understand it, the key part being switch case to modify the meta_query arguments depending on the submitted filter value.
You will need to edit the slug of your custom field and the View id. The following also supposes that your select field values are 1, 2, and 3 as per the screenshot.
/** * Custom filter by height */ function tssupp_filter_thing_by_height( $query_args, $view_settings, $view_id ){ if ( 152 == $view_id && isset( $query_args['meta_query'] ) ) { foreach( (array)$query_args['meta_query'] as $k=>$v ){ if ( isset( $v['key'] ) && $v['key'] == 'wpcf-height' ) { switch ( $v['value'] ) { case 1: $query_args['meta_query'][$k]['value'] = 200; $query_args['meta_query'][$k]['type'] = 'numeric'; $query_args['meta_query'][$k]['compare'] = '<='; break; case 2: $query_args['meta_query'][$k]['value'] = array( 200, 500 ); $query_args['meta_query'][$k]['type'] = 'numeric'; $query_args['meta_query'][$k]['compare'] = 'BETWEEN'; break; case 3: $query_args['meta_query'][$k]['value'] = 500; $query_args['meta_query'][$k]['type'] = 'numeric'; $query_args['meta_query'][$k]['compare'] = '>='; break; } } } } return $query_args; } add_filter('wpv_filter_query', 'tssupp_filter_thing_by_height', 101, 3);
Please note that providing custom code and supporting it is outside our support policy and I provide the above to get you started rather than as a tested solution.
Hello Nigel and thank you very much for the custom code provided. It worked you beautiful.
I've implamented the code for length, height and difficulty.
Because the design is done is such a way, i had to replace the dropdown for radios. But the result was the same.
Now...doing so the flexibility of the filters diminished. I've tried using checkboxes (the ideal scenario for using AND condition) but despite the fact that the filter query updates with a "&" between the metas, they are always queried in the same order (1,2,3) and the result is displayed only for the first query.
Anything comes to mind which can help me with this?
Thank you.
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+01:00)
Hi Hendrik
What does the final query look like?
Just before you return $query_args, if you send them to your debug log with error_log(print_r($query_args, true)); what do the final arguments look like?
Hello Nigel,
I've added the error_log to the function but i get nothin in the console. Maybe i'm doing something wrong.
I've attached a image. This is how my url looks like when i try to use checkboxes. In this case all 3 checkboxes for length are checked.
Thank you.
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+01:00)
Hi Hendrik
It won't show in the console, that is for JavaScript, it will show in your PHP logs.
If you haven't already, turn on the debug log by editing your wp-config.php file and change the line with WP_DEBUG like so:
define('WP_DEBUG', true); define('WP_DEBUG_LOG', true); define('WP_DEBUG_DISPLAY', false);
That will create a debug.log file in your wp-content directory which you can examine in any text editor.
Now when you load the page with that View anything you error_log will be sent to that debug.log file.
So editing my example code above you would log the query args like so:
/** * Custom filter by height */ function tssupp_filter_thing_by_height( $query_args, $view_settings, $view_id ){ if ( 152 == $view_id && isset( $query_args['meta_query'] ) ) { foreach( (array)$query_args['meta_query'] as $k=>$v ){ if ( isset( $v['key'] ) && $v['key'] == 'wpcf-height' ) { switch ( $v['value'] ) { case 1: $query_args['meta_query'][$k]['value'] = 200; $query_args['meta_query'][$k]['type'] = 'numeric'; $query_args['meta_query'][$k]['compare'] = '<='; break; case 2: $query_args['meta_query'][$k]['value'] = array( 200, 500 ); $query_args['meta_query'][$k]['type'] = 'numeric'; $query_args['meta_query'][$k]['compare'] = 'BETWEEN'; break; case 3: $query_args['meta_query'][$k]['value'] = 500; $query_args['meta_query'][$k]['type'] = 'numeric'; $query_args['meta_query'][$k]['compare'] = '>='; break; } } } error_log(print_r($query_args, true)); } return $query_args; } add_filter('wpv_filter_query', 'tssupp_filter_thing_by_height', 101, 3);
Now, we started out talking about a select field, then you said it was done as a radio field, and in your last update you said checkboxes.
Can you clarify what we are working with?
Hello Nigel,
To clarify, the current code (the code you provided) works great with radios, it filters accordingly.
I've also tried to use it with checkboxes, because that's the ideal scenario that i am looking for. Being able to select multiple heights options. But despite the fact that the filter query updates with a "&" between the metas, they are always queried in the same order (1,2,3) and the result is displayed only for the first query.
I attach the debug log using height filters - with radios in one situation and with the checkboxes in the second situation.
USING FUNCTIONAL RADIOS
[09-Mar-2018 14:56:02 UTC] Array ( [post_type] => Array ( [0] => individual-bike-tour [1] => guided-bike-tour ) [paged] => 1 [suppress_filters] => [ignore_sticky_posts] => 1 [posts_per_page] => -1 [post__not_in] => Array ( [0] => 22 ) [wpv_original_limit] => -1 [wpv_original_offset] => 0 [wpv_original_posts_per_page] => -1 [meta_query] => Array ( [0] => Array ( [key] => wpcf-show-tour [value] => 1 [type] => CHAR [compare] => = ) [relation] => AND ) [post_status] => Array ( [0] => publish [1] => private ) [orderby] => date [order] => DESC ) [09-Mar-2018 14:56:35 UTC] Array ( [post_type] => Array ( [0] => individual-bike-tour [1] => guided-bike-tour ) [paged] => 1 [suppress_filters] => [ignore_sticky_posts] => 1 [posts_per_page] => -1 [post__not_in] => Array ( [0] => 22 ) [wpv_original_limit] => -1 [wpv_original_offset] => 0 [wpv_original_posts_per_page] => -1 [meta_query] => Array ( [0] => Array ( [key] => wpcf-show-tour [value] => 1 [type] => CHAR [compare] => = ) [1] => Array ( [key] => wpcf-height-meter [value] => 500 [type] => numeric [compare] => >= ) [relation] => AND ) [post_status] => Array ( [0] => publish [1] => private ) [orderby] => date [order] => DESC ) [09-Mar-2018 14:56:40 UTC] Array ( [post_type] => Array ( [0] => individual-bike-tour [1] => guided-bike-tour ) [paged] => 1 [suppress_filters] => [ignore_sticky_posts] => 1 [posts_per_page] => -1 [post__not_in] => Array ( [0] => 22 ) [wpv_original_limit] => -1 [wpv_original_offset] => 0 [wpv_original_posts_per_page] => -1 [meta_query] => Array ( [0] => Array ( [key] => wpcf-show-tour [value] => 1 [type] => CHAR [compare] => = ) [1] => Array ( [key] => wpcf-height-meter [value] => Array ( [0] => 200 [1] => 500 ) [type] => numeric [compare] => BETWEEN ) [relation] => AND ) [post_status] => Array ( [0] => publish [1] => private ) [orderby] => date [order] => DESC ) [09-Mar-2018 14:56:47 UTC] Array ( [post_type] => Array ( [0] => individual-bike-tour [1] => guided-bike-tour ) [paged] => 1 [suppress_filters] => [ignore_sticky_posts] => 1 [posts_per_page] => -1 [post__not_in] => Array ( [0] => 22 ) [wpv_original_limit] => -1 [wpv_original_offset] => 0 [wpv_original_posts_per_page] => -1 [meta_query] => Array ( [0] => Array ( [key] => wpcf-show-tour [value] => 1 [type] => CHAR [compare] => = ) [1] => Array ( [key] => wpcf-height-meter [value] => 200 [type] => numeric [compare] => < ) [relation] => AND ) [post_status] => Array ( [0] => publish [1] => private ) [orderby] => date [order] => DESC )
USING NON FUNCTIONAL CHECKBOXES
[09-Mar-2018 15:04:07 UTC] Array ( [post_type] => Array ( [0] => individual-bike-tour [1] => guided-bike-tour ) [paged] => 1 [suppress_filters] => [ignore_sticky_posts] => 1 [posts_per_page] => -1 [post__not_in] => Array ( [0] => 22 ) [wpv_original_limit] => -1 [wpv_original_offset] => 0 [wpv_original_posts_per_page] => -1 [meta_query] => Array ( [0] => Array ( [key] => wpcf-show-tour [value] => 1 [type] => CHAR [compare] => = ) [relation] => AND ) [post_status] => Array ( [0] => publish [1] => private ) [orderby] => date [order] => DESC ) [09-Mar-2018 15:04:11 UTC] Array ( [post_type] => Array ( [0] => individual-bike-tour [1] => guided-bike-tour ) [paged] => 1 [suppress_filters] => [ignore_sticky_posts] => 1 [posts_per_page] => -1 [post__not_in] => Array ( [0] => 22 ) [wpv_original_limit] => -1 [wpv_original_offset] => 0 [wpv_original_posts_per_page] => -1 [meta_query] => Array ( [0] => Array ( [key] => wpcf-show-tour [value] => 1 [type] => CHAR [compare] => = ) [relation] => AND ) [post_status] => Array ( [0] => publish [1] => private ) [orderby] => date [order] => DESC ) [09-Mar-2018 15:04:17 UTC] Array ( [post_type] => Array ( [0] => individual-bike-tour [1] => guided-bike-tour ) [paged] => 1 [suppress_filters] => [ignore_sticky_posts] => 1 [posts_per_page] => -1 [post__not_in] => Array ( [0] => 22 ) [wpv_original_limit] => -1 [wpv_original_offset] => 0 [wpv_original_posts_per_page] => -1 [meta_query] => Array ( [0] => Array ( [key] => wpcf-show-tour [value] => 1 [type] => CHAR [compare] => = ) [1] => Array ( [key] => wpcf-height-meter [value] => 200 [type] => numeric [compare] => < ) [relation] => AND ) [post_status] => Array ( [0] => publish [1] => private ) [orderby] => date [order] => DESC ) [09-Mar-2018 15:04:21 UTC] Array ( [post_type] => Array ( [0] => individual-bike-tour [1] => guided-bike-tour ) [paged] => 1 [suppress_filters] => [ignore_sticky_posts] => 1 [posts_per_page] => -1 [post__not_in] => Array ( [0] => 22 ) [wpv_original_limit] => -1 [wpv_original_offset] => 0 [wpv_original_posts_per_page] => -1 [meta_query] => Array ( [0] => Array ( [key] => wpcf-show-tour [value] => 1 [type] => CHAR [compare] => = ) [1] => Array ( [key] => wpcf-height-meter [value] => 200 [type] => numeric [compare] => < ) [relation] => AND ) [post_status] => Array ( [0] => publish [1] => private ) [orderby] => date [order] => DESC ) [09-Mar-2018 15:04:26 UTC] Array ( [post_type] => Array ( [0] => individual-bike-tour [1] => guided-bike-tour ) [paged] => 1 [suppress_filters] => [ignore_sticky_posts] => 1 [posts_per_page] => -1 [post__not_in] => Array ( [0] => 22 ) [wpv_original_limit] => -1 [wpv_original_offset] => 0 [wpv_original_posts_per_page] => -1 [meta_query] => Array ( [0] => Array ( [key] => wpcf-show-tour [value] => 1 [type] => CHAR [compare] => = ) [1] => Array ( [key] => wpcf-height-meter [value] => 200 [type] => numeric [compare] => < ) [relation] => AND ) [post_status] => Array ( [0] => publish [1] => private ) [orderby] => date [order] => DESC )
Thank you for your time.
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+01:00)
Hi Hendrik
Thanks for that, I understand the issue now. The code I proposed was intended for/expected a single selection for the height option.
I'll need some time to think about a solution to handle multiple selections. I'll get back to it a little later when I have gone through some of the other tickets in the queue.
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+01:00)
Hi Hendrik
I updated the code on my test site to allow for making multiple selections with checkboxes, while also including other filters in the search form, see below.
It was a fun exercise for me but please note that providing code such as this falls very much outside of our support policies, so if you have problems implementing it I won't be able to support it.
/** * Custom filter by height */ function tssupp_filter_thing_by_height( $query_args, $view_settings, $view_id ){ $field = 'wpcf-height'; if ( 152 == $view_id && isset( $query_args['meta_query'] ) ) { foreach( (array)$query_args['meta_query'] as $k=>$v ){ if ( isset( $v['key'] ) && $v['key'] == $field ) { $values = explode( ",", $v['value'] ); $query_args['meta_query'][$k] = array( 'relation' => 'OR' ); if ( in_array( "1", $values ) ) { $query_args['meta_query'][$k][] = array( 'key' => $field, 'value' => 200, 'type' => 'numeric', 'compare' => '<=' ); } if ( in_array( "2", $values ) ) { $query_args['meta_query'][$k][] = array( 'key' => $field, 'value' => array( 200, 500 ), 'type' => 'numeric', 'compare' => 'BETWEEN' ); } if ( in_array( "3", $values ) ) { $query_args['meta_query'][$k][] = array( 'key' => $field, 'value' => 500, 'type' => 'numeric', 'compare' => '>=' ); } } } } return $query_args; } add_filter('wpv_filter_query', 'tssupp_filter_thing_by_height', 101, 3);
Thank you very much Nigel!
The code worked out very well. I've understood the code you writted, but was very unlikely that I would have been able to come with a solution by myself.
Best regards.