I need to create a custom WordPress search form, with multiple text input fields. Each text field should search its corresponding meta key. Frontend would look like this:
Search form:
<form role="search" action="/" method="get" id="searchform">
<input type="text" name="s" placeholder="Name"/>
<input type="text" name="hometown" placeholder="Hometown"/>
<input type="text" name="branch" placeholder="Branch of Service"/>
<input type="text" name="birth" placeholder="Birth Year"/>
<input type="text" name="casualty" placeholder="Casualty Year"/>
<input type="text" name="location" placeholder="Casualty Location">
<input type="hidden" name="post_type" value="veterans" />
<input type="submit" alt="Search" value="Search" />
</form>
The "Name" field should search the post title only. The rest of the input fields would search a specific custom meta key. It would use an "AND" relationship when multiple fields are used.
Is this possible? Here is what I have tried, but it doesn't search if the name ("s") is empty, and it doesn't seem to be affected at all by what I enter into the custom fields for Hometown or Branch.
// register query vars
function sm_register_query_vars( $vars ) {
$vars[] = 'hometown';
$vars[] = 'branch';
return $vars;
}
add_filter( 'query_vars', 'sm_register_query_vars' );
// pre get posts
function sm_pre_get_posts( $query ) {
if ( is_admin() || ! $query->is_main_query() ){
return;
}
if ( !is_post_type_archive( 'veterans' ) ){
return;
}
$meta_query = array();
// add meta_query elements
if( !empty( get_query_var( 'hometown' ) ) ){
$meta_query[] = array( 'key' => 'hometown', 'value' => get_query_var( 'hometown' ), 'compare' => 'LIKE' );
}
if( !empty( get_query_var( 'branch' ) ) ){
$meta_query[] = array( 'key' => 'branch', 'value' => get_query_var( 'branch' ), 'compare' => 'LIKE' );
}
if( count( $meta_query ) > 1 ){
$meta_query['relation'] = 'AND';
}
if( count( $meta_query ) > 0 ){
$query->set( 'meta_query', $meta_query );
}
}
add_action( 'pre_get_posts', 'sm_pre_get_posts', 1 );
// the search form (display via shortcode)
function sm_search_form( $args ){
$output = '<form id="smform" action="' . esc_url( home_url() ) . '" method="GET" role="search">';
$output .= '<div class="smtextfield"><input type="text" name="s" placeholder="Name" value="' . get_search_query() . '" /></div>';
$output .= '<div class="smtextfield"><input type="text" name="hometown" placeholder="Hometown" value="' . get_search_query() . '" /></div>';
$output .= '<div class="smtextfield"><input type="text" name="branch" placeholder="Branch" value="' . get_search_query() . '" /></div>';
$output .= '<input type="hidden" name="post_type" value="veterans" />';
$output .= '<p><input type="submit" value="Search" class="button" /></p></form>';
return $output;
}
The above query looks like this when attempting to search:
site.com/?s=john+doe&branch=army&hometown=new+york&post_type=veterans
After checking if there are any terms in your search by something like
if($_GET['myfield'])...
try storing each type of your search in a var and then build a custom query with all the items that are in your search. ie :
<?php
$title=$_GET['name']; // Get the name
$params=[]; // Create an array with all the parameters you've got except the name
function populate_array($term) // Create a function to populate your array
{
if ($_GET[$term]) {
$params[$term] = $_GET[$term];
}
}
populate_array('hometown');
populate_array('branch');
//(...)
$args=array( // Initialize your query
'post_type' => 'my_post_type', // Just set your post type if needed
);
if($title){ // If there is a title add it to the query
$args['title']=$title;
}
if(count($params)>0){. // If there are any params
$meta=array('relation'=>'AND'); // Because you asked for it
foreach($params as $param => $value){
$meta[]=array( // Adding each meta tou your query
'key' => $param, // considering you name your meta as your parameter
'value' => $value,
'compare' => '='
);
}
$args['meta_query']=$meta; // Adding your meta to your main query
}
$query = new WP_Query( $args ); // And now you can request your query with all your parameters
I have not tested this but it should work... Maybe some improvements are needed. Test it and come back to me :)
Related
Here is the code that I find to create a Form on the frontend page in WordPress to allow guests (visitors) to publish posts on the Blog section without logging in.
it has actually 3 steps and I applied it on WordPress Theme twenty twenty-two default theme.
but unfortunately, the Form shortcode does not apply to my mentioned section and it applies after my Body
tag (no matter where I callback the shortcode in Gutenberg).
So I have no idea about the Solution :(
Note: I don't want to do this by using any type of plugin... I know it sounds crazy but no plugin, please...
Step 1:
add bellow code to end line of my functions.php in 2022 WordPress Theme
//Add Shortcode-Form
require get_template_directory() . '/shortcode-form.php';
Step 2: Create shortcode-form.php file in theme's main folder
Step 3: add bellow lines to it:
add_shortcode( 'themedomain_frontend_post', 'themedomain_frontend_post' );
function themedomain_frontend_post() {
themedomain_post_if_submitted(); ?>
<form id="new_post" name="new_post" method="post" enctype="multipart/form-data">
<p><label for="title"><?php echo esc_html__( 'Title', 'theme-domain' ); ?></label><br />
<input type="text" id="title" value="" tabindex="1" size="20" name="title" />
</p>
<?php wp_editor( '', 'content' ); ?>
<p><?php wp_dropdown_categories( 'show_option_none=Category&tab_index=4&taxonomy=category' ); ?></p>
<p><label for="post_tags"><?php echo esc_html__( 'Tags', 'theme-domain' ); ?></label>
<input type="text" value="" tabindex="5" size="16" name="post_tags" id="post_tags" />
</p>
<input type="file" name="post_image" id="post_image" aria-required="true">
<p><input type="submit" value="Publish" tabindex="6" id="submit" name="submit" /></p>
</form>
<?php
}
and:
function themedomain_post_if_submitted() {
// Stop running function if the form wasn't submitted
if ( ! isset( $_POST['title'] ) ) {
return;
}
// Add the content of the form to $post as an array
$post = array(
'post_title' => $_POST['title'],
'post_content' => $_POST['content'],
'post_category' => array( $_POST['cat'] ),
'tags_input' => $_POST['post_tags'],
'post_status' => 'draft', // Could be: publish
'post_type' => 'post', // Could be: 'page' or your CPT
);
$post_id = wp_insert_post( $post );
// For Featured Image
if ( ! function_exists( 'wp_generate_attachment_metadata' ) ) {
require_once ABSPATH . 'wp-admin' . '/includes/image.php';
require_once ABSPATH . 'wp-admin' . '/includes/file.php';
require_once ABSPATH . 'wp-admin' . '/includes/media.php';
}
if ( $_FILES ) {
foreach ( $_FILES as $file => $array ) {
if ( $_FILES[ $file ]['error'] !== UPLOAD_ERR_OK ) {
return 'upload error : ' . $_FILES[ $file ]['error'];
}
$attach_id = media_handle_upload( $file, $post_id );
}
}
if ( $attach_id > 0 ) {
update_post_meta( $post_id, '_thumbnail_id', $attach_id );
}
echo 'Saved your post successfully! :)';
}
Here is the shortcode that I use in my gotenburg theme editor:
[themedomain_frontend_post]
Actually WordPress shortcode should run its own callback function, so it except a return variable. In this case you have echo inside callback function, that's why all the output comes at top of the page
Please try the code like bellow
add_shortcode( 'themedomain_frontend_post', 'themedomain_frontend_post' );
function themedomain_frontend_post() {
ob_start();
themedomain_post_if_submitted();
$return = "<form id='new_post' name='new_post' method='post' enctype='multipart/form-data'>
<p><label for='title'>" . esc_html__('Title','theme-domain') . "</label><br />
<input type='text' id='title' value='' tabindex='1' size='20' name='title' />
</p>". wp_editor( '', 'content' ) ."
<p>" . wp_dropdown_categories( 'show_option_none=Category&tab_index=4&taxonomy=category' ) ."</p>
<p><label for='post_tags'>" . esc_html__('Tags','theme-domain') . "</label>
<input type='text' value='' tabindex='5' size='16' name='post_tags' id='post_tags' /></p>
<input type='file' name='post_image' id='post_image' aria-required='true'>
<p><input type='submit' value='Publish' tabindex='6' id='submit' name='submit' /></p>
</form>";
$return .= ob_get_clean();
return $return;
}
it will solve the issue.
I want to search posts by custom field type.
I have custom field "country "with a custom post type umrahpackage now I want if a visitor search for a country "abc" its should show all posts with abc country.
here is my code but not working.
`
add_shortcode('user_search','My_User_search');
function My_User_search($atts = null)
{
$out = user_search_form();
$args = array(
'post_type' => 'umrahpackage',
'meta_query' => array(
array(
'key' => 'country',
'value' => 'pakistan',
'compare' => 'LIKE',
))
);
$the_query = new WP_Query( $args );
if( $the_query->have_posts() ):
while( $the_query->have_posts() ) : $the_query->the_post();
$out .= '<li>' . get_the_title() . '</li>';
endwhile;
endif;
return $out;
}
//function to display user search form
function user_search_form(){
$metavalue = $metakey = '';
if (isset($_GET['search_by'])){
$metakey = $_GET['search_by'];
}
if (isset($_GET['s_value'])){
$metavalue = $_GET['s_value'];
}
$re = '<div class="user_search"><form action="" name="user_s" method="get">
<label for="search_by">Search by:</label>
<select id="search_by" name="search_by">';
if ($metakey != ''){
$re.= '"';
$re.= ($metakey == "country") ;
}else{
$re .= '
<option value="country">Comapny Name</option>';
}
$re .= '
</select>
<label>Company Name</label>
<input id="s_value" name="s_value" type="text" value="'.$metavalue.'"/>
<input type="hidden" id="user_search" name="post_type" value="umrahpackage" />
<input id="submit" type="submit" value="Search" />
</form></div>';
return $re;
}`
I solved it I share it if its help some one else
add_shortcode('user_search','My_User_search');
function My_User_search($atts = null){
$out = user_search_form();
$args = array('post_type' => 'umrahpackage','order' => 'asc',
'meta_query' => array(
array(
'key' => 'country',
'value' => $_GET['s_value'],
'compare' => 'Like',
)
)
);
$the_query = new WP_Query( $args );
if( $the_query->have_posts() ):
while( $the_query->have_posts() ) : $the_query->the_post();
if($_GET['s_value']==''){
//before search hide the posts
}
else {
$out .= '<li>' . get_the_title() . '</li>';
}
endwhile;
endif;
return $out;
}
function user_search_form(){
$re = '<div class="user_search"><form action="" name="user_s" method="get">
<label for="search_by">Search by:</label>
<div id="search_by" name="search_by">';
$re .= '
<label>Company Name</label>
<input id="s_value" name="s_value" type="text" value="'.$metavalue.'"/>
<input name="user_search" id="user_search" type="hidden" value="umrahpackage"/>
<input id="submit" type="submit" value="Search" />
</form></div>';
return $re;
}
?>
I'm trying to make the default wp_dropdown_categories select dropdown as a radio input with submit button.
This is on the front end.
<form id="filter-select" class="filter-select" action="<?php echo esc_url( home_url( '/' ) ); ?>" method="get">
<?php wp_dropdown_categories(); ?>
<input type="submit" name="submit" value="view" />
</form>
Then in my functions.php I tried to do this
add_filter( 'wp_dropdown_cats', 'dropdown_filter', 10, 2);
function dropdown_filter( $output, $r ) {
$output = preg_replace( '/<option/i', '<input type="radio"', $output );
$output = str_replace( 'class="level-0"', 'name="filter"', $output );
$output = str_replace( "value=\"{$value}\"", "value=\"{$value}\" selected", $output );
return $output;
}
This actually works in swapping out the select dropbox for a radio field. But it does not actually work correctly.
Instead of going to /category/CATEGORYNAME - Like the default select box does.
It goes /?filter=6&submit=view
Any advice is greatly appreciated, thank you.
Try with a custom Walker to output category names instead of IDs.
<div class="radiobuttons">
<?php
$args = array(
'orderby' => 'name',
'hide_title_if_empty' => true,
'title_li' => '',
'walker' => new List_Categories_Radiobuttons
);
wp_list_categories( $args );
?>
</div>
The custom Walker in functions.php:
/**
* Custom Walker to list categories with radio buttons
*/
class List_Categories_Radiobuttons extends Walker_Category {
function start_el(&$output, $category, $depth=0, $args=array()) {
$category_name = esc_attr( $category->name );
$radiobutton = '<input type="radio" name="filtercategory" value="' . $category_name . '">';
$output .= '<div class="radiobutton">' . $radiobutton;
}
function end_el(&$output, $category, $depth=0, $args=array()) {
$output .= "</div>\n";
}
}
Does this point you in the right direction?
I wanted to use the image as an option to check in contact form 7. I searched and found the way to do that with radio button. I made the changes in the code, and it does work as a checkbox, but it is only sending one value when submitting the form, not the multiple values.
This is the code I am using. Please tell me what needs to be changed.
function add_shortcode_imagecheckbox() {
wpcf7_add_shortcode( 'imagecheckbox', 'imagecheckbox_handler', true );
}
add_action( 'wpcf7_init', 'add_shortcode_imagecheckbox' );
function imagecheckbox_handler( $tag ){
$tag = new WPCF7_FormTag( $tag );
$atts = array(
'type' => 'checkbox',
'name' => $tag->name,
'list' => $tag->name . '-options' );
$input = sprintf(
'<input %s />',
wpcf7_format_atts( $atts ) );
$datalist = '';
$datalist .= '<div class="imgcheckbox">';
foreach ( $tag->values as $val ) {
list($checkboxvalue,$imagepath) = explode("!", $val
);
$datalist .= sprintf(
'<label><input type="checkbox" name="%s" value="%s" class="hidecheckbox" /><img src="%s"></label>', $tag->name, $checkboxvalue, $imagepath
);
}
$datalist .= '</div>';
return $datalist;
}
it's a bit late but I've had this problem right now
in input name add []
$datalist .= sprintf(
'<label><input type="checkbox" name="%s[]" value="%s" class="hidecheckbox" /><img src="%s"></label>', $tag->name, $checkboxvalue, $imagepath
);
That code work only set a variable not by form.
function.php
<?php
function title_filter( $where, &$wp_query ) {
global $wpdb;
if ( $search_term = $wp_query->get( 'search_title' ) ) {
$where .= ' AND ' . $wpdb->posts . '.post_title LIKE \'%' . esc_sql( like_escape( $search_term ) ) . '%\'';
}
return $where;
}
add_filter( 'posts_where', 'title_filter', 10, 2 );
?>
form.php
<form role="search" method="get" id="form_percorsi" action="<?php bloginfo('url'); ?>/category/percorsi/" style="float:left;margin-right:10px;">
<h1>Search</h1>
<input placeholder="Cerca…" value="" id="search_them" name="search_title" title="Search for:" type="search">
</form>
my query for display items
$search_them = $_GET['search_them'];
$args = array( 'paged' => $paged, 'orderby' => $order_by, 'order' => $order, 'search_title' => $search_them );
if i search a title by form non work...
have a solution?