I'm trying to add custom data to woocommerce fragment with ajax, but I don't know how to pass it properly. I found topic with similar question, but it doesn't work for me.
https://stackoverflow.com/questions/61632687/woocommerce-ajax-add-to-cart-with-additional-custom-data
this is my jquery
jQuery(document).ready(function($) {
$('.single_add_to_cart_button').on('click', function(e){
e.preventDefault();
var thisbutton = $(this),
$form = thisbutton.closest('form.cart'),
id = thisbutton.val(),
product_qty = $form.find('input[name=quantity]').val() || 1,
product_id = $form.find('input[name=product_id]').val() || id,
variation_id = $form.find('input[name=variation_id]').val() || 0;
var data = {
action: 'ql_woocommerce_ajax_add_to_cart',
product_id: product_id,
product_sku: '',
quantity: product_qty,
variation_id: variation_id,
name: 'Tom',
};
$.ajax({
type: 'post',
url: wc_add_to_cart_params.ajax_url,
data: data,
beforeSend: function (response) {
thisbutton.removeClass('added').addClass('loading');
},
complete: function (response) {
thisbutton.addClass('added').removeClass('loading');
},
success: function (response) {
if (response.error & response.product_url) {
window.location = response.product_url;
return;
} else {
$(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, thisbutton]);
}
console.log( wc_add_to_cart_params.ajax_url, data);
},
});
});
});
this is my function
add_action('wp_ajax_ql_woocommerce_ajax_add_to_cart', 'ql_woocommerce_ajax_add_to_cart');
add_action('wp_ajax_nopriv_ql_woocommerce_ajax_add_to_cart', 'ql_woocommerce_ajax_add_to_cart');
function ql_woocommerce_ajax_add_to_cart() {
$product_id = apply_filters('ql_woocommerce_add_to_cart_product_id', absint($_POST['product_id']));
$quantity = empty($_POST['quantity']) ? 1 : wc_stock_amount($_POST['quantity']);
$variation_id = absint($_POST['variation_id']);
$passed_validation = apply_filters('ql_woocommerce_add_to_cart_validation', true, $product_id, $quantity);
$product_status = get_post_status($product_id);
$cart_item_data['name'] = 'Tom';
if ($passed_validation && WC()->cart->add_to_cart($product_id, $quantity, $variation_id) && 'publish' === $product_status) {
do_action('ql_woocommerce_ajax_added_to_cart', $product_id);
if ('yes' === get_option('ql_woocommerce_cart_redirect_after_add')) {
wc_add_to_cart_message(array($product_id => $quantity), true);
}
WC_AJAX :: get_refreshed_fragments();
} else {
$data = array(
'error' => true,
'product_url' => apply_filters('ql_woocommerce_cart_redirect_after_error', get_permalink($product_id), $product_id));
echo wp_send_json($data);
}
wp_die();
}
I try to pass custom data to woocommerce fragment with ajax, but I don't know how to do it right.
Related
I am trying to create a search bar for a blog, which is working fine if i am logged in, but not when i am not logged out. As logged out user, it returns a empty array with succesed code 200. i shall really appreciated if someone can help me
here is my PHP file
`
function get_ajax_posts() {
$posts_d =array();
// Query Arguments
$args = array(
'post_type' => 'custom_posts',
'post_status' => 'publish',
'posts_per_page' => -1,
'order' => 'DESC',
'orderby' => 'date',
);
// The Query
$ajaxposts = new WP_Query($args); // changed to get_posts from wp_query, because `get_posts` returns an array
if($ajaxposts->have_posts( )){
while($ajaxposts->have_posts( )){
$ajaxposts->the_post();
array_push($posts_d, array(
'title' => get_the_title(),
'url' => get_permalink()
));
}
}
echo json_encode( $posts_d );
exit; // exit ajax call(or it will return useless information to the response)
}
// Fire AJAX action for both logged in and non-logged in users
// add_action('wp_ajax_nopriv_get_ajax_posts', 'get_ajax_posts');
add_action('wp_ajax_get_ajax_posts', 'get_ajax_posts');
add_action('wp_ajax_nopriv_get_ajax_posts', 'get_ajax_posts');
wp_localize_script( 'hello-elementor-child-js', 'script',
array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
`
Here is my javascript code
`
jQuery('#s').on('keyup',function(){
$ajaxurl = "<?php echo admin_url('admin-ajax.php'); ?>"
jQuery.ajax({
type: 'POST',
dataType: "json", // add data type
// url: script.ajax_url,
url: $ajaxurl,
data: { action : 'get_ajax_posts' },
success: function( response ) {
var jobs = '';
var count = 0;
var text = jQuery('#s').val().toLowerCase();
if (!arr || arr.length === 0){
var arr = jQuery(response.filter(function(value){
text = text || null;
return value.title.toLowerCase().includes(text);
}))
};
jQuery.each( arr, function( key, value ) {
if (count == 5){
return false;
} else {
jobs += '<p>' + value.title + '</p>';
count++;
}
} );
jQuery('#livesearch').html(jobs);
}
});
});
`
Edit:
I've solved the problem with wp_add_inline_script. But, Is there a way to get json object as private in a function?
To send ajax requests from theme files we can use wp_localize_script to globally declare our javascript variables.
You need to localize your script.
add_action( 'init', 'load_files' );
function load_files() {
wp_enqueue_script( 'custom-js', PATH_OF_YOUR_FILE , array( 'jquery' ), '1.0.0', true );
wp_localize_script( 'custom-js', 'myVar', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
}
In your js file
jQuery("#s").on("keyup", function () {
let url = myVar.ajax_url; //pass your localize variable for ajax url
jQuery.ajax({
type: "POST",
dataType: "json", // add data type
url: url,
data: { action: "get_ajax_posts" },
success: function (response) {
var jobs = "";
var count = 0;
var text = jQuery("#s").val().toLowerCase();
if (!arr || arr.length === 0) {
var arr = jQuery(
response.filter(function (value) {
text = text || null;
return value.title.toLowerCase().includes(text);
})
);
}
jQuery.each(arr, function (key, value) {
if (count == 5) {
return false;
} else {
jobs += '<p>' + value.title + "</p>";
count++;
}
});
jQuery("#livesearch").html(jobs);
},
});
});
Check and let me know whether the ajax call is working or not.
PHP code
function get_ajax_posts() {
$posts_d =array();
// Query Arguments
$args = array(
'post_type' => 'post', //change post_type with your custom post type
'post_status' => 'publish',
'posts_per_page' => -1,
'order' => 'DESC',
'orderby' => 'date',
);
// The Query
$ajaxposts = new WP_Query($args); // changed to get_posts from wp_query, because `get_posts` returns an array
if($ajaxposts->have_posts( )){
while($ajaxposts->have_posts( )){
$ajaxposts->the_post();
array_push($posts_d, array(
'title' => get_the_title(),
'url' => get_permalink()
));
}
}
echo json_encode( $posts_d );
exit; // exit ajax call(or it will return useless information to the response)
}
// Fire AJAX action for both logged in and non-logged in users
// add_action('wp_ajax_nopriv_get_ajax_posts', 'get_ajax_posts');
add_action('wp_ajax_get_ajax_posts', 'get_ajax_posts');
add_action('wp_ajax_nopriv_get_ajax_posts', 'get_ajax_posts');
add_action( 'wp_enqueue_scripts', 'custom_localize_script' );
function custom_localize_script(){
wp_localize_script( 'hello-elementor-child-js', 'ajax_object', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
}
Javascript code
<script type="text/javascript">
jQuery('#s').on('keyup',function(){
jQuery.ajax({
type: 'POST',
dataType: "json", // add data type
url: ajax_object.ajaxurl,
data: { action : 'get_ajax_posts' },
success: function( response ) {
console.log(response);
var jobs = '';
var count = 0;
var text = jQuery('#s').val().toLowerCase();
if (!arr || arr.length === 0){
var arr = jQuery(response.filter(function(value){
text = text || null;
return value.title.toLowerCase().includes(text);
}))
};
jQuery.each( arr, function( key, value ) {
if (count == 5){
return false;
} else {
jobs += '<p>' + value.title + '</p>';
count++;
}
});
jQuery('#livesearch').html(jobs);
}
});
});
</script>
Also I have shared my working code attachment. Please check and let me know if you find any issue
I made adding multiple items with quantity to the cart using AJAX.
After adding a product, the mini cart isn't updated, but WC_AJAX :: get_refreshed_fragments () is called in function.php and I have a hook to update the cart woocommerce_add_to_cart_fragments.
How to force to update the mini cart or what needs to be fixed in this code.
JS
productsToAdd // array with id and quantity
$(document).on('click', '.buy-tovar', function (e) {
e.preventDefault();
productsToAdd.forEach(function(item){
var data = {
action: 'woocommerce_ajax_add_to_cart',
product_id: item['id'],
quantity: item['quantity']
};
$.ajax({
type: 'post',
url: wc_add_to_cart_params.ajax_url,
data: data,
async: false,
success: function (response) {
$('.buy-tovar').addClass("added");
},
});
});
});
PHP
add_filter( 'woocommerce_add_to_cart_fragments', 'woocommerce_header_add_to_cart_fragment' );
function woocommerce_header_add_to_cart_fragment( $fragments ) {
ob_start();
?>
<a href="<?php echo wc_get_cart_url(); ?>" class="cart">
<div class="img-block">
<img src="<?php echo get_template_directory_uri();?>/image/cart.png" alt="">
<span><?php echo count( WC()->cart->get_cart()); ?></span>
</div>
</a>
<?php
$fragments['a.cart'] = ob_get_clean();
return $fragments;
}
//AJAX
add_action('wp_ajax_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');
add_action('wp_ajax_nopriv_woocommerce_ajax_add_to_cart', 'woocommerce_ajax_add_to_cart');
function woocommerce_ajax_add_to_cart() {
$product_id = apply_filters('woocommerce_add_to_cart_product_id', absint($_POST['product_id']));
$quantity = absint($_POST['quantity']);
$passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $quantity);
$product_status = get_post_status($product_id);
if ($passed_validation && WC()->cart->add_to_cart($product_id, $quantity) && 'publish' === $product_status) {
do_action('woocommerce_ajax_added_to_cart', $product_id);
if ('yes' === get_option('woocommerce_cart_redirect_after_add')) {
wc_add_to_cart_message(array($product_id => $quantity), true);
}
WC_AJAX::get_refreshed_fragments();
} else {
$data = array(
'error' => true,
'product_url' => apply_filters('woocommerce_cart_redirect_after_error', get_permalink($product_id), $product_id));
echo wp_send_json($data);
}
wp_die();
}
I found a solution i added the line in my JS:
$(document.body).trigger('wc_fragment_refresh');
Full code JS
document).on('click', '.buy-tovar', function (e) {
e.preventDefault();
productsToAdd.forEach(function(item){
var data = {
action: 'woocommerce_ajax_add_to_cart',
product_id: item['id'],
quantity: item['quantity']
};
$.ajax({
type: 'post',
url: wc_add_to_cart_params.ajax_url,
data: data,
async: false,
success: function (response) {
$('.buy-tovar').addClass("added");
$(document.body).trigger('wc_fragment_refresh');
},
});
});
});
I'm trying to update my checkout cart's shipping with AJAX...
I've got the action in functions.php
function jwd_update_shipping()
{
WC()->cart->calculate_shipping();
echo "hi";
die();
}
add_action('jwd_update_shipping_callback', 'jwd_update_shipping');
Then in js I call it, like so
jQuery.ajax({
type: "POST",
url: 'MYSITE.com/wp-admin/admin-ajax.php',
data: ({
action: "jwd_update_shipping"
}),
success: function(response) {
console.log("got this: " + response);
if (response.type == "success") {
alert("here");
jQuery('body').trigger('update_checkout');
} else {
alert("fail");
}
},
error: function(request, status, error) {
alert(request.responseText);
}
});
I just get a 0 alerted back at me, which suggests that the AJAX call failed.
First your ajax request is not reaching the related php function… Also you need more things to refresh checkout… Try the following instead:
// The jQuery script that send the Ajax request
add_action( 'wp_footer', 'refresh_shipping_js' );
function refresh_shipping_js() {
// Only on checkout
if( is_checkout() && ! is_wc_endpoint_url() ):
?>
<script type="text/javascript">
jQuery( function($){
if (typeof wc_checkout_params === 'undefined')
return false;
var refresh = 'yes';
$.ajax({
type: "POST",
url: wc_checkout_params.ajax_url,
data: ({
'action': 'updating_shipping',
'refresh_shipping': refresh,
}),
success: function(response) {
if( response === '1' ) {
$(document.body).trigger('update_checkout');
console.log('Success: '+response); // For testing (to be removed)
} else {
console.log('Failled: '+response); // For testing (to be removed)
}
},
error:function(error) {
console.log('Error: '+error); // For testing (to be removed)
}
});
});
</script>
<?php
endif;
}
// function that gets the Ajax data
add_action( 'wp_ajax_updating_shipping', 'updating_shipping' );
add_action( 'wp_ajax_nopriv_updating_shipping', 'updating_shipping' );
function updating_shipping() {
if ( isset($_POST['refresh_shipping']) && $_POST['refresh_shipping'] === 'yes' ){
WC()->session->set('refresh_shipping', '1' );
} else {
WC()->session->set('refresh_shipping', '0' );
}
echo WC()->session->get('refresh_shipping');
die(); // Alway at the end (to avoid server error 500)
}
// Function that refresh session shipping methods data
add_action( 'woocommerce_checkout_update_order_review', 'refresh_shipping_methods', 10, 1 );
function refresh_shipping_methods( $post_data ){
if ( WC()->session->get('refresh_shipping' ) === '1' ) {
foreach ( WC()->cart->get_shipping_packages() as $package_key => $package ){
WC()->session->set( 'shipping_for_package_' . $package_key, false );
}
WC()->cart->calculate_shipping();
}
}
I've removed the standard "Added to cart" message given by WooCommerce. I have then added the code below which is using the Sweet Alert. The idea is to remove all "added to cart" messages and to only use the sweet alert.
Based on "JS alert on ajax add to cart for specific product category count in Woocommerce" answer code by #LoicTheAztec, my code works for the first product added, but not for the following ones. So it works fine when the cart is empty and when adding the first product.
Here's the code I'm using:
// remove add to cart woocommerce message
add_filter('wc_add_to_cart_message_html', '__return_null');
// Wordpress Ajax PHP
add_action('wp_ajax_nopriv_checking_items', 'atc_sweet_message');
add_action('wp_ajax_checking_items', 'atc_sweet_message');
function atc_sweet_message() {
if (isset($_POST['id']) && $_POST['id'] > 0) {
$count = 0;
$product_id = $_POST['id'];
foreach(WC()-> cart-> get_cart() as $cart_item) {
$count += $cart_item['quantity'];
}
}
echo $count;
die();
}
// jQuery Ajax
add_action('wp_footer', 'item_count_check');
function item_count_check() {
if (is_checkout())
return;
?>
<script src="https://unpkg.com/sweetalert2#7.20.1/dist/sweetalert2.all.js"></script>
<script type="text/javascript">
jQuery( function($) {
if ( typeof wc_add_to_cart_params === 'undefined' )
return false;
$(document.body).on( 'added_to_cart', function( event, fragments, cart_hash, $button ) {
$.ajax({
type: 'POST',
url: wc_add_to_cart_params.ajax_url,
data: {
'action': 'checking_items',
'id' : $button.data( 'product_id' )
},
success: function (response) {
if(response == 1 ){
const toast = swal.mixin({
toast: true,
showConfirmButton: false,
timer: 3000
});
toast({
type: 'success',
title: 'Product Added To Cart'
})
}
}
});
});
});
</script>
<?php
}
I tried removing if(response == 1 ){ without success. Any input on this is appreciated.
There was little mistakes in your code on the function for Wordpress Ajax PHP. Try the following:
// remove add to cart woocommerce message
add_filter('wc_add_to_cart_message_html', '__return_null');
// Wordpress Ajax PHP
add_action('wp_ajax_nopriv_item_added', 'addedtocart_sweet_message');
add_action('wp_ajax_item_added', 'addedtocart_sweet_message');
function addedtocart_sweet_message() {
echo isset($_POST['id']) && $_POST['id'] > 0 ? (int) esc_attr($_POST['id']) : false;
die();
}
// jQuery Ajax
add_action('wp_footer', 'item_count_check');
function item_count_check() {
if (is_checkout())
return;
?>
<script src="https://unpkg.com/sweetalert2#7.20.1/dist/sweetalert2.all.js"></script>
<script type="text/javascript">
jQuery( function($) {
if ( typeof wc_add_to_cart_params === 'undefined' )
return false;
$(document.body).on( 'added_to_cart', function( event, fragments, cart_hash, $button ) {
var $pid = $button.data('product_id');
$.ajax({
type: 'POST',
url: wc_add_to_cart_params.ajax_url,
data: {
'action': 'item_added',
'id' : $pid
},
success: function (response) {
if(response == $pid){
const toast = swal.mixin({
toast: true,
showConfirmButton: false,
timer: 3000
});
toast({
type: 'success',
title: 'Product Added To Cart'
})
}
}
});
});
});
</script>
<?php
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
It works now for all ajax added to cart items (and not just the first one).
I am trying to add non-required fields but not sure how to add multiple strings. Adding one is fine but it stops working when I add multiple. Can anyone point out what I may be missing? Below is the code;
jQuery( '#appointment-popup' ).on( 'click', 'input.submit-appointment', function() {
values = {
'name' : '',
'phone' : '',
'email' : '',
'appointment-date' : '',
'approximate-time' : '',
'place' : '',
'additional-notes' : '',
'solutions' : ''
};
areErrors = false;
jQuery.each( values, function( key, value ) {
currentElement = jQuery( '#appointment-form-in-popup form *[name='+ key +']' );
values[key] = currentElement.val();
if( key != 'additional-notes' ) { // put here unrequired fields
if( values[key] != false ) { currentElement.removeClass( 'error' ); }
else {
currentElement.addClass( 'error' );
areErrors = true;
}
}
});
if( areErrors == false ) {
// your action here, for example sending an email...
jQuery.ajax({
url: path_to_template +'/_assets/submit.php',
data: { 'submit': 'appointment-form', 'data': values, 'email': appointment_contact },
type: 'post',
success: function( output ) {
// animation after your action
jQuery.appointmentFormAnimation();
}
});
}
});
jQuery.appointmentFormAnimation = function() {
formHeight = jQuery( '.appointment-popup-content' ).height();
jQuery( '.appointment-popup-content' ).css({ 'minHeight' : formHeight });
jQuery( '#appointment-form-in-popup form' ).fadeOut( 300 );
setTimeout( function() {
jQuery( '#appointment-form-in-popup .thanks' ).fadeIn( 300 );
}, 400 );
}