I'm trying to modify a div's content everytime when something is added to the woocommerce shopping cart. For this example the content is gonna be the current total cart value.
So first I created a simple plugin called "test-cart-value" which contains the following code:
<?php
function test_cart_value() {
echo "<div>" . WC()->cart->total . "</div>";
}
add_shortcode('test_cart_value_shortcode', 'test_cart_value');
This works fine, wherever I place the shortcode I get the current cart value after page load.
So, now I want this printed value to updated every time something is added to the cart, without reloading the page. The idea was to use the action hook woocommerce_cart_updated and call the function - so everytime something in the cart changes, the new cart value gets echoed:
function action_woocommerce_cart_updated() {
test_cart_value();
};
// add the action
add_action( 'woocommerce_cart_updated', 'action_woocommerce_cart_updated', 10, 0 );
The problem is, now I'm not able to dynamically add products to the shopping cart. Whenever I hit the "add to cart" button, the loading animation loads forever.
How to do this properly?
I was trying different approaches with Ajax and different Hooks, but so far nothing worked.
Any Ideas? Thanks in advance!
Edit:
So I tried this as my plugin code
function test_cart_value() {
echo "<div id='cart_test'>" . WC()->cart->total . "</div>";
}
add_shortcode('test_cart_value_shortcode', 'test_cart_value');
// define the actions for the two hooks created, first for logged in users and the next for logged out users
add_action("woocommerce_cart_updated", "cart_update");
// define the function to be fired for logged in users
function cart_update() {
$cart = WC()->cart->total;
$result['type'] = "success";
$result['new_cart'] = $cart;
$result = json_encode($result);
//if I uncomment the "die" function, the page won't load
// die();
}
// Fires after WordPress has finished loading, but before any headers are sent.
add_action( 'init', 'script_enqueuer' );
function script_enqueuer() {
// Register the JS file with a unique handle, file location, and an array of dependencies
wp_register_script( "test_script", plugin_dir_url(__FILE__).'test_script.js', array('jquery') );
// localize the script to your domain name, so that you can reference the url to admin-ajax.php file easily
wp_localize_script( 'test_script', 'myAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' )));
// enqueue jQuery library and the script you registered above
wp_enqueue_script( 'jquery' );
wp_enqueue_script( 'test_script' );
}
And my test_script.js code:
jQuery(document).ready( function() {
jQuery(".ajax_add_to_cart").click( function(e) {
e.preventDefault();
jQuery.ajax({
type : "post",
dataType : "json",
url : myAjax.ajaxurl,
data : {action: "cart_update"},
success: function(response) {
if(response.type == "success") {
jQuery("#cart_test").html(response.new_cart);
}
else {
alert("Your like could not be added");
}
}
});
});
});
So I thought that the cart_update() function should fire when I press the "ajax_add_to_cart" Button, but I get an error 400.
Any ideas?
Thanks!
made it work with woocommerce_add_to_cart_fragments.
Related
I'm using the currency switcher WordPress plugin to change currencies on my website, I want the cart to be cleared once I change the currency. I've been trying for some time now, but can't figure out why it isn't working.
This is my source code in the theme functions.php file
function currency_change_action_callback() {
global $woocommerce;
$url_data=$_POST['url_data'];
$woocommerce->cart->empty_cart();
echo $url_data;
die();
}
add_action( 'wp_ajax_currency_change_action', 'currency_change_action_callback' );
add_action( 'wp_ajax_nopriv_currency_change_action', 'currency_change_action_callback' );
I've also tried creating a javascript file and calling it to my functions.php file. here are my source codes
app.js
$('#alg_currency_select').on('change', function () {
function Clearcart(d){
jQuery.post(
"http://localhost/epay/wp-admin/admin-ajax.php",
//ajaxurl,
{
"action": "clearcart",
"data": d.getAttribute("data-product")
},
function(){
window.location = d.getAttribute("data-href");
}
);
})};
functions.php
function load_javascript() {
wp_register_script('custom', get_template_directory_uri().'/app.js', 'jquery', 1, true);
wp_enqueue_script('custom');
}
add_action('wp_enqueue_scripts', 'load_javascript');
would greatly appreciate it if someone can help me solve the issue of why my cart isn't clearing. thanks.
There are some mistakes in your code and unnecessary things.
In the code below, the jQuery code is now located in a php function and enqueued in WordPress using the WooCommerce wc_enqueue_js() function.
// The jQuery Ajax enqueued code
add_action('template_redirect', 'currency_change_trigger_clear_cart_js' );
function currency_change_trigger_clear_cart_js() {
wc_enqueue_js( "jQuery( function($){
$(document.body).on('change', '#alg_currency_select', function() {
$.ajax({
url: '" . admin_url('/admin-ajax.php') . "',
type: 'POST',
data: {
'action': 'currency_change_clear_cart'
},
success: function(response) {
if( response == 'cleared' ) {
$(document.body).trigger('wc_fragment_refresh'); // Refresh cart
}
// console.log(response);
}
});
});
});" );
}
// Php AJAX receiver: Empty cart
add_action( 'wp_ajax_currency_change_clear_cart', 'currency_change_clear_cart' );
add_action( 'wp_ajax_nopriv_currency_change_clear_cart', 'currency_change_clear_cart' );
function currency_change_clear_cart() {
if( count(WC()->cart->get_cart()) > 0 ) {
WC()->cart->empty_cart();
echo 'cleared';
}
die();
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
I'm using the Super Cache plugin.
For some time I was looking for a solution, but without success. I need to disable the cache for one function in the file functions.php.
add_shortcode('custom_counter', 'example_shortcode');
function example_shortcode() {
// Get custom counter option value
$counter = get_option( 'wc-custom-counter' );
return '<span class="custom-counter">' . $counter . ' rub.</span>';
}
This is shortcode is used on the created custom page. It is necessary that the data output by this shortcode does not fall into the page cache.
Adapted from this old WSE thread, you will find below the complete way to make it working.
Here we display a spinner loading icon that will be replaced by the counter real non cached value through ajax. Javascript stays always active even in a cached page, so it can change anything needed on the page via Ajax or via any detected event. So there is no need to exclude anything in the plugin settings.
The replacement code:
// The shortcode
add_shortcode('custom_counter', 'customer_counter_shortcode');
function customer_counter_shortcode() {
// Start buffering
ob_start();
// Using woocommerce existing animated spinner gif icon
$loading_url = home_url( '/wp-content/plugins/woocommerce/assets/images/select2-spinner.gif' );
// Displaying a "Loading spinner icon + text to be replaced by Ajax value
echo '<span class="custom-counter">
<img id="loading-img" src="'.$loading_url.'" alt="Loading..." style="opacity:0.5; display:inline-block; vertical-align: middle;" />
<span style="opacity:0.5;"> ' . _("loading…") . '</span>
</span>';
?>
<script type="text/javascript">
jQuery( function($){
if (typeof woocommerce_params === 'undefined')
return false;
$.ajax({
type: 'POST',
url: woocommerce_params.ajax_url,
data: {
'action': 'custom_counter',
'custom-counter': true,
},
success: function (result) {
$('.custom-counter').text(result);
console.log('response: '+result); // just for testing | TO BE REMOVED
},
error: function(error){
console.log(error); // just for testing | TO BE REMOVED
}
});
});
</script>
<?php
return ob_get_clean(); // Return the buffered code
}
// The wordpress ajax hooked function (for logged in and non logged users)
add_action('wp_ajax_custom_counter', 'ajax_custom_counter');
add_action('wp_ajax_nopriv_custom_counter', 'ajax_custom_counter');
function ajax_custom_counter() {
if( isset($_POST['custom-counter']) && $_POST['custom-counter'] )
echo get_option( 'wc-custom-counter' ); // Get option value
exit();
}
Code goes in function.php file of your active child theme (or active theme). tested and works.
You cannot exclude a function from cache plugins. Instead you can exclude an URL (in WP Super Cache, go to 'Settings > WP Super Cache > Advanced' - 'Accepted Filenames & Rejected URIs' section).
So, call this function using AJAX instead calling directly and you can exclude the AJAX URL.
Here is the full code.
Add these in theme's functions.php:
add_action('wp_ajax_customer_counter', 'customer_counter_ajax_handler'); // wp_ajax_{action}
add_action('wp_ajax_nopriv_customer_counter', 'customer_counter_ajax_handler'); // wp_ajax_nopriv_{action}
function customer_counter_ajax_handler() {
// Get custom counter option value
$counter = get_option( 'wc-custom-counter' );
echo $counter . ' rub.';
}
Replace all your shortcodes [custom_counter] instances with <span class="customer_counter_shortcode"> </span>.
Add this script to theme's footer.php:
jQuery(function($){
$.ajax({
url : '<?php echo site_url(); ?>/wp-admin/admin-ajax.php', // AJAX handler
data : { action : 'customer_counter' },
type : 'POST',
success : function( $result ){
if( $result ) {
$('.customer_counter_shortcode').html($result);
}
}
});
});
You can then exclude the AJAX URL - /wp-admin/admin-ajax.php?action=customer_counter.
In my woocommerce website, I have changed the cart page, removed the button "update cart" and create 2 buttons to add and remove items of product like I show in this picture:
When I click on the quantity buttons I want to call the same function if I press the button to update the cart.
For this I am using ajax but it doesn't do anything.
First in my function.php file I have this:
function update_my_cart() {
// here update then cart
var_dump("execute");
}
add_action( 'wp_ajax_update_my_cart', 'update_my_cart' ); // If called from admin panel
add_action( 'wp_ajax_nopriv_update_my_cart', 'update_my_cart' );
add_action( 'wp_enqueue_scripts', 'rct_enqueue_scripts' );
if ( ! function_exists( 'rct_enqueue_scripts' ) ) :
function rct_enqueue_scripts() {
wp_enqueue_script( 'rct-js', get_template_directory_uri() . '/js/themeCoffee.js', array(), '1.0', true );
wp_localize_script('rct-js', 'ajax_object', array('ajax_url' => admin_url( 'admin-ajax.php' )));
}
endif;
And in my jquery file I have this:
updatecart = function(qty) {
var currentVal, data, item_hash, request;
currentVal = void 0;
data = void 0;
item_hash = void 0;
currentVal = parseFloat(qty);
request = $.ajax({
url: 'ajax_object.ajax_url',
method: 'POST',
data: {
quantity: currentVal,
action: 'update_my_cart'
},
dataType: 'html'
});
request.done(function(msg) {
alert('cart update ');
});
request.fail(function(jqXHR, textStatus) {
alert('Request failed: ' + textStatus);
});
};
I obtain this error:
Failed to load resource: the server responded with a status of 404 (Not Found)
Because I try to load my_website/cart/ajax_object.ajax_url.
Thanks in advance!
You have forget this essential process:
add_action('wp_enqueue_scripts', 'add_my_ajax_scripts');
function add_my_ajax_scripts() {
// Here you register your script located in a subfolder `js` of your active theme
wp_enqueue_script( 'ajax-script', get_template_directory_uri().'/js/script.js', array('jquery'), '1.0', true );
// Here you are going to make the bridge between php and js
wp_localize_script( 'ajax-script', 'cart_ajax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
}
Then you will retrieve "ajaxurl" and "cart_ajax" in your javascript file in "url:":
$.ajax({
url: cart_ajax.ajaxurl,
...
})
Your javascript function will not work. Here are some functional examples of what you need to do:
WooCommerce - auto update total price when quantity changed?
Wordpress passing ajax value to a specific page using Wordpress
Using AJAX With PHP on Your WordPress Site Without a Plugin
How to use Ajax with your WordPress Plugin or Theme?
Since WooCommerce 2.6.0, released June 2016, WooCommerce cart page uses Ajax to update cart totals after clicking on Update cart button.
It's no longer needed to create your own Ajax call, the one assigned to Update cart button can be used.
I created a free plugin Ajax Cart AutoUpdate for WooCommerce which updates cart page and mini cart after changing product quantity and provides some customization options for this process.
The most important thing is to set update delay. If user changes quantity again during this delay, it will be reset to full duration. If it's not implemented and you change quantity from 1 to 10 by clicking on increment button, it will trigger 9 Ajax calls instead of 1.
JQuery code is below, I suggest placing it in js file and enqueuing in dependency with jQuery, then it works with jQuery deferred:
var timeout;
jQuery('div.woocommerce').on('change keyup mouseup', 'input.qty', function(){ // keyup and mouseup for Firefox support
if (timeout != undefined) clearTimeout(timeout); //cancel previously scheduled event
if (jQuery(this).val() == '') return; //qty empty, instead of removing item from cart, do nothing
timeout = setTimeout(function() {
jQuery('[name="update_cart"]').trigger('click');
}, 1000 );
});
I am customizing woocommerce wp right now and I have a problem.
How do I check woocommerce cart using jQuery? The reason why I need to do this is I want to make some animations for the site using jQuery when user clicks on the product add to cart button.
The scenario is like:
A user adds a product and this site I'm developing only gives 1 products, meaning you cant buy more than (1) product at a time. So when a user is done clicking or buying a product and back to home/product page and clicks the add to cart button on the other product I want something to popup using jQuery. My problem is I don't know how to do it. Thank you in advance for your answers.
modify your product or home page and add your on own button with onclick function with product id as a parameter.
make an ajax call in that function .
function somefunction(productid) {
$.ajax({
type : "post",
url: 'wwww.siteurl.com/wp-admin/admin-ajax.php',
data: {
action: 'myajax',pid:productid
},
success: function(data){
alert(data); // this is error message user will see.use javascript to make popup
},
error: function(MLHttpRequest, textStatus, errorThrown){
alert(errorThrown);
}
});
}
in your function.php
function myajax() {
$product_id = $_POST['pid'];
if(WC()->cart->cart_contents_count <1) {
WC()->cart->add_to_cart( $product_id );
echo "success";
die();
}
else {
echo "Not more then one product can be added"; // this is the error will return to jquery function //
die();
}
}
add_action('wp_ajax_myajax', 'myajax');
add_action('wp_ajax_nopriv_myajax', 'myajax');
hope this help ...
I'm trying to make the following happen in a WordPress page:
User clicks on a "sort posts by" button
Value from the button is sent to sortFilter.php page
Current page is refreshed and uses the value posted in sortFilter.php to create a new loop.
On the initial page there is a tag that I want to load the data into:
<p id="sortFilter"></p>
Here is the code I'm using, and it doesn't seem to be working (nothing is being loaded into the #sortFilter p)
$(document).ready(function() {
setInterval(function(){
$("#sortFilter").load("http://<?php echo $_SERVER[HTTP_HOST]; ?>/sort-filter/");
},1000);
//Filter Categories
$.ajaxSetup({cache:true});
$('#byAuthorCtrl ul li').click( function() {
$.post("http://<?php echo $_SERVER[HTTP_HOST]; ?>/sort-filter/", {id: "testValue"}
);
});
});
then on sortFilter.php:
<?php
/*
Template Name: sortFilter
*/
$id = $_POST['id'];
echo $id;
?>
Right now I'm just using a test value to try to post to the page.
WordPress has built in AJAX capabilities. Send your ajax request to /wp-admin/admin-ajax.php using POST with the argument 'action':
jQuery(document).ready(function(){
jQuery.ajax({
type:'POST',
data:{
action:'my_unique_action',
id:'testValue'
},
url: "http://mysite/wp-admin/admin-ajax.php",
success: function(value) {
jQuery(this).html(value);
}
});
});
Then hook it in the plugin like this if you only want it to work for logged in users:
add_action('wp_ajax_my_unique_action','doMyCustomAjax');
or hook it like this to work only for non-logged in users:
add_action('wp_ajax_nopriv_my_unique_action','doMyCustomAjax');
Use both if you want it to work for everybody.
Here's the doAjax function, for example:
function doMyCustomAjax(){
$id = ( isset( $_POST['id'] ) ) ? $_POST['id'] : '';
if( empty( $id ) )
return;
echo $id;
}
Put that in functions.php too. That will return the id you send in AJAX.
admin-ajax.php uses some action names already, so make sure you look through the file and don't use the same action names, or else you'll accidentally try to do things like delete comments, etc.
EDIT
Put the add_action lines in the functions.php file. The admin-ajax.php file will run some functions and then runs the hook that your 'action' value makes, then kills the script. I've modified the code above to reflect this information.
Ok... sorry to use the Answer to add a comment, but it will be much easier to elaborate with the code display here.
So, I have the following in my functions.php:
add_action('wp_ajax_my_unique_action','doMyCustomAjax');
function doMyCustomAjax(){
$id = ( isset( $_POST['id'] ) ) ? $_POST['id'] : '';
if( empty( $id ) )
return;
echo $id;
}
the following script in footer.php to be executed on my category archive:
<script type="text/javascript">
$(document).ready(function() {
//Filter Categories
$.ajaxSetup({cache:true});
$('#byAuthorCtrl ul li').click( function() {
jQuery.ajax({
type:'POST',
data:{id:'my_unique_action'},
url: "http://www.theknotcollective.com/wp-admin/admin-ajax.php",
success: function(value) {
jQuery(this).html(value);
}
});
});
});
</script>
and the following at the top of my category.php:
<p id="sortFilter"><?php doMyCustomAjax(); ?></p>
Again my goal is to post that "id" variable once the link is clicked, then retrieve it once the page has been reloaded, in order to end up with a different loop on page refresh.
I'm new to ajax and this type of PHP function so I don't quite understand what's going on here, and obviously I'm missing something / doing something wrong. If you could elaborate a little I'd really appreciate it!
Thx!