WooCommerce set cart quantity with AJAX? - javascript

I've now been scratching my head about this for several days and need some pointers.
I'm making a custom theme totally from scratch for a WooCommerce site and now I'm trying to get the cart functionality to work. I'm stuck at trying to have buttons (+/-) for updating the quantity of a product item in the cart.
The problem to me seems to be that the WC() I use inside functions.php is not the same instance as the current frontend-session, or something among those lines. At least my thought for now.
If I've debugged correctly the WC()->cart->set_quantity($cart_item_key, 0) gives no error (if using number 0), all other numbers gives '500 (Internal Server Error)'. But even with 0 quantity in cart is never changed nonetheless.
I've enqueued the scripts correctly so the AJAX function call executes fine when the button is clicked.
Here's my HTML and PHP (simplified)
<div class="cart-items">
<?php foreach(WC()->cart->get_cart() as $cart_item_key => $cart_item) : ?>
<div class="cart-item">
<div class="quantity" id="cart-qty-<?php echo $cart_item_key ?>">
<button class="minus" id="cart-subtract"
onclick="updateCartQuantity('<?php echo $cart_item_key ?>', '<?php echo $cart_item['quantity'] ?>', -1)">-</button>
<p><?php echo $cart_item['quantity'] ?></p>
<button class="plus" id="cart-add">+</button>
</div>
</div>
<? endforeach; ?>
</div>
Here's my JS (inside a file called shopping-ajax.js)
function updateCartQuantity(cart_item_key, current_qty, value) {
function qty_cart() {
jQuery.ajax({
type: "POST",
url: my_ajax_object.ajax_url,
data: {
action: "update_cart",
hash: cart_item_key,
quantity: current_qty,
value: value,
},
success: function (data) {
console.log(data);
},
error: function (data) {
console.log(data);
},
});
}
qty_cart();
}
Here's my PHP function (inside functions.php)
function updateCartQuantity(){
$cart_item_key = $_REQUEST['cart_item_key'];
$quantity = $_REQUEST['quantity'];
$value = $_REQUEST['value'];
WC()->cart->set_quantity($cart_item_key, $quantity + $value);
echo $quantity + $value;
wp_die();
}
add_action( 'wp_ajax_nopriv_update_cart', 'updateCartQuantity' );
add_action( 'wp_ajax_update_cart', 'updateCartQuantity' );
A massive thanks for any help or pointer in advance!

You should manage product qty according to the qty input box(change qty).
My JS:
location: theme directory -> js -> custom.js
jQuery( function( $ ) {
$( document ).on( 'change', 'input.qty', function() {
var $thisbutton = $(this);
var item_hash = $( this ).attr( 'name' ).replace(/cart\[([\w]+)\]\[qty\]/g, "$1");
var item_quantity = $( this ).val();
var currentVal = parseFloat(item_quantity);
$.ajax({
type: 'POST',
url: cart_qty_ajax.ajax_url,
data: {
action: 'my_cart_qty',
hash: item_hash,
quantity: currentVal
},
success: function(response) {
jQuery(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $thisbutton]);
//jQuery(document.body).trigger('update_checkout');
}
});
});
});
fuctions.php -
Setup Enqueue Ajax Scripts:
function enqueue_cart_qty_ajax() {
wp_register_script( 'my_cart_qty-ajax-js', get_template_directory_uri() . '/js/custom.js', array( 'jquery' ), '', true );
wp_localize_script( 'my_cart_qty-ajax-js', 'cart_qty_ajax', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
wp_enqueue_script( 'my_cart_qty-ajax-js' );
}
add_action('wp_enqueue_scripts', 'enqueue_cart_qty_ajax');
Ajax call -
function ajax_my_cart_qty() {
// Set item key as the hash found in input.qty's name
$cart_item_key = $_POST['hash'];
// Get the array of values owned by the product we're updating
$threeball_product_values = WC()->cart->get_cart_item( $cart_item_key );
// Get the quantity of the item in the cart
$threeball_product_quantity = apply_filters( 'woocommerce_stock_amount_cart_item', apply_filters( 'woocommerce_stock_amount', preg_replace( "/[^0-9\.]/", '', filter_var($_POST['quantity'], FILTER_SANITIZE_NUMBER_INT)) ), $cart_item_key );
// Update cart validation
$passed_validation = apply_filters( 'woocommerce_update_cart_validation', true, $cart_item_key, $threeball_product_values, $threeball_product_quantity );
// Update the quantity of the item in the cart
if ( $passed_validation ) {
WC()->cart->set_quantity( $cart_item_key, $threeball_product_quantity, true );
}
// Refresh the page
echo do_shortcode( '[woocommerce_cart]' );
die();
}
add_action('wp_ajax_my_cart_qty', 'ajax_my_cart_qty');
add_action('wp_ajax_nopriv_my_cart_qty', 'ajax_my_cart_qty');

Related

Live WooCommerce Product Search Form using AJAX (Shortcode)

While the search form works, I need help fixing the problem that occurs when the form is empty after having been typed into.
What I mean is this:
If you start typing a search query, you start to get results. This part works fine.
But if you, while / after typing, remove the text from the search form - you get a list of ALL products.
It should only show results if and when typing and show nothing if and when empty.
Fix:
After applying a modified version of the solution offered and provided by Terminator-Barbapapa as per below, it works as intended.
The code below might not be 100% correct, but it works.
The code so far:
add_shortcode('live_search', 'live_search_function');
function live_search_function() { ?>
<input type="text" name="keyword" id="keyword" onkeyup="fetch()"></input>
<div id="productfetch"></div>
<?php
}
add_action( 'wp_footer', 'ajax_fetch' );
function ajax_fetch() { ?>
<script type="text/javascript">
function fetch() {
if( document.getElementById('keyword').value.trim().length == 0 ) {
jQuery('#productfetch').html('');
} else {
jQuery.ajax( {
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'post',
data: { action: 'data_fetch', keyword: jQuery('#keyword').val() },
success: function(data) {
jQuery('#productfetch').html( data );
}
});
}
}
</script>
<?php
}
add_action('wp_ajax_data_fetch' , 'product_fetch');
add_action('wp_ajax_nopriv_data_fetch','product_fetch');
function product_fetch() {
$the_query = new WP_Query( array( 'posts_per_page' => -1, 's' => esc_attr( $_POST['keyword'] ), 'post_type' => 'product' ) );
if( $the_query->have_posts() ) :
while( $the_query->have_posts() ): $the_query->the_post(); ?>
<h2><?php the_title();?></h2>
<?php endwhile;
wp_reset_postdata();
endif;
die();
}
You can add a check in your fetch() function to see if your input field is empty. If so, clear the datafetch div, else run your AJAX.
add_action( 'wp_footer', 'ajax_fetch' );
function ajax_fetch() { ?>
<script type="text/javascript">
function fetch() {
if( document.getElementById('keyword').value.trim().length == 0 ) {
jQuery('#productfetch').html('');
} else {
jQuery.ajax( {
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'post',
data: { action: 'data_fetch', keyword: jQuery('#keyword').val() },
success: function(data) {
jQuery('#productfetch').html( data );
}
});
}
}
</script>
<?php
}

Dynamically load WordPress post content into DIV using HTML select, query, and AJAX

I am trying to figure out how to use WordPress and AJAX to display content (title and ACF fields) from a single post object in a page template using a HTML <select> input with no button or submit. The single post would change each time a different option is selected. The page would need to display the most recent post by default in the div when the page is loaded.
I have included the code I have implemented so far.
My knowledge of AJAX is limited.
Any tips or suggestions?
functions.php
function theme_global_script() {
wp_enqueue_script( 'sendout-ajax', get_template_directory_uri().'/js/sendouts.js', array( 'jquery' ) );
wp_localize_script( 'sendout-ajax', 'frontEndAjax', array('ajaxurl' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce('ajax_nonce') ));
}
add_action( 'wp_enqueue_scripts', 'theme_global_script' );
add_action('wp_ajax_get_ajax_posts', 'get_sendout_posts');
add_action('wp_ajax_nopriv_get_ajax_posts', 'get_sendout_posts');
function get_sendout_posts() {
// Query Arguments
// Select unlimited published posts from category 101 and order by date
$args = array(
'post_status' => array('publish'),
'nopaging' => true,
'numberposts' => '-1',
'order' => 'DESC',
'orderby' => 'date',
'cat' => 101,
);
// The Query
$ajaxposts = new WP_Query( $args );
$response = '';
// The Query
// If query is has results, load the sendouts template part
if ( $ajaxposts->have_posts() ) {
while ( $ajaxposts->have_posts() ) {
$ajaxposts->the_post();
$response .= get_template_part( 'template-includes', 'sendouts' );
}
} else {
$response .= get_template_part( 'none' );
}
echo $response;
exit;
}
Sendout template part HTML
The $post->ID and $post->name would be returned from the WordPress query
<select id="" name="" class="sendout-select">
<option value="[$post->ID]">[$post-name]</option>
<option value="[$post->ID]">[$post-name]</option>
<option value="[$post->ID]">[$post-name]</option>
</select>
<div class="sendout-container">
<!-- Load Post object here -->
</div>
AJAX JavaScript
jQuery(document).ready(function($) {
$( ".sendout-select" ).change(function() {
$.ajax({
type: 'POST',
url: frontEndAjax.ajaxurl,
dataType: 'html',
data: {
action : 'get_sendout_posts'
},
success: function(response) {
console.log(response)
},
error: function(error) {
console.log(error)
}
});
});
});

How to load more logo's with ajax?

I found a solution how to get a load more button that displays more content on click, but it was for posts, I want to make it work for my custom post type 'Klanten'.
I tried editing the code to match my post type, but I get an error: "Undefined index: offset"
functions.php
wp_enqueue_script( 'dfib-theme-custom', get_template_directory_uri() .'/js/custom.js', array('jquery') );
wp_localize_script( 'dfib-theme-custom', 'ajax_object', array('ajax_url' => admin_url('admin-ajax.php')) );
add_action( 'wp_ajax_load_more_posts', 'load_more_posts' );
add_action( 'wp_ajax_nopriv_load_more_posts', 'load_more_posts' );
function load_more_posts(){
global $post;
$args = array('post_type'=>'klanten', 'posts_per_page'=> 4, 'offset'=> $_POST['offset']);
$rst=[];
$query = new WP_Query($args);
if($query->have_posts()):
while($query->have_posts()):$query->the_post();
$rst[] = $post;
endwhile;
wp_reset_postdata();
$offset = $_POST['offset']+4;
endif;
wp_send_json_success(array('klanten'=>$rst, 'offset'=>$offset));
}
custom.js
$('#load_more_posts').on('click', function(e){
console.log('hi');
e.preventDefault();
var $offset = $(this).data('offset');
console.log('var'+$offset);
$.ajax({
method: 'POST',
url: ajax_object.ajax_url,
type: 'JSON',
data: {
offset: $offset,
action: 'load_more_posts'
},
success:function(response){
console.log(response);
$('#load_more_posts').data('offset', parseInt(response.data.offset));
}
});
})
php-file
$query = new WP_Query( array(
'post_type' => 'klanten',
'posts_per_page' => 4,
'offset' => 0,
'paged' => 1,
'order' => 'ASC',
'orderby' => 'rand',
) );
if ( $query->have_posts() ) { ?>
<div class="klanten__wrapper">
<?php
while ( $query->have_posts() ) :
$query->the_post();
?>
<div class="logo__wrapper">
<img class="klant__logo" src="<?php the_post_thumbnail_url(); ?>">
</div>
<?php endwhile; ?>
<div id="load_more_posts" class="loadmore">Load More...</div>
</div>
<?php
wp_reset_postdata();
return ob_get_clean();
}
Console log
I want to show 4 logo's (elements), and load 4 more each time someone clicks the loadmore button
Replace this
<div id="load_more_posts" class="loadmore" data-offset="4">Load More...</div>
You need to return ajax data with logo array and then append data like below code.
AJAX call
$('#load_more_posts').on('click', function(e){
console.log('hi');
e.preventDefault();
var $offset = $(this).data('offset');
console.log('var'+$offset);
$.ajax({
method: 'POST',
url: ajax_object.ajax_url,
type: 'JSON',
data: {
offset: $offset,
action: 'load_more_posts'
},
success:function(response){
console.log(response);
var html = "";
$(response.data.klanten).each(function(index,value) {
html += '<div class="logo__wrapper"> <img class="klant__logo" src="'+value.post_thumbnail+'"></div>'
});
$('.logo_wrapper').append(html);
$('#load_more_posts').data('offset',
parseInt(response.data.offset));
}
});
})
HTML Code
<div class="klanten__wrapper">
<div class="logo_wrapper">
<?php
while ( $query->have_posts() ) :
$query->the_post();
?>
<div class="logo__wrapper">
<img class="klant__logo" src="<?php the_post_thumbnail_url(); ?>">
</div>
<?php endwhile; ?>
<div>
<div id="load_more_posts" class="loadmore">Load More...</div>
</div>
function.php
wp_enqueue_script( 'dfib-theme-custom', get_template_directory_uri() .'/js/custom.js', array('jquery') );
wp_localize_script( 'dfib-theme-custom', 'ajax_object', array('ajax_url' => admin_url('admin-ajax.php')) );
add_action( 'wp_ajax_load_more_posts', 'load_more_posts' );
add_action( 'wp_ajax_nopriv_load_more_posts', 'load_more_posts' );
function load_more_posts(){
global $post;
$args = array('post_type'=>'klanten', 'posts_per_page'=> 4, 'offset'=> $_POST['offset']);
$rst=[];
$query = new WP_Query($args);
if($query->have_posts()):
while($query->have_posts()):$query->the_post();
$rst[] = $post;
$post_thumbnail = get_the_post_thumbnail($post->id);
$rst['post_thumbnail'] = $post_thumbnail;
endwhile;
wp_reset_postdata();
$offset = $_POST['offset']+4;
endif;
wp_send_json_success(array('klanten'=>$rst, 'offset'=>$offset));
}
I got help from a colleague and he figured it out. I added this in my js-file (jQuery)
// Counter for logos
var logoCount = $('.logo__wrapper').length;
var counter = 12;
// Show only first 12 logos
$('.logo__wrapper:nth-of-type(1n+13)').addClass('is-hidden');
// Load more logos button click
$('#load_more_posts').on('click', function (e) {
// Loop hidden logo's
$('.logo__wrapper.is-hidden').each(function (i) {
// Hide button if no more logo's
if (counter++ === logoCount) {
$('#load_more_posts').hide();
$('.loadmore__end').toggle();
}
// Show next 12 logos
if (i < 12) {
$(this).removeClass('is-hidden');
}
// Break loop after 12 logos
else {
return false;
}
});
});

Wordpress AJAX search not working

I am trying to create a search functionality with AJAX so it will load posts. It currently does not show the results.
I took this code from another post and played around with it as the completed code was sent privately.
Any help would be greatly appreciated.
functions.php file code
// the ajax function
add_action('wp_ajax_data_fetch' , 'data_fetch');
add_action('wp_ajax_nopriv_data_fetch','data_fetch');
function data_fetch(){
$the_query = new WP_Query( array( 'posts_per_page' => -1, 's' => esc_attr( $_POST['keyword'] ), 'post_type' => 'post' ) );
if( $the_query->have_posts() ) :
while( $the_query->have_posts() ): $the_query->the_post(); ?>
<h2><?php the_title();?></h2>
<?php endwhile;
wp_reset_postdata();
endif;
die();
}}
Script (in functions.php)
// add the ajax fetch js
add_action( 'wp_footer', 'ajax_fetch' );
function ajax_fetch() {
?>
<script type="text/javascript">
function fetch(){
jQuery.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'post',
data: { action: 'data_fetch', keyword: jQuery('#keyword').val() },
success: function(data) {
jQuery('#datafetch').html( data );
}
});
}
</script>
html
<input type="text" name="keyword" id="keyword" onkeyup="fetch()">
<div id="datafetch">Search results will appear here</div>
You might want to update the method name to 'POST' as javascript is case sensitive
function fetch(){
jQuery.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'POST',
data: { action: 'data_fetch', keyword: jQuery('#keyword').val() },
success: function(data) {
jQuery('#datafetch').html( data );
}
});
}
You also might want to do an async call which needs callback as above approach will do synchronous call. Check this answer for callback approach
jQuery: Return data after ajax call success
there are some typos in your code like an extra } and a mising } later in php code. Please try:
functions.php
// the ajax function
add_action('wp_ajax_data_fetch' , 'data_fetch');
add_action('wp_ajax_nopriv_data_fetch','data_fetch');
function data_fetch(){
$the_query = new WP_Query( array( 'posts_per_page' => -1, 's' => esc_attr( $_POST['keyword'] ), 'post_type' => 'post' ) );
if( $the_query->have_posts() ) :
while( $the_query->have_posts() ): $the_query->the_post(); ?>
<h2><?php the_title();?></h2>
<?php endwhile;
wp_reset_postdata();
endif;
die();
}
// add the ajax fetch js
add_action( 'wp_footer', 'ajax_fetch' );
function ajax_fetch() {
?>
<script type="text/javascript">
function fetch_search() {
jQuery.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'post',
data: { action: 'data_fetch', keyword: jQuery('#keyword').val() },
success: function(data) {
jQuery('#datafetch').html( data );
}
});
}
</script>
<?php
}
html
<input type="text" name="keyword" id="keyword" onkeyup="fetch_search()">
<div id="datafetch">Search results will appear here</div>

The WordPress Ajax request returns 0

I can't figure out why nothing is returned
I am a real beginner in Ajax ..
I just read a lot of topics about using Ajax in Woprdpress but the examples are super advanced for me
Here is my JS code combo_checkout_iRange.js
jQuery(document).ready(function() {
jQuery('#loader').hide();
jQuery('#check-out-date').hide();
jQuery('#check-in-date').change(function(){
jQuery('#check-out-date').fadeOut();
jQuery('#loader').show();
jQuery.ajax({
type: 'POST',
url:myAjax.ajaxurl,
data: {
action : 'my_ajax_handler',
parent_id: jQuery("#check-in-date").val()
},
success: function(data){
alert(data);
jQuery('#loader').hide();
jQuery('#check-out-date').show();
jQuery('#check-out-date').append(data);
}});
return false;
});
jQuery('#check-out-date').change(function(){
alert(jQuery('#check-out-date').val());
});
});
This is what I wrote on function.php
Note: this should work in post type called "meetings"
add_action("wp_enqueue_scripts", function() {
if (is_single()) {
if (get_post_type() == 'meetings')
{
wp_enqueue_script('combo_checkout_iRange', get_template_directory_uri() . '/js/combo_checkout_iRange.js', array( 'jquery' ), '1.0' ,true);
$data_array = array(
'ajaxurl' => admin_url( 'admin-ajax.php' )
);
wp_register_script( 'combo_checkout_iRange', get_template_directory_uri() . '/js/combo_checkout_iRange.js', array('jquery') );
wp_localize_script( 'combo_checkout_iRange', 'myAjax', $data_array );
}
}
});
and this is my ajax handler i put it inside single_meetings.php
add_action("wp_ajax_my_ajax_handler", "my_ajax_handler");
add_action("wp_ajax_nopriv_my_ajax_handler", "my_ajax_handler");
function my_ajax_handler() {
if ( isset($_REQUEST["parent_id"]) ) {
$id = $_REQUEST["parent_id"];
return $id;
die();
}
}
You can't use return in your AJAX callback. The code never gets to die on the line beneath. You need to echo the value instead and then use wp_die().
Replace:
return $id;
die();
With:
echo $id;
wp_die();

Categories

Resources