Reputation: 5513
I want to remove the double price field on variable products in WooCommerce. At the moment there is an overall price field which shows the range of the price and there is the price field which shows the price of the selected variation.
I now want to replace the overall price with the price of the selected variation. And only show the overall price when no variation is selected.
There is a good answer for that from @LoicTheAztec here: https://stackoverflow.com/a/47618953/1788961
He uses the following code to change the output:
// 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;
visibility: hidden !important;
}
</style>
<script>
jQuery(document).ready(function($) {
// When variable price is selected by default
setTimeout( function(){
if( 0 < $('input.variation_id').val() && null != $('input.variation_id').val() ){
if($('p.availability'))
$('p.availability').remove();
$('p.price').html($('div.woocommerce-variation-price > span.price').html()).append('<p class="availability">'+$('div.woocommerce-variation-availability').html()+'</p>');
console.log($('div.woocommerce-variation-availability').html());
}
}, 300 );
// On live variation selection
$('select').blur( function(){
if( 0 < $('input.variation_id').val() && null != $('input.variation_id').val() ){
if($('.price p.availability') || $('.price p.stock') )
$('p.price p').each(function() {
$(this).remove();
});
$('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;
}
The problem is, that I use some different HTML structure because of the plugin "German Market". Therefore the solution above doesn't work for me. I tried to edit the code from the answer above but I couldn't make it work.
I guess the problem is the different HTML structure and some extra styles. The plugin also adds some extra fields for stock, tax and shipping. The solution from the answer above hides these fields.
Here is a demo of a variable product with the plugin "German Market": http://demo.marketpress.com/hamburg-de/shop/clothing/ship-your-idea-2/
And here is my HTML structure of a variable product page (as you might notice, I already changed the placement of the price to above the variations table):
<form class="variations_form cart" action="https://example.com/product/test/" method="post" enctype="multipart/form-data" data-product_id="7474" data-product_variations="....." current-image="2492">
<div class="woocommerce-variation single_variation">
<div class="woocommerce-variation-description"></div>
<div class="woocommerce-variation-price"><span class="price"><del><span class="woocommerce-Price-amount amount">169,00 <span class="woocommerce-Price-currencySymbol">€</span></span></del><ins><span class="woocommerce-Price-amount amount">119,00 <span class="woocommerce-Price-currencySymbol">€</span></span></ins></span>
<div class="wgm-info woocommerce-de_price_taxrate ">Enthält 19% Mwst.</div>
<div class="versandkostenfrei product_free_delivery">versandkostenfrei</div>
<div class="wgm-info woocommerce_de_versandkosten">zzgl. <a class="versandkosten" href="https://example.com/versand/" target="_blank">Versand</a></div>
<div class="wgm-info shipping_de shipping_de_string">
<small>
<span>Lieferzeit: sofort versandfertig, Lieferfrist 1-3 Tage</span>
</small>
</div>
</div>
<div class="woocommerce-variation-availability">
<p class="stock in-stock ">Vorrätig</p>
</div>
</div>
<table class="variations" cellspacing="0">
<tbody>
<tr>
<td class="label"><label for="pa_farbe">Farbe</label></td>
<td class="value">
<div id="picker_pa_farbe" class="select swatch-control"><!-- variations --></div>
</td>
</tr>
</tbody>
</table>
<div class="single_variation_wrap">
<div class="woocommerce-variation-add-to-cart variations_button woocommerce-variation-add-to-cart-enabled">
<div class="quantity">
<label class="screen-reader-text" for="quantity_5afeba61bc89d">Anzahl</label>
<input type="number" id="quantity_5afeba61bc89d" class="input-text qty text" step="1" min="1" max="95" name="quantity" value="1" title="Menge" size="4" pattern="[0-9]*" inputmode="numeric" aria-labelledby="">
</div>
<button type="submit" class="single_add_to_cart_button button alt">In den Warenkorb</button>
<input type="hidden" name="add-to-cart" value="7474">
<input type="hidden" name="product_id" value="7474">
<input type="hidden" name="variation_id" class="variation_id" value="7478">
</div>
<input type="hidden" name="wlid" id="wlid">
<input type="hidden" name="add-to-wishlist-type" value="variable">
<input type="hidden" name="wl_from_single_product" value="1">
</div>
</form>
Upvotes: -1
Views: 1490
Reputation: 254428
I have make it work with the german Market plugin, but it doesn't display the prices with tax hints as the plugin does… You will need for that to make more customizations on the code and to search a bit in the plugin source code…
That was not working beacuse the plugin was already removing Woocommerce hooked prices, replacing them by other custom hooked functions with different hook priority…
So try this as it solve it with the normal price display and allow you to have the same functionality than in my initial answer:
// removing the price of variable products
remove_action( 'woocommerce_single_product_summary', array( 'WGM_Template', 'woocommerce_de_price_with_tax_hint_single'), 7 );
// 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;
visibility: hidden !important;
}
</style>
<script>
jQuery(document).ready(function($) {
// When variable price is selected by default
setTimeout( function(){
if( 0 < $('input.variation_id').val() && null != $('input.variation_id').val() ){
if($('p.availability'))
$('p.availability').remove();
$('p.price').html($('div.woocommerce-variation-price > span.price').html()).append('<p class="availability">'+$('div.woocommerce-variation-availability').html()+'</p>');
console.log($('div.woocommerce-variation-availability').html());
}
}, 300 );
// On live variation selection
$('select').blur( function(){
if( 0 < $('input.variation_id').val() && null != $('input.variation_id').val() ){
if($('.price p.availability') || $('.price p.stock') )
$('p.price p').each(function() {
$(this).remove();
});
$('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 '<div class="hidden-variable-price" >'.$price.'</div>';
endif;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Upvotes: 1