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 ...
Related
I have a payment form generated by a payment processor which I need to integrate and clicking on the buy button takes the user to an external site for payment.
<input type="hidden" name="order_id" value="0" id="crypto_orderid">
<input type="submit" value="Pay with cryptocurrency" id="buy-btn">
So the user clicks on the button and jquery sends a request to php and order id is returned.
Jquery
$('#buy-btn').click(function() {
generate_invoice();
});
function generate_invoice() {
$.ajax({
url: "./core/create-invoice.php",
type: "POST",
beforeSend: function() {
},
success: function(res) {
try {
var res = JSON.parse(res);
if(res.success) {
$("#crypto_orderid").val(res.id);
alert(res.id);
console.log(res.id);
} else {
alert("unknown error");
}
} catch (e) { }
}
});
}
But the order id doesnt go through as i can see in the external page the order id is not displayed.
However if i do this without ajax try to change the value of order id field then 11 goes though as order id.
Why does the same thing not work with ajax ?
Do i have to make another button to generate the invoice and change the form ? This cant be done with 1 button ?
$('#buy-btn').click(function() {
generate_invoice();
});
function generate_invoice() {
$("#crypto_orderid").val(11);
}
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.
I am trying to create a step in checkout to confirm your order. I'm thinking when the place order button is clicked AND the checkout fields are valid I could run some JS to show a modal or whatever.
Is there a JS trigger/event similar to checkout_place_order that runs after validation? For example, I can use the following but it happens before validation. Maybe there is a way to trigger validation from inside there and display my modal based off that?
var checkout_form = $('form.checkout');
checkout_form.on('checkout_place_order', function () {
// do your custom stuff
return true; // continue to validation and place order
return false; // doesn't validate or place order
});
There is also the woocommerce_after_checkout_validation hook but I am not sure how to utilize it to achieve what I'm after.
I am open to ideas...
I was able to figure this out finally, Its more of a workaround since I don't think there is a clear way to do this.
As soon as the "Place Order" button is clicked, we use the checkout_place_order event to place a hidden field with a value set to 1.
var checkout_form = $('form.checkout');
checkout_form.on('checkout_place_order', function () {
if ($('#confirm-order-flag').length == 0) {
checkout_form.append('<input type="hidden" id="confirm-order-flag" name="confirm-order-flag" value="1">');
}
return true;
});
Next, we use the hook woocommerce_after_checkout_validation to check our hidden input and if the value is 1 add in error (This stops the order from going through).
function add_fake_error($posted) {
if ($_POST['confirm-order-flag'] == "1") {
wc_add_notice( __( "custom_notice", 'fake_error' ), 'error');
}
}
add_action('woocommerce_after_checkout_validation', 'add_fake_error');
Last, we use the checkout_error event to determine if there was a real validation or if if there is only 1 error, the error we added. If there is only 1 error it means validation passed so we can show our modal (or whatever you need to do).
$(document.body).on('checkout_error', function () {
var error_count = $('.woocommerce-error li').length;
if (error_count == 1) { // Validation Passed (Just the Fake Error I Created Exists)
// Show Confirmation Modal or Whatever
}else{ // Validation Failed (Real Errors Exists, Remove the Fake One)
$('.woocommerce-error li').each(function(){
var error_text = $(this).text();
if (error_text == 'custom_notice'){
$(this).css('display', 'none');
}
});
}
});
Inside my modal I have a confirm button that sets our hidden field value to nothing and clicks the place order button again. This time the order will go through because we are checking for the hidden input value of 1.
$('#confirm-order-button').click(function () {
$('#confirm-order-flag').val('');
$('#place_order').trigger('click');
});
As far as I know, there is no hooks in between validation and order creation process, that will allow you to interact with customer, making some actions.
Using jQuery and Sweet Alert component (SWAL 2), here is an example of code that will disable the "Place Order" button displaying a Sweet Alert with confirmation buttons. It's not perfect, but it answers partially your question.
Once customer will confirm, the "Place Order" button will be enabled back and it will be triggered by the codeā¦ If the customer use the cancel button, Checkout review order will be refreshed (Ajax).
The code:
add_action( 'wp_footer', 'checkout_place_order_script' );
function checkout_place_order_script() {
// Only checkout page
if( is_checkout() && ! is_wc_endpoint_url() ):
// jQuery code start below
?>
<script src="https://unpkg.com/sweetalert2#8.8.1/dist/sweetalert2.all.min.js"></script>
<script src="https://unpkg.com/promise-polyfill#8.1.0/dist/polyfill.min.js"></script>
jQuery( function($){
var fc = 'form.checkout',
pl = 'button[type="submit"][name="woocommerce_checkout_place_order"]';
$(fc).on( 'click', pl, function(e){
e.preventDefault(); // Disable "Place Order" button
// Sweet alert 2
swal({
title: 'Are you sure?',
text: "You are about proceed the order",
type: 'success',
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: "Yes let's go!"
}).then((result) => {
if (result.value) {
$(fc).off(); // Enable back "Place Order button
$(pl).trigger('click'); // Trigger submit
} else {
$('body').trigger('update_checkout'); // Refresh "Checkout review"
}
});
});
});
</script>
<?php
endif;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
I'm late to the party, but wanted to share a variation of the answers above
jQuery(document).ready(function($){
/* on submit */
$('form#FORMID').submit( function(e) {
/* stop submit */
e.preventDefault();
/* count validation errors */
var error_count = $('.woocommerce-error li').length;
/* see if terms and conditions are accepted */
var terms = $('input#terms').is(':checked');
/* if there are no validation errors and terms are accepted*/
if( error_count == 0 && terms ) {
/* trigger confirmation dialogue */
if( confirm('Are you sure?') ){
/* resume default submit */
$(this).unbind('submit').submit();
} else {
/* do nothing */
e.stopPropagation();
}
}
});
});
I got a fast and simple JS decision for myself in this case (there were woocommerce and stripe forms). That is based on preventing the checkout button from submit but still makes forms verifications.
// making the wrap click event on dinamic element
$('body').on('click', 'button#place_order_wrap', function(event) {
// main interval where all things will be
var validatoins = setInterval(function(){ happen
// checking for errors
if(no_errors==0){
// making the setTimeout() function with limited time like 200ms
// to limit checkout function for just make verification
setTimeout(function(){
// triggering original button
$('button#place_order').click();
// if there some errors, stop the interval, return false
if(($('element').find('ul.woocommerce_error').length!==0)||($('element').find('.woocommerce-invalid-required-field').length!==0)){
clearInterval(validatoins);
return false;
}else{
no_errors=1;
}
}, 200);
}
if(no_errors==1){
// same error checking
if($('#step5').find('ul.woocommerce_error').length!=0||($('#step5').find('.woocommerce-invalid-required-field').length!==0)){
// if there some errors, stop the interval, return false
clearInterval(validatoins);
return false;
}
setTimeout(function(){
// if no errors
if(($('#step5').find('ul.woocommerce_error').length==0)&&($('#step5').find('.woocommerce-invalid-required-field').length==0)){
// do something, mark that finished
return false;
}
}, 1000);
// if something finished
if() {
setTimeout(function(){
// trigger original checkout click
$('button#place_order').click();
clearInterval(validatoins);
}, 1000);
}
}
}, 1000);
}
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'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!