I have a page with a Search Form searching against a Custom Post type on two fields - "Surname" and "Card Number". My search form is returning the results on the same page via AJAX and it must perform an EXACT Match Search against BOTH fields. Only ONE result should ever be returned. If no data is entered, NO results should be returned:
Two things are not happening the way I want - the search results are not exact match, the search is not being conducted against BOTH fields as an AND but rather against either field as an EITHER / OR, the search is returning more than one result which it should only ever return 1 result, and if I click submit with empty search fields it returns all results instead of NO results:
1) If I leave the search form blank and click SUBMIT, ALL custom post type posts are displayed; I would like the search to not return ANY results if NO search terms are entered or WRONG search terms are entered.
2) I am searching against TWO custom post type fields but the search form displays results that satisfy either of the fields; I need the search form to perform an EXACT MATCH against BOTH fields. Both fields must be required and the search form should return results that are an EXACT MATCH.
3) Only 1 Result should be returned per search query in the Ajax result display. It should never return more than one result since the Card Number search field is unique.
I built this search using Toolset Blocks and not Toolset Views Search. The results content template is built using Toolset Blocks.
When one of the custom fields did not have a value for the search filter, it does not get passed to the view's query. So, we must make sure that the view's query has both fields in its meta_query. The following code should work, and will also reset the views if none of the custom fields were added:
add_filter( 'wpv_filter_query', 'query_have_two_cf', 30, 3 );
function query_have_two_cf( $query_args, $view_settings, $view_id ) {
// Execute this code only for my view id(1173)
$my_view_id = 1718;
$first_field = 'wpcf-book-status';
$second_field = 'wpcf-number-of-pages';
if ( $view_id == $my_view_id ) {
// If no custom fields
if ( !isset( $query_args['meta_query'] ) ) {
$query_args['post__in'] = array(0);
return $query_args;
}
// must contain both fields
if ( my_contains_function( $query_args['meta_query'], $first_field ) && my_contains_function( $query_args['meta_query'], $second_field ) ) {
$query_args['meta_query']['relation'] = 'AND';
} else {
$query_args['post__in'] = array(0);
}
$query_args['meta_query']['relation'] = 'AND';
}
// return the query arguments
return $query_args;
}
Please adapt the following lines to your website:
$my_view_id = 1718;
$first_field = 'wpcf-book-status';
$second_field = 'wpcf-number-of-pages';
You can find the view id in the browser console. Check this screenshot hidden link
For fields, you need to append the field's slug to the Toolset prefix 'wpcf-'. Check this screenshot from my test site hidden link
Let me know what you will get.
Hi Jamal,
Unfortunately I just get a spinning icon - it never ends.
This is the exact code I used:
<?php
/**
* New custom code snippet (replace this with snippet description).
*/
toolset_snippet_security_check() or die( 'Direct access is not allowed' );
// Put the code of your snippet below this comment.
add_filter( 'wpv_filter_query', 'query_have_two_cf', 30, 3 );
function query_have_two_cf( $query_args, $view_settings, $view_id ) {
// Execute this code only for my view id(120428)
$my_view_id = 120428;
$first_field = 'wpcf-surname';
$second_field = 'wpcf-card-number';
if ( $view_id == $my_view_id ) {
// If no custom fields
if ( !isset( $query_args['meta_query'] ) ) {
$query_args['post__in'] = array(0);
return $query_args;
}
// must contain both fields
if ( my_contains_function( $query_args['meta_query'], $first_field ) && my_contains_function( $query_args['meta_query'], $second_field ) ) {
$query_args['meta_query']['relation'] = 'AND';
} else {
$query_args['post__in'] = array(0);
}
$query_args['meta_query']['relation'] = 'AND';
}
// return the query arguments
return $query_args;
}
would you allow me temporary access to your site to check this further? Or provide a Duplicator copy of your website and I'll check it locally.
Your next reply will be private to let you share credentials or download links safely.
I will need to know what view?
What URL on the frontend?
Hi there...
Where do you define my_contains_function?
Even when I pass the URL:
hidden link
It doesn't return any data whereas if I turn off the code snippet this URL returns the exact screen I am looking for
My apologies, I forgot the share it, the full code
function my_contains_function( $meta_query, $field ) {
foreach( $meta_query as $meta ){
if ( isset( $meta['key'] ) && ( $meta['key'] == $field ) )
return true;
}
return false;
}
Thanks Jamal,
Where do I put this code?
The order and indents matter.
Thanks
You can put it before or after the previous code:
<?php
/**
* New custom code snippet (replace this with snippet description).
*/
toolset_snippet_security_check() or die( 'Direct access is not allowed' );
// Put the code of your snippet below this comment.
function my_contains_function( $meta_query, $field ) {
foreach( $meta_query as $meta ){
if ( isset( $meta['key'] ) && ( $meta['key'] == $field ) )
return true;
}
return false;
}
add_filter( 'wpv_filter_query', 'query_have_two_cf', 30, 3 );
function query_have_two_cf( $query_args, $view_settings, $view_id ) {
// Execute this code only for my view id(120428)
$my_view_id = 120428;
$first_field = 'wpcf-surname';
$second_field = 'wpcf-card-number';
if ( $view_id == $my_view_id ) {
// If no custom fields
if ( !isset( $query_args['meta_query'] ) ) {
$query_args['post__in'] = array(0);
return $query_args;
}
// must contain both fields
if ( my_contains_function( $query_args['meta_query'], $first_field ) && my_contains_function( $query_args['meta_query'], $second_field ) ) {
$query_args['meta_query']['relation'] = 'AND';
} else {
$query_args['post__in'] = array(0);
}
$query_args['meta_query']['relation'] = 'AND';
}
// return the query arguments
return $query_args;
}
Indentation won't matter 🙂
My issue is resolved now. Thank you!
This was a tough one but I am grateful!