Remove item from Woocommerce minicart using ajax - javascript

I'm using Woocommerce and I'm trying to remove item from the mini cart using ajax.
By looking at woocommerce minicart.php file I have found the relevant functionality to removing item:
<?php
echo apply_filters( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
'woocommerce_cart_item_remove_link',
sprintf(
'×',
esc_url( wc_get_cart_remove_url( $cart_item_key ) ),
esc_attr__( 'Remove this item', 'woocommerce' ),
esc_attr( $product_id ),
esc_attr( $cart_item_key ),
esc_attr( $_product->get_sku() )
),
$cart_item_key
);
?>
But I can't figure out how to run the command through ajax instead of refreshing the page. I have tried to modify code I found about adding to cart using ajax.
Didn't work, the page still refreshes.
Here is what I have tried:
$(document).on('click', '.remove1', 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: 'woocommerce_cart_item_removed',
product_id: product_id,
product_sku: '',
quantity: product_qty,
variation_id: variation_id,
};
$.ajax({
type: 'post',
url: wc_add_to_cart_params.ajax_url, // What params should I use?
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;
}
},
});
});
functions.php
add_action( 'woocommerce_remove_cart_item', 'update_cart', 10, 2 );
function update_cart(){
//What to do here?
}
No debugging errors.
Few important things I haven't found information online for:
Which ajax url url: wc_add_to_cart_params.ajax_url should I use to remove item from mini cart?
How to handle the data transferred from the ajax to functions.php?
How can I remove item from Woocommerce mini cart using ajax?

First of all, please check your WooCommerce settings to see if Ajax enables the add-to-cart button. If not, Enable it from the admin panel. Check out the screenshot click here to see the screenshot of admin panel setting for ajax
Then try to remove the product from the cart.

Related

Why are there no problems with Ajax on the desktop, but have on the phone?

There is a button on the site, when you click on that button, new posts are loaded.Everything works fine on the desktop, but it breaks down on the phone.
XHR failed loading: POST "https://test-5.vbbn.in/wp-admin/admin-ajax.php".
send # jquery.js?ver=1.12.4-wp:4
ajax # jquery.js?ver=1.12.4-wp:4
n. # jquery.js?ver=1.12.4-wp:4
(anonymous) # (index):1732
dispatch # jquery.js?ver=1.12.4-wp:3
r.handle # jquery.js?ver=1.12.4-wp:3
add_action( 'wp_footer', 'my_action_javascript' );
function my_action_javascript() { ?>
<script>
jQuery(document).ready(function($) {
var page = 2;
var post_count = jQuery('#posts').data('count');
var ajaxurl = "<?php echo admin_url('admin-ajax.php');?>"
jQuery('#load_more').click(function () {
var data = {
'action': 'my_action',
'page': page
};
jQuery.post(ajaxurl, data, function(response) {
jQuery('#posts').append(response);
if (post_count == page){
jQuery('#load_more').hide();
}
page++;
});
});
});
</script> <?php
}
add_action( 'wp_ajax_my_action', 'my_action' );
function my_action() {
$args = array(
'post_type' => 'post',
'category_name'=> 'nouvelles',
'paged' => $_POST['page'],
);
$the_query = new WP_Query( $args ); ?>
<?php if ( $the_query->have_posts() ) : ?>
<?php
while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
Tried to add e.preventDefault, to avoid rebooting that does not write the POST then pass event to the function, but it shows that e.preventDefault is not a function.
Website - https://test-5.vbbn.in/
Hope for any help. thanks
You are trying to hit an url using admin ajax. but url is not returning 200 as response. It is returning 400(not found) . I just tested the url by clicking button. Please see the screenshot below that I attached.
Now fix the issue and be confirm that your action is available for admin-ajax

Disable downlaod link after 5 time clicks Wordpress | Javascripts | Ajax

I am creating a custom wordpress theme and what i want is that; there is a download link, what i want is that users can download only 5 times when the user clicks that link only for 5 times, if the user tries to click the link for the 6th time it automatically hides. I dont have any idea how to do this, also didn't find any relevant solution on google.
here below is my testing code:
<script type="text/javascript">
function myFunction() {
$(document).ready(function(){
$(".gotocls").click(function(){
alert("Hello! I am an alert box!!");
});
});
}
</script>
<a class="dkpdf-button gotocls" onclick="myFunction()" href="downlaod/image.com" target="_blank"><span class="dkpdf-button-icon"><i class="fa fa-file-pdf-o"></i></span> <?php echo $pdfbutton_text;?></a>
i think this might be done with ajax, but i dont have much knowledge of ajax
you don't need onClick in this code I add document.getElementsByClassName('gotocls')[0].style.display = 'none'; when i equals 5 .
$(document).ready(function(){
var i = 0
$(".gotocls").click(function(){
i++
if(i == 5)
document.getElementsByClassName('gotocls')[0].style.display = 'none';
alert("Hello! I am an alert box!!" + i);
});
});
</script>
<a class="dkpdf-button gotocls" id="myLink" href="downlaod/image.com" target="_blank"><span class="dkpdf-button-icon"><i class="fa fa-file-pdf-o"></i></span> <?php echo $pdfbutton_text;?></a>
If you only want to hide the download link in the current session, then simple javascript should do your job.
<script type="text/javascript">
var counter = 0;
function myFunction() {
if(counter === 5){
document.getElementsByClassName('gotocls')[0].style.display = 'none';
}
counter = counter +1;
}
</script>
However when the user refreshes the site, then the download link will be visible again. If you want to store information permanently then you have to use a database.
I wrote the code needed real quick with no tests but it should give you a starting point at least, in your PHP:
/**
* Enqueue a JS file using WP proper action and functions
* 'my-custom-script' can be any name of your fantasy, prepend it with your vendor name and you are good to go
* 'url_to_js_file' MUST be a full URL to your .JS file containing the ajax you need
*/
function our_custom_scripts() {
wp_register_script( 'my-custom-script', 'url_to_js_file.js', array( 'jquery' ), false, true );
wp_localize_script( 'my-custom-script', 'myJsVarName', array(
'ajaxurl' => admin_url( 'admin-ajax.php' ), // Used to make ajax call in WP
) );
wp_enqueue_script( 'my-custom-script' );
}
// Load script
add_action( 'wp_enqueue_scripts', 'our_custom_scripts' );
/**
* What the ajax call will actually trigger thanks to WP AJAX handle
*/
function my_ajax_action() {
/** #var wpdb $wpdb */
global $wpdb;
$clickedLink = $_POST["clicked_link"];
$userId = get_current_user_id();
/*
* Query for the pressed link, that's up to you on how to store data in the database, im going with an easy one
* saving the full link (i would really NOT recommend this :D, its just to show)
*/
$sql = "SELECT * FROM {$wpdb->prefix}my_table_name WHERE link = %s";
$res = $wpdb->get_row( $wpdb->prepare( $sql, array( $clickedLink ) ) );
if ( $canClick = $res["num_pressed"] < 5 ) {
$wpdb->update(
$wpdb->prefix . "my_table_name",
array(
'num_pressed' => ( $res["num_pressed"] + 1 ),
'string_col' => 'val2', //example string col
'int_col' => 3, //example int col
),
array( "user_id" => $userId ), // Where condition
array( "%d", "%s", "%d" ), // updated values format. %s are for strings, %d for integers
array( "%d" ) );// Where condition format
wp_send_json_success();
} else {
wp_send_json_error();
}
}
add_action( 'wp_ajax_my_ajax_action', array( $this, 'my_ajax_action' ) );
add_action( 'wp_ajax_nopriv_my_ajax_action', array( $this, 'my_ajax_action' ) );
Then in your .js file add this:
$(document).ready(function () {
$(".gotocls").click(function (evt) {
var $pressedLink = $(this);
evt.preventDefault(); // Stop doing w/e the browser was trying to do
$.ajax({
url: myJsVarName.ajaxurl,
type: 'POST',
data: {
action: 'my_ajax_action',
clicked_link: $pressedLink.attr("href")
},
timeout: 5000
dataType: 'json',
success: function (response) {
console.log('Your response content', response);
if (response.success) {
window.location.href = $pressedLink.attr("href"); // Proceed with click
}
},
error: function (jqXHR, textStatus, errorThrown) {
}
});
});
});
})(jQuery);
This should cover the PHP and the JS side of your stuff. The rest is up to you, stackoverflow is not a coding factory, it's a community for advices :D

Update Woocommerce product gallery with Ajax

I'm trying to do a dynamic product gallery based on colours in woocommerce product page. When I click on one colour, example on red, i should see Red Gallery's photos.
To do this i replaced all woocommerce gallery block with a new one created by ajax ( who have same classes of old gallery).
The loading of new photos work fine and I get gallery photos based on colour.
But when ajax load new gallery the slider don't work, I think because the woocommere js, who create the slider, is read only on page load.
I think I should reload some Woocommerce JS Function to recreate slider with his functions, but I don't know how.
This is the php file, which one I create a new gallery, called from ajax:
global $product;
$current_id = "";
if(isset($_POST['prodid']) && $_POST['prodid'] != "" ) {
$current_id = $_POST['prodid'];
$product = new WC_Product($current_id);
}
$columns = apply_filters( 'woocommerce_product_thumbnails_columns', 4 );
$post_thumbnail_id = $product->get_image_id();
$wrapper_classes = apply_filters( 'woocommerce_single_product_image_gallery_classes', array(
'woocommerce-product-gallery',
'woocommerce-product-gallery--' . ( $product->get_image_id() ? 'with-images' : 'without-images' ),
'woocommerce-product-gallery--columns-' . absint( $columns ),
'images',
) );
?>
<figure class="woocommerce-product-gallery__wrapper">
<?php
if ( $product->get_image_id() ) {
$html = wc_get_gallery_image_html( $post_thumbnail_id, true );
} else {
$html = '<div class="woocommerce-product-gallery__image--placeholder">';
$html .= sprintf( '<img src="%s" alt="%s" class="wp-post-image" />', esc_url( wc_placeholder_img_src( 'woocommerce_single' ) ), esc_html__( 'Awaiting product image', 'woocommerce' ) );
$html .= '</div>';
}
echo apply_filters( 'woocommerce_single_product_image_thumbnail_html', $html, $post_thumbnail_id ); // phpcs:disable WordPress.XSS.EscapeOutput.OutputNotEscaped
do_action( 'woocommerce_product_thumbnails' );
?>
</figure>
This is the ajax function called on box colour click
function changeGallery(selected_gallery, productID) {
jQuery(function($) {
var select_color = selected_gallery;
var xhttp;
$.ajax({
url : 'https://mysite.it/wp-admin/admin-ajax.php', // AJAX handler
data : { action : 'load_gallery', gallery : select_color, prodid : productID },
type : 'POST',
beforeSend: function() {
},
success : function( result ){
if( result ) {
$('.woocommerce-product-gallery').html(result);
//Reload here some woocommerce JS functions?
}
}
});
});
}
The way to solve issues like this is to look at the WooCommerce source code to see how the plugin initialises the gallery to begin with. Based on this, I think you need to do something like:
jQuery( '.woocommerce-product-gallery' ).each( function() {
jQuery( this ).wc_product_gallery();
} );
See Github: single-product.js for reference.
I had same problem. The dafoxuk answer is correct, you need to reinitialize ProductGallery class on the .woocomorce-product-gallery. The problem was that this element already has a flexslider entity attached to it. To solve this, just remove that element (.woocomorce-product-gallery) and create a new identical one. (Flexslider doesn't have a way to detach itself from the element as far as I know)

Load Template-Part with Ajax in Wordpress

Hi I am trying to add a feature to my store that when someone clicks on a product instead of being redirected to the product page, the product page loads with ajax in the home page like in this website (click on one of the products): http://www.itsjustyes.com. This is my jquery:
jQuery(document).ready(function($){
$('.info_btn').on('click',function(){
var theId = $(this).attr('id');
var div = $('#product-container')
$.post('wp-admin/admin-ajax.php',{
action:'my_get_posts',post_id: theId
}, function(data){
console.log(data);
div.html(data);
})
return false;
});
});
This is my code in functions.php:
//Ajax call to product
function my_get_posts_return()
{
global $post;
$post_id = intval(isset($_POST['post_id']) ? $_POST['post_id'] : 0);
if ($post_id > 0) {
$the_query = new WP_query(array('p' => $post_id));
if ($the_query->have_posts()) {
while ($the_query->have_posts()) : $the_query->the_post();
wc_get_template_part( 'content', 'single-product' );
endwhile;
} else {
echo "There were no posts found";
}
}
wp_die();
}
add_action('wp_ajax_my_get_posts', 'my_get_posts_return');
add_action('wp_ajax_nopriv_my_get_posts', 'my_get_posts_return');
I keep getting that there were no posts found in the loop which is weird cause I know I am sending the right post id. By the way, if I try to get the individual parts of the product page with get_the_title( $post_id ) I get it just fine. It's only when I try to load the template part with the loop that I get this problem. Any idea what I am doing wrong??
Your WP_Query was not finding the correct post type.
$the_query = new WP_query(array('p' => $post_id));
The query above didn't return any post at all. By default, wordpress will assume that you're querying the post_type = 'posts' which is why you cannot find the product post.
Therefore, you need to specify what post_type you're looking for. With WooCommerce product, you can use:
$the_query = new WP_query(array('p' => $post_id, 'post_type' => 'product'));
P.S. It's a good practice to use wp_localize_script function to register your ajaxurl, rather than hard coded in your javascript. You can follow this post for more detail.
Hope this helps.

How do I assign jQuery event handlers properly?

I am still learning how to use AJAX so would display a novice code here...
I got this div (which repeats itself as a list of checkbox):
<div class="updateTask fs11">
<input type="checkbox" name="taskStatusRadio" id="taskStatus" value="<?php echo $taskId; ?>" <?php echo $done; ?> >
<?php _e('Task Done', 'sagive'); ?>
</div>
Which activates this:
jQuery(function($){
$('.updateTask').click(function () {
$.post(ajax_object.ajaxurl, {
action: 'action_update_task',
task_id: $("input[name=taskStatusRadio]:checked").map(function () {return this.value;}).get()
}, function(data) {
// USE DATA RETURNED //////////
var $response = $(data);
var message = $response.filter('div#message').html();
var taskid = $response.filter('div#taskid').html();
// SUCCESS RESPOND //////////
setTimeout(function(){
$('#success ul li').append(message + taskid);
$('#success').fadeIn();
$('#success').css("display", "block");
}, 1000);
setTimeout(function(){
$('#success ul li').empty();
$('#success').fadeIn();
$('#success').css("display", "none");
}, 30000);
hideTask = "#" + taskid;
$(hideTask).hide("slow");
hideTask = '';
});
});
});
And uses this php file:
wp_enqueue_script( 'ajax-update-task', get_stylesheet_directory_uri().'/ajaxLoops/ajax-update_task.js', array('jquery'), 1.0 ); // jQuery will be included automatically
wp_localize_script( 'ajax-update-task', 'ajax_object', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) ); // setting ajaxurl
add_action( 'wp_ajax_action_update_task', 'ajax_update_task' ); // ajax for logged in users
function ajax_update_task() {
global $current_user;
get_currentuserinfo();
$task_user = $current_user->display_name;
if($taskUser == '') {$taskUser = $current_user->user_login;}
$task_id = $_POST["task_id"];
$task_id = $task_id[0];
$task_status = 'done';
$task_title = get_the_title($task_id);
$task_title = mb_substr($task_title, 0 ,35).'...';
update_post_meta($task_id, '_sagive_task_radio_selector', $task_status);
update_post_meta($task_id, '_sagive_task_user_changed', $task_user);
echo '<div id="message">'.__('The task: ', 'sagive').$task_title.__('Was Marked Completed!', 'sagive').'</div>';
echo '<div id="taskid">'.$task_id.'</div>';
die(); // stop executing script
}
It all works fine the first time. But the second checkbox I mark after the first one disappears as expected does nothing. It doesn't activate the php script and doesn't return a response.
Since I'm still new using AJAX, I would appreciate an example using my code or a good example with explanation.
Revision 1:
This is the structure of the page where the checkboxes are at
I think your problem comes from your selector :
$("input[name=taskStatusRadio]:checked").map(function () {return this.value;}).get();
which returns all the taskStatusRadio input checked and not just the one you click.
Your php script receive all the taskid checked in an array an pick the first one to treat it and send a response.
So the first time, it's ok, you just have one checkbox checked. But when you check a second checkbox, all checked taskid will be send and only the $_POST["task_id"][0] will be treated.
Same response from your php script and no change in the front view.
So, i think, you just have to modify a little bit your code, to post only taskid of the checkbox you click on it.
jQuery(function($) {
// we listen only the checkbox, not the div click action
$(':checkbox', '.updateTask').click(function () {
// if the checkbox is checked
if ($(this).attr('checked') == "checked") {
$.post(ajax_object.ajaxurl, {
action: 'action_update_task',
task_id: $(this).val() },
function(data) {
// SUCCESS RESPOND //////////
setTimeout(function() {
$('#success ul li').append( $(data).html());
$('#success').fadeIn();
$('#success').css("display", "block");
}, 1000);
setTimeout(function() {
$('#success ul li').empty();
$('#success').fadeIn();
$('#success').css("display", "none");
}, 30000);
// we hide the checkbox
$(this).hide("slow");
});
}
});
});
And because of this change in the front javascript, we have to simplify your php script like this :
wp_enqueue_script( 'ajax-update-task', get_stylesheet_directory_uri().'/ajaxLoops/ajax-update_task.js', array('jquery'), 1.0 ); // jQuery will be included automatically
wp_localize_script( 'ajax-update-task', 'ajax_object', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) ); // setting ajaxurl
add_action( 'wp_ajax_action_update_task', 'ajax_update_task' ); // ajax for logged in users
function ajax_update_task() {
global $current_user;
get_currentuserinfo();
$task_user = $current_user->display_name;
if($taskUser == '') {$taskUser = $current_user->user_login;}
$task_id = $_POST["task_id"];
$task_status = 'done';
$task_title = get_the_title($task_id);
$task_title = mb_substr($task_title, 0 ,35).'...';
update_post_meta($task_id, '_sagive_task_radio_selector', $task_status);
update_post_meta($task_id, '_sagive_task_user_changed', $task_user);
// Note : now we send the message directly well-formed with the task_id
echo __('The task: ', 'sagive').$task_title.__('Was Marked Completed!', 'sagive'). $task_id;
die(); // stop executing script
}
I hope my answer will solve your problem ;)
ps: i apologize for my poor english...

Categories