Hide enquiry button when product is on stock - php

How can I hide a specific button, based on the stock status of my product?
The plugin is creating this class:
function wdm_pefree_init() {
// phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid
if ( ! class_exists( 'Product_Enquiry_For_Woocommerce', false ) ) {
include_once WDM_PE_PLUGIN_PATH . '/includes/class-product-enquiry-for-woocommerce.php';
}
Product_Enquiry_For_Woocommerce::instance();
}
I only want to display this button the single product page of every product that is in backorder, but I can't get my code to work.
I'm not that great with PHP, so I'm trying to adapt some other code I have on my functions.php file, but without any luck.
Any help would be great, thanks!
I've tried this code:
add_filter('woocommerce_get_availability', 'wcs_custom_get_availability', 1, 2);
function wcs_custom_get_availability($availability, $_product) {
// Remove Enquiry Button
if (!$_product->is_in_stock()) {
remove_action('Product_Enquiry_For_Woocommerce');
}
return $availability;
}
I also see that the css class for the button is .pe-show-enq-modal, but I can't do a conditional "visibility: hidden" that only works for backorder products.

What you are looking for is this:
add_action( 'woocommerce_single_product_summary', 'remove_enquiry_button_if_out_of_stock', 30 );
function remove_enquiry_button_if_out_of_stock() {
global $product;
if ( ! $product->is_in_stock() ) {
remove_action( 'woocommerce_single_product_summary', array( Product_Enquiry_For_Woocommerce::instance(), 'enquiry_button' ), 25 );
}
}
Or Via CSS :
.product.out-of-stock .pe-show-enq-modal {
display: none;
}

The only way I got this (kinda) working was by using this JS:
function remove_enquiry() {
?>
<script type="text/javascript">
(function($){
$(document).ready(function(){
if($(".in-stock").length)
$(".pe-show-enq-modal").hide();
});
})(jQuery);
</script>
<?php
}
add_action('wp_head', 'remove_enquiry');
You can see it here.
But if you notice, it has a delay executing the JS, because when the page loads, the button still shows up for a brief moment (otherwise it seems to be working ok).

Related

Change custom Ajax Add to Cart button text after add to cart in WooCommerce

I use a code that changes the text and style of the "Add to Cart" button for a product if the item is already in the cart. Many thanks to 7uc1f3r for this.
/* for single product */
add_filter( 'woocommerce_product_single_add_to_cart_text', 'single_product_button_text' );
function single_product_button_text( $text ) {
if( WC()->cart->find_product_in_cart( WC()->cart->generate_cart_id( get_the_ID() ) ) ) {
$text = 'Product in cart';
}
return $text;
}
/* for archive/category pages */
add_filter( 'woocommerce_product_add_to_cart_text', 'products_button_text', 20, 2 );
function products_button_text( $text, $product ) {
if(
$product->is_type( 'simple' )
&& $product->is_purchasable()
&& $product->is_in_stock()
&& WC()->cart->find_product_in_cart( WC()->cart->generate_cart_id( $product->get_id() ) )
) {
$text = 'Product in cart';
}
return $text;
}
function action_wp_footer() {
?>
<script>
jQuery(document).ready(function($) {
var selector = '.add_to_cart_text:contains("Product in cart")';
// Selector contains specific text
if ( $( selector ).length > 0 ) {
$( selector ).addClass( 'product-is-added' );
} else {
$( selector ).removeClass( 'product-is-added' );
}
});
</script>
<?php
}
add_action( 'wp_footer', 'action_wp_footer' );
After adding a product to the cart, I have to refresh the page each time to get new text and button style.
UPDATE
I also used Relabel "add to cart" button after add to cart in WooCommerce 2nd function code to change the text and style of the button using AJAX. The text changes, but all styles break.
Unfortunately, adding styles on the echo '<div class="add_to_cart_text">' . $new_text . '</div>'; line doesn't work.
Any help?
As your website shop and archives pages are very custom (doesn't have the default WooCommerce html structure) you need a very custom jQuery code made for your website.
Your Ajax add to cart button has by default this output html example:
<a href="?add-to-cart=1234" rel="nofollow" data-quantity="1" data-product_id="1234" class="add-to-cart-grid btn-link nasa-tip add_to_cart_button ajax_add_to_cart product_type_simple nasa-tiped" data-product_sku="AB123" data-tip="Add to Cart">
<span class="add_to_cart_text">Add to Cart</span>
<i class="cart-icon pe-7s-cart"></i>
</a>
And you need on Ajax added to cart to have the following output html (example):
<a href="?add-to-cart=1234" rel="nofollow" data-quantity="1" data-product_id="1234" class="add-to-cart-grid btn-link nasa-tip add_to_cart_button ajax_add_to_cart product_type_simple nasa-tiped" data-product_sku="AB123" data-tip="Product in cart">
<span class="add_to_cart_text product-is-added">Product in cart</span>
<i class="cart-icon pe-7s-cart"></i>
</a>
So know we can manage the jQuery code that is needed for your custom Ajax add to cart buttons on shop and archive pages…
Try the following that will change the text on your custom Ajax add to cart button on added_to_cart WooCommerce jQuery event:
add_action( 'wp_footer', 'ajax_button_text_js_script' );
function ajax_button_text_js_script() {
$text = __('Product in cart', 'woocommerce');
?>
<script>
jQuery(function($) {
var text = '<?php echo $text; ?>', $this;
$(document.body).on('click', '.ajax_add_to_cart', function(event){
$this = $(this); // Get button jQuery Object and set it in a variable
});
$(document.body).on('added_to_cart', function(event,b,data){
var buttonText = '<span class="add_to_cart_text product-is-added">'+text+'</span><i class="cart-icon pe-7s-cart"></i>';
// Change inner button html (with text) and Change "data-tip" attribute value
$this.html(buttonText).attr('data-tip',text);
});
});
</script>
<?php
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
I have something similar implemented on a website.
What might help is
.on('input change', function() { // Your code here }).change();
this updated my product page in real time and I believe you should be able to find a way to implement it to change the text on the add to cart button.
I am new to JavaScript so please bear with me and I hope my answer was at least a little helpful.

Additional Woocommerce product Add To Cart button that redirect to checkout

I need the customer to be able to choose between add to cart and continue to shop and add to cart and get re-directed to the checkout. In other words, I'm adding a extra button to the product page.
Being new to WooCommerce, I'm struggling getting the qty input to function. It works fine if buying just one, but not when adding more than one (qty).
Also, I'm failing to understand how to add support for variable products, but that might be a separate question? (sorry if so).
Here's the code I'm using:
add_action( 'woocommerce_after_add_to_cart_button', 'add_content_after_addtocart' );
function add_content_after_addtocart() {
$current_product_id = get_the_ID();
$product = wc_get_product( $current_product_id );
$checkout_url = WC()->cart->get_checkout_url();
if( $product->is_type( 'simple' )) { ?>
<script>
jQuery(function($) {
$(".custom-checkout-btn").on("click", function() {
$(this).attr("href", function() {
return this.href + '&quantity=' + $('input.qty').val();
});
});
});
</script>
<?php
echo 'Buy & Checkout';
}
}
Any input on where I'm going wrong? All the help I can get is appreciated.
There are some mistakes in your code… Try the following:
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;
}
Code goes in function.php file of your active child theme (or active theme). It should works.

Hide element with specific css selector in WordPress

I'm using the WordPress plugin "restrict content pro".
I would like to hide an element with selector li#wp-admin-bar-my-account-messages for a specific subscription id with PHP within my functions.php file.
I guess the PHP validation is rcp_is_active() && rcp_get_subscription_id() == 2 but don't know how to go on from here.
Thanks in advance
Assuming that rcp_is_active() && rcp_get_subscription_id() == 2 will validate to your specific use case and you just want to hide the element which has selector li#wp-admin-bar-my-account-messages you can do the following in your function.php
if ( rcp_is_active() && rcp_get_subscription_id() == 2 )
{
// for frontend
add_action( 'wp_head', function() {
echo '<style type="text/css">li#wp-admin-bar-my-account-messages{display:none !important}</style>';
} );
// for backend
add_action( 'admin_head', function() {
echo '<style type="text/css">li#wp-admin-bar-my-account-messages{display:none !important}</style>';
} );
}
Hope it helps :)

WooCommerce mini cart event trigger [duplicate]

This question already has answers here:
Run javascript code after ajax add to cart event in Woocommerce
(1 answer)
JS alert on ajax add to cart for specific product category count in Woocommerce
(1 answer)
Closed 4 years ago.
Every time a product is added to the basket by ajax and the mini cart is refreshed I need to be able to run some jQuery. I can't just simply create an even for add to cart because, I run some jQuery that checks if the mini cart has products inside it, but the add to cart even runs before the mini cart has added the products. This means that my if statement becomes false.
What can I do about this apart from creating a timeout in jQuery?
Here is the code I have modified from the current answers;
add_action( 'wp_footer', 'ajax_add_tocart_event' );
function ajax_add_tocart_event() {
?>
<script type="text/javascript">
jQuery( 'body' ).on( 'added_to_cart', function() {
if( $('#mini_wrap .cart_list').length ){
alert('hi');
}
} );
</script>
<?php
}
You can do using following code.
add_action( 'wp_footer', 'ajax_add_tocart_event' );
function ajax_add_tocart_event() {
?>
<script type="text/javascript">
jQuery( 'body' ).on( 'added_to_cart', function( e, fragments, cart_hash, this_button ) {
alert('product added to cart');
} );
</script>
<?php
} ?>
Put this code in functions.php file.
add_action( 'wp_footer', 'trigger_for_ajax_add_to_cart' );
function trigger_for_ajax_add_to_cart() {
?>
<script type="text/javascript">
(function($){
$('body').on( 'added_to_cart', function(){
//do some code
});
})(jQuery);
</script>
<?php
} ?>

Show or hide html element on chosen shipping method change in Woocommerce

I'm trying to show/hide some elements from my checkout page, based on the chosen shipping method. The page elements I'm trying to show/hide come from another plugin, so I tried to change the display properties for them. I've looked to many thread like:
Show or hide checkout fields based on shipping method in Woocommerce 3
But it's for checkout fields, and I'm not sure how to do it for page elements.
Then based on this answer thread Here's my code so far:
add_action( 'wp_footer', 'conditionally_hidding_order_delivery_date' );
function conditionally_hidding_order_delivery_date(){
// Only on checkout page
if( ! is_checkout() ) return;
// HERE your shipping methods rate ID "Home delivery"
$home_delivery = 'distance_rate_shipping';
?>
<script>
jQuery(function($){
// Choosen shipping method selectors slug
var shipMethod = 'input[name^="shipping_method"]',
shipMethodChecked = shipMethod+':checked';
// Function that shows or hide imput select fields
function showHide( actionToDo='show', selector='' ){
if( actionToDo == 'show' )
$(selector).show( 200, function(){
$(this).addClass("validate-required");
});
else
$(selector).hide( 200, function(){
$(this).removeClass("validate-required");
});
$(selector).removeClass("woocommerce-validated");
$(selector).removeClass("woocommerce-invalid woocommerce-invalid-required-field");
}
// Initialising: Hide if choosen shipping method is "Home delivery"
if( $(shipMethodChecked).val() != '<?php echo $home_delivery; ?>' ) {
showHide('hide','#e_deliverydate_field' );
showHide('hide','#time_slot_field' );
}
// Live event (When shipping method is changed)
$( 'form.checkout' ).on( 'change', shipMethod, function() {
if( $(shipMethodChecked).val() == '<?php echo $home_delivery; ?>' ) {
showHide('show','#e_deliverydate_field' );
showHide('show','#time_slot_field' );
}
else {
showHide('hide','#e_deliverydate_field' );
showHide('hide','#time_slot_field' );
}
});
});
</script>
<?php
}
But it's not working completely (the initializing function is not working.)
Any help is very much appreciated.
Additional edit:
<p class="form-row form-row-wide validate-required" id="e_deliverydate_field" data-priority="" style="display: block;"><label for="e_deliverydate" class="">Date<abbr class="required" title="required">*</abbr></label><span class="woocommerce-input-wrapper"><input class="input-text hasDatepicker" name="e_deliverydate" id="e_deliverydate" placeholder="Choose a Date" value="" style="cursor:text !important;" type="text"></span></p>
My objective is to change the display properties for p element from block to none, and vice versa.
The needed code is something much more simple, than the one used in my other answers, but you need to be sure that the targeted chosen shipping method is 'distance_rate_shipping' as I can't test it.
For initialization problem, see the solution exposed at the end of my answer.
The simplified needed code:
// Embedded jQuery script
add_action( 'wp_footer', 'checkout_delivery_date_script' );
function checkout_delivery_date_script() {
// Only checkout page
if( ! ( is_checkout() && ! is_wc_endpoint_url() ) ) return;
?>
<script type="text/javascript">
jQuery( function($){
var a = 'input[name^="shipping_method"]', b = a+':checked',
c = 'distance_rate_shipping',
d = '#e_deliverydate_field,#time_slot_field';
// Utility function that show or hide the delivery date
function showHideDeliveryDate(){
if( $(b).val() == c )
$(d).show();
else
$(d).hide('fast');
console.log('Chosen shipping method: '+$(b).val()); // <== Just for testing (to be removed)
}
// 1. On start
showHideDeliveryDate();
// 2. On live event "change" of chosen shipping method
$('form.checkout').on('change', a, function(){
showHideDeliveryDate();
});
});
</script>
<?php
}
Code goes in function.php file of your active child theme (or theme). It should work.
The initialization problem:
It's certainly because the plugin you are using that generates the delivery date output is delayed after initialization
The solution can be to add some delay on initialization execution.
So should try to replace this:
// 1. On start
showHideDeliveryDate();
By the following in my code (adjusting the execution delay to something higher or lower than 500):
// 1. On start
setTimeout(function(){
showHideDeliveryDate();
}, 500);

Categories