I have an ajax form that filters posts based on the category.
Setup:
HTML form
PHP function to echo ouput
jQuery ajax request to load php
function
Question: How can I parse a value to the php function ($test, see below) from within the jQuery ajax function?
Form - Outputs html select field and button to filter posts
<form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" method="POST" id="filter">
<?php
if( $terms = get_terms( 'category', 'orderby=name' ) ) : // to make it simple I use default categories
echo '<select name="categoryfilter"><option>Select category...</option>';
foreach ( $terms as $term ) :
echo '<option value="' . $term->term_id . '">' . $term->name . '</option>'; // ID of the category as the value of an option
endforeach;
echo '</select>';
endif;
?>
<button>Apply filter</button>
<input type="hidden" name="action" value="myfilter">
</form>
<div id="response"></div>
PHP function - Outputs result on button click in HTML form
function misha_filter_function($test){
// Do something with $test, but how to parse it with jQuery into this php function?
$args = array(
'orderby' => 'date', // we will sort posts by date
'order' => $_POST['date'] // ASC или DESC
);
// for taxonomies / categories
if( isset( $_POST['categoryfilter'] ) )
$args['tax_query'] = array(
array(
'taxonomy' => 'category',
'field' => 'id',
'terms' => $_POST['categoryfilter']
)
);
$query = new WP_Query( $args );
if( $query->have_posts() ) :
while( $query->have_posts() ): $query->the_post();
echo '<h2>' . $query->post->post_title . '</h2>';
endwhile;
wp_reset_postdata();
else :
echo 'No posts found';
endif;
die();
}
add_action('wp_ajax_myfilter', 'misha_filter_function');
add_action('wp_ajax_nopriv_myfilter', 'misha_filter_function');
jQuery - Question: how to parse php value $test to the above php function?
jQuery(function($){
$('#filter').submit(function(){
var filter = $('#filter');
$.ajax({
url:filter.attr('action'),
data:filter.serialize(), // form data
type:filter.attr('method'), // POST
beforeSend:function(xhr){
filter.find('button').text('Processing...'); // changing the button label
},
success:function(data){
filter.find('button').text('Apply filter'); // changing the button label back
$('#response').html(data); // insert data
}
});
return false;
});
});
You serialize data so accesed by:
parse_str($_POST['data'], $inputValues); //$inputValues will be array with your form fields
Related
Thanks to the help of stack overflow I was able to make my filter work(Ajax filter for wordpress) but now I want to add a search input that search the titles of my posts (a custom post type called 'Contratistas').
So I have a few questions:
My form for my filter has POST, but the search (i've seen examples) always has GET, so, should I have two separete forms? If so, is there a way for submiting my search without a button? this is my code:
<form id="searchform" method="get" action="<?php echo esc_url( home_url( '/' ) ); ?>">
<input type="text" class="search-field mb-3" name="s" placeholder="Search" value="<?php echo get_search_query(); ?>">
<input type="submit" value="Search" class="mb-3">
</form>
<form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" method="POST" id="filter">
<div class="titulo mb-3">
<h3>Región</h3>
</div>
<?php
if( $terms = get_terms( array( 'taxonomy' => 'region', 'orderby' => 'name' ) ) ) :
echo '<select name="filtroRegion"><option value="">Seleccione una región</option>';
foreach ( $terms as $term ) :
echo '<option value="' . $term->term_id . '">' . $term->name . '</option>'; // ID of the category as the value of an option
endforeach;
echo '</select>';
endif;
?>
<div class="titulo my-3">
<h3>Industrias</h3>
</div>
<?php
if( $terms = get_terms( array( 'taxonomy' => 'industria', 'orderby' => 'name' ) ) ) :
echo '<select name="filtroIndustria"><option value="">Seleccione una industria</option>';
foreach ( $terms as $term ) :
echo '<option value="' . $term->term_id . '">' . $term->name . '</option>'; // ID of the category as the value of an option
endforeach;
echo '</select>';
endif;
?>
<button class="my-3 filtrar">Filtrar</button>
<button>Limpiar filtros</button>
<input type="hidden" name="action" value="myfilter">
</form>
As you can see i have two buttons but i only want the last one ('Filtrar')
I have no idea how to implement the search with the filters so that i can put my results in the same fashion as the one i get from the dropdowns.
Here is my filter:
$args = array(
'orderby' => 'date', // we will sort posts by date
'order' => $_POST['date'], // ASC or DESC
'post_per_page' => -1,
'post_type' => 'contratista'
);
if (!empty($_POST['filtroRegion']) || !empty($_POST['filtroIndustria'])) {
$args['tax_query'] = array();
if (!empty($_POST['filtroRegion'])) {
$args['tax_query'][] = array(
'taxonomy' => 'region',
'terms' => $_POST['filtroRegion']
);
}
if (!empty($_POST['filtroIndustria'])) {
$args['tax_query'][] = array(
'taxonomy' => 'industria',
'terms' => $_POST['filtroIndustria']
);
}
if (count($args['tax_query']) > 1) {
$args['tax_query']['relation'] = 'AND';
}
}
$query = new WP_Query($args);
And my JQuery:
jQuery(function($) {
$('#filter').submit(function() {
var filter = $('#filter');
$.ajax({
url: filter.attr('action'),
data: $('#filter :input').filter(function(index, element) { return $(element).val() != ''; }).serialize(), // form data
type: filter.attr('method'), // POST
beforeSend: function(xhr) {
filter.find('.filtrar').text('Procesando...'); // changing the button label
},
success: function(data) {
filter.find('.filtrar').text('Filtrar'); // changing the button label back
$('#response').html(data); // insert data
}
});
return false;
}
}
Any help or guidance will be very appreciated. Thanks
I got it! Here's my working code in case somebody else needs it!
The answer was VERY simple! I only had to add this:
's' => $_POST['s']
Here is my function
function misha_filter_function(){
$args = array(
'orderby' => 'date', // we will sort posts by date
'order' => $_POST['date'], // ASC or DESC
'post_per_page' => -1,
'post_type' => 'contratista',
's' => $_POST['s'],
);
//Same code as before:
if( !empty($_POST['filtroRegion']) || !empty($_POST['filtroIndustria']) ){
$args['tax_query'] = array();
if(!empty($_POST['filtroRegion']) ){
$args['tax_query'][] = array(
'taxonomy' => 'region',
'terms' => $_POST['filtroRegion']
);
}
}
$query = new WP_Query( $args );
//my post
And my form:
<form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" method="POST" id="filter">
<h3>Buscar</h3>
<input type="text" class="search-field mb-3" name="s" placeholder="Busqueda por nombre" value="<?php echo get_search_query(); ?>">
<div class="titulo mb-3">
<h3>Región</h3>
</div>
<?php
if( $terms = get_terms( array( 'taxonomy' => 'region', 'orderby' => 'name' ) ) ) :
echo '<select name="filtroRegion"><option value="">Seleccione una región</option>';
foreach ( $terms as $term ) :
echo '<option value="' . $term->term_id . '">' . $term->name . '</option>'; // ID of the category as the value of an option
endforeach;
echo '</select>';
endif;
?>
I am creating a card calculator form where you can select a card type and select a quantity and a price is returned.
I am using a csv file for the pricing and I have it all working great. as a simple HTML Form displayed through a shortcode in WordPress.
<?php
// Get CSV
$ch = fopen($standard_csv, "r");
$header_row = fgetcsv($ch);
// Get array of rows
$rows = array_map('str_getcsv', file($standard_csv));
// Remove first row (header row) as we already have this separately
unset( $rows[0] );
?>
<!-- The Form -->
<form action="" method="post" name="calc" id="calc">
Type:
<select name="card" id="card">
<option value="">Please Select</option>
<?php
// Remove first blank cell from $header
unset( $header_row[0] );
foreach ( $header_row as $key => $card ){
echo '<option value="' . $key . '">' . $card . '</option>';
}
?>
</select>
Quantity:
<select name="quantity" id="quantity">
<option value="">Please Select</option>
<?php
foreach ( $rows as $key => $row ){
echo '<option value="' . $key . '">' . $row[0] . '</option>';
}
?>
</select>
<input type="submit" name="get-price" value="Get Price!">
</form>
<?php
if ( isset( $_POST['get-price'] ) ){
$card = $_POST['card'];
$quantity = $_POST['quantity'];
echo 'Price: £' . $rows[$quantity][$card];
}
?>
This is great but I want to display the returned price using AJAX so I do not have to refresh the page when a user requests a price for their chosen card and quantity.
I have my scripts enqueued like so:
wp_enqueue_script( 'custom_script', plugin_dir_url( __FILE__ ) . 'js/custom.js', array('jquery'), '1.0' );
wp_localize_script( 'custom_script-script', 'ajax_object', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ),
add_action('wp_ajax_get_price', 'get_price');
add_action('wp_ajax_nopriv_get_price', 'get_price');
function get_price(){
$card = $_POST['card'];
$quantity = $_POST['quantity'];
return 'Price: £' . $rows[$quantity][$card];
}
I have this in my Javascript File
$('#calc').submit(function (event) {
event.preventDefault();
var card = jQuery('#card').val();
var quantity = jQuery('#quantity').val();
jQuery.ajax({
type: 'POST',
url: ajax_object.ajax_url,
data: {
action: 'get_price',
card: card,
quantity: quantity
},
success: function (data) {
console.log(data);
},
error: function (errorThrown) {
console.log(data);
alert(errorThrown);
}
});
});
I have totally confused myself and I have tried to follow many tutorials, but I just cant work out the correct logic to be able to output a price from the CSV file using AJAX without reloading the page.
I know this code is totally not right, but please any help to set me in the right direction would be extremely appreciated.
I just need help understanding the logic on how to handle passing the variables and prices between the ajax and the php function in order to return a price from the CSV File.
Thank you.
Don't return from ajax - exit.
Replace return 'Price: £' . $rows[$quantity][$card];
with
wp_die('Price: £' . $rows[$quantity][$card]);
Best wishes,
Mitchell
I am trying to build a simple interface in Woocommerce where a product gets added straight to the mini cart next to it with AJAX, rather than having the page refresh every time you add an item to the cart. Unfortunately I cannot get the AJAX to work and the page just keeps refreshing.
woocommerce.php - the default woocommerce page:
<?php
//LOOP THROUGH ALL PRODUCTS
$args = array( 'post_type' => 'product');
$loop = new WP_Query( $args );
echo "<ul class='mylisting'>";
while ( $loop->have_posts() ) : $loop->the_post();
global $product;
$id = $product->get_id();
$item_name = $product->get_name();
if( $product->is_type( 'variable' ) ){
$class = "variable-product";
} else {
$class = NULL;
}
//OUTPUT PRODUCTS
?>
<li>
<a class="menu-link <?php echo $class; ?>" data-product_id="<?php echo $id; ?>" href="/wpdev/shop/?add-to-cart=<?php echo $id; ?>"><?php echo $item_name." - ".$id; ?></a>
</li>
<?php if( $product->is_type( 'variable' ) ) : ?>
<div id="product-popup-<?php echo $id; ?>" class="product-popup">
<div class="popup-inner">
<?php woocommerce_variable_add_to_cart(); ?>
</div>
</div>
<?php endif; ?>
<?php
endwhile;
echo "</ul>";
wp_reset_query();
?>
<!-- DISPLAY MINI CART -->
<div id="mini-cart-container">
<?php woocommerce_mini_cart(); ?>
</div>
main.js - Main javascript file:
$('.menu-link').click(function(){
jQuery.ajax({
url : woocommerce_params.ajax_url,
type : 'post',
data : {
'action': 'ajax_update_mini_cart'
},
success : function( response ) {
$('#mini-cart-container').html(response);
}
});
});
functions.php
function ajax_update_mini_cart() {
echo wc_get_template( 'cart/mini-cart.php' );
die();
}
add_filter( 'wp_ajax_nopriv_ajax_update_mini_cart', 'ajax_update_mini_cart' );
add_filter( 'wp_ajax_ajax_update_mini_cart', 'ajax_update_mini_cart' );
The goal is to get the woocommerce_mini_cart() function to update with ajax. Is this possible?
I suspect the problem lies with the way I have coded the javascript ajax function, but I'm not sure. Any help would be greatly appreciated.
UPDATE: Moe's solution below has now been added, which has stopped the page reloading but the cart still doesn't update. Echoing some text inside the ajax_update_mini_cart() function does ajax that text inside the mini-cart-container div where the mini-cart should be, which proves (I think) that the javascript function and the php function is working. I think for some reason the problem comes when the echo wc_get_template( 'cart/mini-cart.php' ); is placed inside the function. Does anyone know why this is?
its following the href. try the following
$('.menu-link').click(function(e){
e.preventDefault();
jQuery.ajax({
url : woocommerce_params.ajax_url,
type : 'post',
data : {
'action': 'ajax_update_mini_cart'
},
success : function( response ) {
$('#mini-cart-container').html(response);
}
});
});
So my website lists upcoming film screenings in my area.
I'm using the ACF date time picker to only show posts/film screenings that are in the future in the wordpress loop.
I have tags filtering the results dynamically using ajax (thanks to https://www.bobz.co/ajax-filter-posts-tag/) except there are tags that aren't relevant to the results because they belong to posts that are older than the current date (past screenings).
*For example on the website, the 'animated film festival' is still coming up with the other tags.
I don't know if it's possible to delete a posts tags with PHP (within the post template while it loops through other posts) - and to delete the posts tags if the ACF date time field for that post is older than the current date.
I haven't found much luck googling this and I am a bit of a noob so...
This is my site: http://pigcine.pamrosel.com/
This is what I'm doing in my functions.php file at the moment:
// Get all tags and display
function tags_filter() {
$tax = 'post_tag';
$terms = get_terms( $tax );
$count = count( $terms );
if ( $count > 0 ): ?>
<div class="post-tags">
<?php
foreach ( $terms as $term ) {
$term_link = get_term_link( $term, $tax );
echo '' . $term->name . ' ';
} ?>
</div>
<?php endif; }
// Script for getting posts
function ajax_filter_get_posts( $taxonomy ) {
// Verify nonce
if( !isset( $_POST['afp_nonce'] ) || !wp_verify_nonce($_POST['afp_nonce'], 'afp_nonce' ) )
die('Permission denied');
$taxonomy = $_POST['taxonomy'];
// WP Query
$args = array(
'tag' => $taxonomy,
'post_type' => 'post',
'posts_per_page' => -1,
'meta_key' => 'datetime',
'orderby' => array(
'datetime' => 'ASC'
),
);
// If taxonomy is not set, remove key from array and get all posts
if( !$taxonomy ) {
unset( $args['tag'] );
}
$query = new WP_Query( $args );
if ( $query->have_posts() ) : while($query->have_posts()) : $query>the_post();
$today = date('Y-m-d H:i:s', strtotime('+9 hours'));
$event_date = get_field('datetime');
if (strtotime($today) <= strtotime($event_date)) {
?>
<div class="sl">
<div class="sl_closed">
<div class="col-2-8"><div class="modulepad">
<p><?php the_field('datetime'); ?></p>
</div></div>
<div class="col-3-8"><div class="modulepad">
<p><?php the_title(); ?><br>
<?php $wpmovieinput = get_field('movie_title'); $movie = imdb_connector_get_movie($wpmovieinput); echo implode(", ", $movie["directors"]); ?>
</p>
</div></div>
<div class="col-3-8"><div class="modulepad">
<p><?php the_field('location_name'); ?><br>
<?php $wpmovieinput = get_field('movie_title'); $movie = imdb_connector_get_movie($wpmovieinput); echo implode(", ", $movie["countries"]) . " "; echo $movie["released"] . " "; echo implode(", ", $movie["runtime"]); ?>
</p>
</div></div>
</div><!--SL_CLOSED-->
<?php } endwhile; ?>
<?php else: ?>
<h2>No posts found</h2>
<?php endif;
die();
}
add_action('wp_ajax_filter_posts', 'ajax_filter_get_posts');
add_action('wp_ajax_nopriv_filter_posts', 'ajax_filter_get_posts');
I'm implementing a like button in yii,when i click on the button it calls a controller action which increases the number of likes by 1, i show the changed value in the Button label,how do i do it?
here is my view,what do i change ?
<?php $id =$data->id;
$foo = $data->likes;
echo CHtml::ajaxbutton($foo.' '.'Likes',
array('post/like/'.$id),
array(
'type'=>'POST',
'success'=>'js:function(data){
')
);
?>
You should try the following
<?php $id =$data->id;
$foo = $data->likes;
echo CHtml::ajaxbutton($foo.' '.'Likes',
array('post/like/'.$id),
array(
'type'=>'POST',
'replace'=>'#buttonId')
),
array(
'id'=>'buttonId'
);
?>
However, I suggest using sending parameters as data for AJAX like this:
<?php $id =$data->id;
$foo = $data->likes;
echo CHtml::ajaxbutton($foo.' '.'Likes',
array('post/like),
array(
'type'=>'POST',
'data'=>array("id"=>$id),
'replace'=>'#buttonId')
),
array(
'id'=>'buttonId'
);
?>
http://www.yiiframework.com/doc/api/1.1/CHtml#ajax-detail
replace: string, specifies the selector whose target should be replaced by the AJAX