I'm trying to change the product thumbnail on my Woocommerce website when a variation is selected. I know this has to be done with JS/jQuery but this is not my main skill, so I hope some of you can help me further.
For changing the SKU I found the mix between PHP and JS as below:
<?php
add_action( 'custom_right_side_product_summary', 'wc_product_variable_sku', 45 );
function wc_product_variable_sku() {
global $product;
// $product->is_type( $type ) checks the product type, string/array $type ( 'simple', 'grouped', 'variable', 'external' ), returns boolean
if ( $product->is_type( 'variable' ) ) {
?>
<script type="text/javascript">
jQuery( function($){
$('form.variations_form').on('show_variation', function( event, data ){
$( 'div.widget' ).attr( 'sp-sku', data.sku );
// For testing
//console.log( 'Variation Id: ' + data.variation_id + ' | Sku: ' + data.sku );
//To Show
//document.querySelector(".sku").textContent="NEW SKU: " + data.sku;
document.querySelector(".sku").textContent=data.sku;
});
$('form.variations_form').on('hide_variation', function(){
$( 'div.widget' ).attr( 'sp-sku', '' );
});
});
</script>
<?php
}
}
Now I want to modify this so when a variation is selected the src of the product thumbnail will be replaced. This should make sure the image will be changed. I got the code like below but this is not working yet:
<?php
// ADD SUPPORT FOR VARIABLE IMAGE DISPLAY
add_action( 'custom_left_side_image', 'wc_product_variable_image', 45 );
function wc_product_variable_image() {
global $product;
// $product->is_type( $type ) checks the product type, string/array $type ( 'simple', 'grouped', 'variable', 'external' ), returns boolean
if ( $product->is_type( 'variable' ) ) {
?>
<script type="text/javascript">
jQuery( function($){
$('form.variations_form').on('show_variation', function( event, data ){
$( 'div.widget' ).attr( 'thumb_src', data.image );
// For testing
console.log( 'Variation Id: ' + data.variation_id + ' | Variation Image URL: ' + data.image );
//To Show
document.querySelector(".zoomImg").src="data.image";
});
$('form.variations_form').on('hide_variation', function(){
$( 'div.widget' ).attr( 'thumb_src', '' );
});
});
</script>
<?php
}
}
Something is going wrong, but don't know what. I think the problem is the way I call for an URL but can't find anywhere what another option is. Hope someone can help me solve this.
Related
I have a question if someone can help me with the amount of products added to the cart - when, for example, I add a product x in quantity 2, when I want to add another product in any amount, e.g. y, then it displays 2 items in the cart in the cart. The amount of product x does not reset as if and only when it "resets" itself, I can add a different amount of a different product. It is the same as if I were a customer who marked 2 quantities of the product x but withdrew without adding to the basket and chose, for example, 1 item of the product y then I read 2 items of the product x. Does anyone know how to solve it? Please help. Website - https://www.fabrykaprzypraw.com.pl/blog22/
/**
* Add quantity field on the archive page.
*/
function custom_quantity_field_archive() {
$product = wc_get_product( get_the_ID() );
//if ( ! $product->is_sold_individually() && 'variable' != $product->product_type && $product->is_purchasable() ) { //niki. ako ne go iskash za variable products. az go iskam
if ( ! $product->is_sold_individually() && $product->is_purchasable() ) {
woocommerce_quantity_input( array( 'min_value' => 1, 'max_value' => $product->backorders_allowed() ? '' : $product->get_stock_quantity() ) );
}
}
add_action( 'woocommerce_after_shop_loop_item', 'custom_quantity_field_archive', 15, 9 );
function custom_add_to_cart_quantity_handler() {
wc_enqueue_js( '
jQuery( "body" ).on( "click", ".quantity input", function() {
return false;
});
jQuery( "body" ).on( "change input", ".quantity .qty", function() {
var add_to_cart_button = jQuery( this ).parents( ".product" ).find( ".add_to_cart_button" );
// For AJAX add-to-cart actions
add_to_cart_button.attr( "data-quantity", jQuery( this ).val() );
// For non-AJAX add-to-cart actions
add_to_cart_button.attr( "href", "?add-to-cart=" + add_to_cart_button.attr( "data-product_id" ) + "&quantity=" + jQuery( this ).val() );
});
' );
}
add_action( 'init', 'custom_add_to_cart_quantity_handler' );
I had the same issue and I have solved it by changing the JavaScript a little bit. This JavaScript must be inside your functions.php in the method custom_add_to_cart_quantity_handler
wc_enqueue_js( '
$(".woocommerce .products").on("click", ".quantity input", function() {
return false;
});
$(".woocommerce li.product").on("change input", ".quantity .qty", function() {
var add_to_cart_button = $(this).parent( ".quantity" ).parent(".product").find(".add_to_cart_button");
console.log(add_to_cart_button);
// For AJAX add-to-cart actions
add_to_cart_button.attr("data-quantity", $(this).val());
});
// Trigger on Enter press
$(".woocommerce .products").on("keypress", ".quantity .qty", function(e) {
if ((e.which||e.keyCode) === 13) {
$( this ).parents(".product").find(".add_to_cart_button").trigger("click");
}
});
' );
For some reason, the code I'm using does not seem to load unless I inspect and run a debug. Perhaps someone else can review and make sure?
While the first check makes sure it's a product page, I would like a secondary check making sure the product has a gallery and if not - return.
This is the code:
add_action( 'wp_footer', 'image_swap_on_hover' );
function image_swap_on_hover() {
if ( ! is_product() ) return;
// if (???) // check if product has image gallery
?>
<script>
jQuery( document ).ready( function($) {
$( window ).load( function() {
$( '.flexslider' ).flexslider( {
animation: "slide",
controlNav: "thumbnails",
start: function() {
}
}
);
$( ".flex-control-thumbs li img" ).hover( function() {
$(this).click();
}
);
}
);
}
);
</script>
<?php
}
For your loading problem, don't use jQuery ready event as it comes after load event, so the load event never get triggered in your code.
You can use the WC_Product method get_gallery_image_ids() as follows:
add_action( 'wp_footer', 'image_swap_on_hover' );
function image_swap_on_hover() {
if ( ! is_product() )
return;
global $product;
if ( ! is_a( $product, 'WC_Product' ) ) {
$product = wc_get_product( get_the_id() );
}
// Get product gallery image ids
$gallery_image_ids = $product->get_gallery_image_ids();
// Check if product gallery image ids is not empty
if ( ! empty($gallery_image_ids) ) :
?>
<script>
jQuery( function($) {
$( window ).load( function() {
console.log( 'window LOAD event' ); // Only for testing (to be removed)
$( '.flexslider' ).flexslider( {
animation: "slide",
controlNav: "thumbnails",
start: function() {
// do something
}
});
$( ".flex-control-thumbs li img" ).hover( function() {
$(this).click();
});
});
});
</script>
<?php
endif;
}
I have tried to add a quantity input field to all my Wordpress pages which display Woocommerce products. My code adds a quantity input file to all products on all pages as intended but it only processes inputs on the Woocomerce shop page. If the product is on any other page including Woocommerce category pages only the input field is shown but id does not affect anything. Anyone got any idea what I am missing? Thank you.
/**
* Add quantity field on the archive page.
*/
function custom_quantity_field_archive() {
$product = wc_get_product( get_the_ID() );
if ( ! $product->is_sold_individually() && 'variable' != $product->product_type && $product->is_purchasable() ) {
woocommerce_quantity_input( array( 'min_value' => 1, 'max_value' => $product->backorders_allowed() ? '' : $product->get_stock_quantity() ) );
}
}
add_action( 'woocommerce_after_shop_loop_item', 'custom_quantity_field_archive', 0, 9 );
/**
* Add requires JavaScript.
*/
function custom_add_to_cart_quantity_handler() {
wc_enqueue_js( '
jQuery( ".post-type-archive-product" ).on( "click", ".quantity input", function() {
return false;
});
jQuery( ".post-type-archive-product" ).on( "change input", ".quantity .qty", function() {
var add_to_cart_button = jQuery( this ).parents( ".product" ).find( ".add_to_cart_button" );
// For AJAX add-to-cart actions
add_to_cart_button.data( "quantity", jQuery( this ).val() );
// For non-AJAX add-to-cart actions
add_to_cart_button.attr( "href", "?add-to-cart=" + add_to_cart_button.attr( "data-product_id" ) + "&quantity=" + jQuery( this ).val() );
});
' );
}
add_action( 'init', 'custom_add_to_cart_quantity_handler' );
post-type-archive-product needs to be replaced with type-product
I am trying the following code by LoicTheAztec - Add to cart and redirect to checkout for variable products in WooCommerce
Now, the problem is whenever I am clicking on the Buy Now button with the default variations set in the Product editor, the code is not working.
The Buy Now URL in this case becomes …/?addtocart=0&quantity=n
The Theme I am using - Basel
Any solutions?
Tried the code by LoicTheAztec.
function add_custom_addtocart_and_checkout() {
global $product;
$addtocart_url = wc_get_checkout_url().'?add-to-cart='.$product->get_id();
$button_class = 'single_add_to_cart_button button alt custom-checkout-btn';
$button_text = __("Buy & Checkout", "woocommerce");
if( $product->is_type( 'simple' )) :
?>
<script>
jQuery(function($) {
var url = '<?php echo $addtocart_url; ?>',
qty = 'input.qty',
button = 'a.custom-checkout-btn';
// On input/change quantity event
$(qty).on('input change', function() {
$(button).attr('href', url + '&quantity=' + $(this).val() );
});
});
</script>
<?php
elseif( $product->is_type( 'variable' ) ) :
$addtocart_url = wc_get_checkout_url().'?add-to-cart=';
?>
<script>
jQuery(function($) {
var url = '<?php echo $addtocart_url; ?>',
vid = 'input[name="variation_id"]',
pid = 'input[name="product_id"]',
qty = 'input.qty',
button = 'a.custom-checkout-btn';
// Once DOM is loaded
setTimeout( function(){
if( $(vid).val() != '' ){
$(button).attr('href', url + $(vid).val() + '&quantity=' + $(qty).val() );
}
}, 300 );
// On input/change quantity event
$(qty).on('input change', function() {
if( $(vid).val() != '' ){
$(button).attr('href', url + $(vid).val() + '&quantity=' + $(this).val() );
}
});
// On select attribute field change event
$('.variations_form').on('change blur', 'table.variations select', function() {
if( $(vid).val() != '' ){
$(button).attr('href', url + $(vid).val() + '&quantity=' + $(qty).val() );
}
});
});
</script>
<?php
endif;
echo ''.$button_text.'';
} ```
I expect this code to work when the user does not change or update any variations on the product page. That is when the user clicks on the Buy Now button with the default variations.
you don’t need all that you should add the button in the variation form it will work as submiting the form as the add to cart button then make the redirect
this is tested and working with me
add_action( 'woocommerce_single_variation', 'second_button_single_variation', 30 );
function second_button_single_variation() {
global $product;
echo '<form method="post">
<button type="submit" name="checkout_now" id="checkout_now" class="single_add_to_cart_button button alt buy_now_button" value="'.$product->get_id().'">Buy Now</button></form>';
}
function woo_redirect_to_checkout() {
global $woocommerce;
if( isset($_POST['checkout_now']) ){
wc_clear_notices();
$checkout_url = $woocommerce->cart->get_checkout_url();
wp_redirect($checkout_url);
}
}
add_filter ('add_to_cart_redirect', 'woo_redirect_to_checkout');
// clearing the cart if you want to go to checkout with the desired product only
add_filter( 'woocommerce_add_to_cart_validation', 'remove_cart_item_before_add_to_cart', 20, 3 );
function remove_cart_item_before_add_to_cart( $passed, $product_id, $quantity ) {
if( isset($_POST['checkout_now']) ){
if( ! WC()->cart->is_empty() )
WC()->cart->empty_cart();
}
return $passed;
}
I got help in this answer thread that allow to add an additional add-to-cart button that redirects to checkout. It works fine for simple products.
But how to make it work for variable products as well?
I've been trying myself, but no matter what I do, I break the site. I simply do not understand how to make this work with/ for variable products.
Here's the lightly changed code that works for simple products and which takes the quantity field into consideration:
add_action( 'woocommerce_after_add_to_cart_button', 'add_custom_addtocart_and_checkout' );
function add_custom_addtocart_and_checkout() {
global $product;
$addtocart_url = wc_get_checkout_url().'?add-to-cart='.$product->get_id();
$button_class = 'single_add_to_cart_button button alt custom-checkout-btn';
$button_text = __("Buy & Checkout", "woocommerce");
if( $product->is_type( 'simple' )) :
?>
<script>
jQuery(function($) {
var url = '<?php echo $addtocart_url; ?>',
qty = 'input.qty',
button = 'a.custom-checkout-btn';
// On input/change quantity event
$(qty).on('input change', function() {
$(button).attr('href', url + '&quantity=' + $(this).val() );
});
});
</script>
<?php
echo ''.$button_text.'';
endif;
}
Does anyone know how to get this working for variable products too?
Update 3
The following code will handle simple and variable products adding an additional Add to cart button that redirects to cart (with synchronized quantity).
The code works for simple and variable products as well.
add_action( 'woocommerce_after_add_to_cart_button', 'add_custom_addtocart_and_checkout' );
function add_custom_addtocart_and_checkout() {
global $product;
$addtocart_url = wc_get_checkout_url().'?add-to-cart='.$product->get_id();
$button_class = 'single_add_to_cart_button button alt custom-checkout-btn';
$button_text = __("Buy & Checkout", "woocommerce");
if( $product->is_type( 'simple' )) :
?>
<script>
jQuery(function($) {
var url = '<?php echo $addtocart_url; ?>',
qty = 'input.qty',
button = 'a.custom-checkout-btn';
// On input/change quantity event
$(qty).on('input change', function() {
$(button).attr('href', url + '&quantity=' + $(this).val() );
});
});
</script>
<?php
elseif( $product->is_type( 'variable' ) ) :
$addtocart_url = wc_get_checkout_url().'?add-to-cart=';
?>
<script>
jQuery(function($) {
var url = '<?php echo $addtocart_url; ?>',
vid = 'input[name="variation_id"]',
pid = 'input[name="product_id"]',
qty = 'input.qty',
button = 'a.custom-checkout-btn';
// Once DOM is loaded
setTimeout( function(){
if( $(vid).val() != '' ){
$(button).attr('href', url + $(vid).val() + '&quantity=' + $(qty).val() );
}
}, 300 );
// On input/change quantity event
$(qty).on('input change', function() {
if( $(vid).val() != '' ){
$(button).attr('href', url + $(vid).val() + '&quantity=' + $(this).val() );
}
});
// On select attribute field change event
$('.variations_form').on('change blur', 'table.variations select', function() {
if( $(vid).val() != '' ){
$(button).attr('href', url + $(vid).val() + '&quantity=' + $(qty).val() );
}
});
});
</script>
<?php
endif;
echo ''.$button_text.'';
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.