Hide/show a button which depends on a variable - javascript

Hello I have a little problem, and I hope someone of you can help me, I use wordpress and I have a buy button that I want to be active only when the amount is bigger than 267 $ for example!
How can I do that?
Someone can tell me if I can do that simply in javaScript or maybe even css?
I attach some pictures and explain more:
I have tried something with an woocommerce code but it just stop me to place the order in the check out page, this is the code I used:
add_action( 'woocommerce_checkout_process', 'wc_minimum_order_amount' );
add_action( 'woocommerce_before_cart' , 'wc_minimum_order_amount' );
function wc_minimum_order_amount() {
// Set this variable to specify a minimum order value
$minimum = 267;
if ( WC()->cart->total < $minimum ) {
if( is_cart() ) {
wc_print_notice(
sprintf( 'Totalul tau este %s — comanda ta trebuie sa fie de minim %s adica minim 3 m² pentru a putea plasa comanda! ' ,
wc_price( WC()->cart->total ),
wc_price( $minimum )
), 'error'
);
} else {
wc_add_notice(
sprintf( 'Totalul tau este %s — comanda ta trebuie sa fie de minim %s adica minim 3 m² pentru a putea plasa comanda!' ,
wc_price( WC()->cart->total ),
wc_price( $minimum )
), 'error'
);
}
}
}

Well, in WooCommerce the function that displays the button can be overwritten in a theme's file or a mu-plugin file.
If you want the button to disappear when the order doesn't comply you can simply add this in functions.php.
if ( ! function_exists( 'woocommerce_widget_shopping_cart_proceed_to_checkout' ) ) {
function woocommerce_widget_shopping_cart_proceed_to_checkout() {
$total = WC()->cart->subtotal;
$minimum_amount = 267;
if ( $total < $minimum_amount ) {
return;
}
echo '' . esc_html__( 'Checkout', 'woocommerce' ) . '';
}
add_action( 'woocommerce_widget_shopping_cart_buttons', 'woocommerce_widget_shopping_cart_proceed_to_checkout', 20 );
}
Personally I would rather create a CSS class like .disabled and add it to the button when our condition in true.
if ( ! function_exists( 'woocommerce_widget_shopping_cart_proceed_to_checkout' ) ) {
function woocommerce_widget_shopping_cart_proceed_to_checkout() {
$total = WC()->cart->subtotal;
$minimum_amount = 267;
if ( $total <= $minimum_amount ) {
echo '' . esc_html__( 'Checkout', 'woocommerce' ) . '';
} else {
echo '' . esc_html__( 'Checkout', 'woocommerce' ) . '';
}
}
add_action( 'woocommerce_widget_shopping_cart_buttons', 'woocommerce_widget_shopping_cart_proceed_to_checkout', 20 );
}
In this case you will need to add some sort of CSS to make it look like a inactive button:
.button.checkout.disabled {
opacity: 0.6; // or give it some sort of gray feeling.
cursor: not-allowed; // so the user get's the notice that something is wrong.
pointer-events: none; // so the user cannot click the button.
}
.button.checkout.disabled:before {
content: "Add here a notice for the user about the minimum requirement."
// the should feel like a tooltip and you will have to make your own placements here.
// oh, and if you need this to be translatable you will have to print this in PHP.
}
Anyway, this is just "esthetics" You should keep the function that prevents the user to place the order from the checkout page.
Cheers!

Related

X amount before free shipping, on the cart page [duplicate]

I modified this script to make a shortcode that shows how much the customer need to spend to get free shipping.
/**
* #author Rodolfo Melogli
* #compatible WooCommerce 3.9
* #donate $9 https://businessbloomer.com/bloomer-armada/
*/
add_shortcode ('woo_freeshipping_target', 'woo_freeship_target' );
function woo_freeship_target() {
ob_start();
$min_amount = 279; //change this to your free shipping threshold
$current = WC()->cart->subtotal;
if ( $current < $min_amount ) {
$added_text = wc_price( $min_amount - $current );
$notice = sprintf( $added_text );
echo '<span> You need to add '.$notice.'</span>';
}
else if ( $current >= $min_amount ) {
echo '<span>Free Shipping!</span>';
}
return ob_get_clean();
}
But I cannot figure out how can I make it to auto update when the items quantity is modified. Any idea?
To ajaxify your message so it updates when the subtotal change (via ajax) use the woocommerce_add_to_cart_fragments filter hook
So you get:
function custom_message() {
// Initialize
$message = __( 'Default message', 'woocommerce' );
// True
if ( WC()->cart ) {
// Change this to your free shipping threshold
$min_amount = 279;
// Get cart subtotal
$subtotal = WC()->cart->get_subtotal();
if ( $subtotal < $min_amount ) {
$message = sprintf( __( 'You need to add %s to get free shipping', 'woocommerce' ), wc_price( $min_amount - $subtotal ) );
} else {
$message = __( 'Free shipping', 'woocommerce' );
}
}
return $message;
}
// Refreshing on cart ajax events
function filter_woocommerce_add_to_cart_fragments( $fragments ) {
$fragments['div.display-message'] = '<div class="display-message">' . custom_message() . '</div>';
return $fragments;
}
add_filter( 'woocommerce_add_to_cart_fragments', 'filter_woocommerce_add_to_cart_fragments', 10, 1 );
// Shortcode
function display_my_message() {
return '<div class="display-message">' . custom_message() . '</div>';
}
// Register shortcode
add_shortcode( 'display_message', 'display_my_message' );
SHORTCODE USAGE
In an existing page:
[display_message]
Or in PHP:
echo do_shortcode("[display_message]");
Related: WooCommerce shortcode to ajaxify message that display: "Buy X more products to get a discount"

PHP function output only updates after click on page

So I was looking for a way to update Pricing for a variable Product (Woocommerce + WP), without showing the Price Range + Final Price (including Variables).
I stumbled upon this script, which seems to work perfectly for my use case. Source - Stackoverflow
It works fine on mobile.
However, in Desktop Browser, it requires me to click on a random place of the page to update the pricing. This is very inconvenient.
Any idea how to fix this?
My coding skills are limited to HTML/CSS and very basic js.
Any help is appreciated.
This is the code:
add_action( 'woocommerce_before_single_product', 'check_if_variable_first' );
function check_if_variable_first(){
if ( is_product() ) {
global $post;
$product = wc_get_product( $post->ID );
if ( $product->is_type( 'variable' ) ) {
// removing the price of variable products
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_price', 10 );
// Change location of
add_action( 'woocommerce_single_product_summary', 'custom_wc_template_single_price', 10 );
function custom_wc_template_single_price(){
global $product;
// Variable product only
if($product->is_type('variable')):
// Main Price
$prices = array( $product->get_variation_price( 'min', true ), $product->get_variation_price( 'max', true ) );
$price = $prices[0] !== $prices[1] ? sprintf( __( 'From: %1$s', 'woocommerce' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );
// Sale Price
$prices = array( $product->get_variation_regular_price( 'min', true ), $product->get_variation_regular_price( 'max', true ) );
sort( $prices );
$saleprice = $prices[0] !== $prices[1] ? sprintf( __( 'From: %1$s', 'woocommerce' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );
if ( $price !== $saleprice && $product->is_on_sale() ) {
$price = '<del>' . $saleprice . $product->get_price_suffix() . '</del> <ins>' . $price . $product->get_price_suffix() . '</ins>';
}
?>
<style>
div.woocommerce-variation-price,
div.woocommerce-variation-availability,
div.hidden-variable-price {
height: 0px !important;
overflow:hidden;
position:relative;
line-height: 0px !important;
font-size: 0% !important;
}
</style>
<script>
jQuery(document).ready(function($) {
$('select').blur( function(){
if( '' != $('input.variation_id').val() ){
$('p.price').html($('div.woocommerce-variation-price > span.price').html()).append('<p class="availability">'+$('div.woocommerce-variation-availability').html()+'</p>');
console.log($('input.variation_id').val());
} else {
$('p.price').html($('div.hidden-variable-price').html());
if($('p.availability'))
$('p.availability').remove();
console.log('NULL');
}
});
});
</script>
<?php
echo '<p class="price">'.$price.'</p>
<div class="hidden-variable-price" >'.$price.'</div>';
endif;
}
}
}
}
LINK to Image for Usecase explanation - See also Stackoverflow Link where I took the code from
The problem which you are facing seems to be the $('select').blur().
As you want this to change automatically, I suggest changing this to change()..
<script>
jQuery(document).ready(function($) {
$('select').change( function(){
if( '' != $('input.variation_id').val() ){
$('p.price').html($('div.woocommerce-variation-price > span.price').html()).append('<p class="availability">'+$('div.woocommerce-variation-availability').html()+'</p>');
console.log($('input.variation_id').val());
} else {
$('p.price').html($('div.hidden-variable-price').html());
if($('p.availability'))
$('p.availability').remove();
console.log('NULL');
}
});
});
</script>
The blur() event occurs when an object loses focus.. In your case, when you click off the screen.
the change() event occurs when the object changes.. In your case, whenever the select option changes
The code above was flawed.
I found a better solution for my use case in this post: Update Woo Variable Price

WooCommerce external product to new tab

I would like to have WooCommerce external/affiliate products open in a new tab. This would go for all aspects of a product: image, title, buy now button and archive pages(product category/tags). All I have been able to find is a way to change the "Buy Now" button but no other solutions to the other areas previously mentioned. Other solutions offer a the external link in all the right places(product image, title, buy now button, archive pages), but it can't open in a new tab.
I've tried a bunch of different codes, as mentioned above, all lead to partial solutions. I believe if these can be combined, it may work. But I haven't been successful.
add_action( 'template_redirect', 'redirect_external_products' );
function redirect_external_products() {
global $post;
if ( is_singular( 'product' ) && ! empty( $post ) && ( $product = wc_get_product( $post ) ) && $product->is_type( 'external' ) ) {
wp_redirect( $product->get_product_url() );
exit;
}
}
function custom_redirect() {
global $post;
if( is_single() ){
$external_link = get_post_meta( $post->ID, 'external_link', true );
if($external_link) {
echo "<script> window.open(".$external_link.", '_blank') </script>";
exit;
}
}
}
I would like all affiliate/external links to open in a new tab. This would include: product image, product title, buy now button, archive page listings(product category/tags).
All previous attempts will only open the Buy Now links in a new tab - but the image and title still direct to the single product page. The first code above from does the trick, but won't open in a new tab. My research tells me that when using the template_redirect function, link targeting is not possible.
remove the previous code and let's add this code in the theme's functions.php file.
add_filter( 'woocommerce_loop_product_link', 'filter_external_product_permalink', 10, 2 );
if ( ! function_exists( 'filter_external_product_permalink' ) ) {
/**
* Insert the external url for products in the loop.
*/
function filter_external_product_permalink( $the_permalink, $product ){
global $product;
if( $product->is_type( 'external' ) ) {
$external_link = $product->get_product_url();
return $external_link;
}
return $the_permalink;
}
}
if ( ! function_exists( 'woocommerce_template_loop_product_link_open' ) ) {
/**
* Insert the opening anchor tag for products in the loop.
*/
function woocommerce_template_loop_product_link_open() {
global $product;
$link = apply_filters( 'woocommerce_loop_product_link', get_the_permalink(), $product );
$link_target = $product->is_type( 'external' ) ? '_blank' : '_self';
echo '<a target="' . esc_attr( $link_target ).'" href="' . esc_url( $link ) . '" class="woocommerce-LoopProduct-link woocommerce-loop-product__link">';
}
}
add_filter( 'woocommerce_loop_add_to_cart_link', 'custom_external_add_product_link' , 10, 2 );
if ( ! function_exists( 'custom_external_add_product_link' ) ) {
function custom_external_add_product_link( $permalink ) {
global $product;
if ( $product->is_type( 'external' ) ) {
$permalink = sprintf( '<a rel="nofollow" href="%s" data-quantity="%s" data-product_id="%s" data-product_sku="%s" class="%s" target="_blank">%s</a>',
esc_url( $product->add_to_cart_url() ),
esc_attr( isset( $quantity ) ? $quantity : 1 ),
esc_attr( $product->id ),
esc_attr( $product->get_sku() ),
esc_attr( isset( $class ) ? $class : 'button product_type_external add_to_cart_button' ),
esc_html( $product->add_to_cart_text() )
);
}
return $permalink;
}
}

Javascript scroll function on my checkout page in Woocommerce not moving to the right place

On my checkout page in Woocommerce I want to move the coupon link from the top of the page to the order review box between subtotal and payment methods with my own translation. I want the coupon box to open at the bottom of the page and scroll there automatically. I managed moving the link and having the box to open at the bottom of the page by finding the code below Googling (source: https://www.sellwithwp.com/move-the-woocommerce-coupon-field/):
The problem is: The page scrolls too far to the bottom. I want it to stop at the discount box. The box opens below the checkout form when the voucher link is clicked. This is the URL to the page: https://www.shopamerica.nl/afrekenen/ (you need something above €20 in the cart,like https://www.shopamerica.nl/product/hersheys-kisses-milk-chocolate-party-bag-113-kg/)
It must be in this line:
$( "html, body" ).animate({scrollTop:$(document).height()}, "slow" );
I googled and searched on this site, thought I found solutions with a div box. But I don’t get it to work. Thank you for your help.
Code to move form link and box to the bottom
// move form link check out to bottom
remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form', 10 );
add_action( 'woocommerce_after_checkout_form', 'woocommerce_checkout_coupon_form' );
Code to move form link order review box
// rename coupon message on checkout
add_filter( 'woocommerce_email_order_items_table', 'sww_add_wc_order_email_images', 10, 2 );
function woocommerce_rename_coupon_message_on_checkout() {
return 'Heb je een voucher?' . ' ' . __( 'Click here to enter your code', 'woocommerce' ) . '';
}
add_filter( 'woocommerce_checkout_coupon_message', 'woocommerce_rename_coupon_message_on_checkout' );
// rename the coupon field on the checkout page
function woocommerce_rename_coupon_field_on_checkout( $translated_text, $text, $text_domain ) {
// bail if not modifying frontend woocommerce text
if ( is_admin() || 'woocommerce' !== $text_domain ) {
return $translated_text;
}
if ( 'Coupon code' === $text ) {
$translated_text = 'voucher';
} elseif ( 'Apply Coupon' === $text ) {
$translated_text = 'Vouchercode toepassen';
}
return $translated_text;
}
add_filter( 'gettext', 'woocommerce_rename_coupon_field_on_checkout', 10, 3 );
// show form link in order review section
function sa_show_coupon_js() {
wc_enqueue_js( '
$( "a.showcoupon" ).parent().hide();
$( "body" ).bind( "updated_checkout", function() {
$( "#show-coupon-form" ).click( function() {
$( ".checkout_coupon" ).show();
$( "html, body" ).animate({scrollTop:$(document).height()}, "slow" );
return false;
} );
} );
');
}
add_action( 'woocommerce_before_checkout_form', 'sa_show_coupon_js' );
/**
* Show a coupon link above the order details.
**/
function sa_show_coupon() {
echo '<p class="voucher_sa"> Heb je een voucher? Klik hier om de code in te vullen.</p>';
}
add_action( 'woocommerce_checkout_order_review', 'sa_show_coupon' );

Woocommerce Variation

I have woocommerce setup with products and variations on these products. When I change the variation (for example, the size of the product (340g or 900g), I want it to dynamically on the page update the price so the person can see what the price difference is between the two sizes. At the moment, I can't even get the variation ID of the variation. This does not seem to be working at all.
If I test and modify the variations, this is all I get from the Javascript console:
Here is my code:
// removing the price of variable products
remove_action( 'woocommerce_single_product_summary','woocommerce_template_single_price', 10 );
// Change location of
add_action( 'woocommerce_single_product_summary', 'custom_wc_template_single_price', 10 );
function custom_wc_template_single_price(){
global $product;
// Variable product only
if($product->is_type('variable')):
// Main Price
$prices = array( $product->get_variation_price( 'min', true ), $product->get_variation_price( 'max', true ) );
$price = $prices[0] !== $prices[1] ? sprintf( __( 'From: %1$s', 'woocommerce' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );
// Sale Price
$prices = array( $product->get_variation_regular_price( 'min', true ), $product->get_variation_regular_price( 'max', true ) );
sort( $prices );
$saleprice = $prices[0] !== $prices[1] ? sprintf( __( 'From: %1$s', 'woocommerce' ), wc_price( $prices[0] ) ) : wc_price( $prices[0] );
if ( $price !== $saleprice && $product->is_on_sale() ) {
$price = '<del>' . $saleprice . $product->get_price_suffix() . '</del> <ins>' . $price . $product->get_price_suffix() . '</ins>';
}
?>
<style>
div.woocommerce-variation-price,
div.woocommerce-variation-availability,
div.hidden-variable-price {
height: 0px !important;
overflow:hidden;
position:relative;
line-height: 0px !important;
font-size: 0% !important;
}
</style>
<script>
jQuery(document).ready(function($) {
$('select').blur( function(){
console.log("blur");
if( '' != $('input.variation_id').val() ){
console.log($('input.variation_id'));
console.log($('input.variation_id').val());
$('p.price').html($('div.woocommerce-variation-price > span.price').html()).append('<p class="availability">'+$('div.woocommerce-variation-availability').html()+'</p>');
console.log($('input.variation_id').val());
} else {
$('p.price').html($('div.hidden-variable-price').html());
if($('p.availability'))
$('p.availability').remove();
console.log('NULL');
}
});
});
</script>
<?php
echo '<p class="price">'.$price.'</p>
<div class="hidden-variable-price" >'.$price.'</div>';
endif;
}
Here is the site: https://bricksandmortar.ca/product/no-eye-contact/#
Any ideas?
You can hook into the show_variation trigger with some jQuery to get all of the information about the selected variation. Here's an example that will write the price formatted in HTML to the console.
(function( $ ) {
'use strict';
$(function() {
var $variation_form = $( '.variations_form' );
$variation_form.on( "show_variation", function ( event, variation ) {
// Fired when the user selects all the required attributes
console.log(variation.price_html);
} );
});
})( jQuery );

Categories

Resources