I want to add a new button for other actions beside the refund button in Edit Order page for WooCommerce.
I know it may be possible by hooks, but I can't seem to find the right hook to execute for it.
Use the following (where you will replace "custom" by your desired action slug and name):
add_action( 'woocommerce_order_item_add_action_buttons', 'wc_order_item_add_action_buttons_callback', 10, 1 );
function wc_order_item_add_action_buttons_callback( $order ) {
$label = esc_html__( 'Custom', 'woocommerce' );
$slug = 'custom';
?>
<button type="button" class="button <?php echo $slug; ?>-items"><?php echo $label; ?></button>
<?php
}
The hook is located in includes/admin/meta-boxes/views/html-order-items.php (line 288)
Then you will have to enable Ajax for this button, adding some jQuery code (sender) and some PHP code (WordPress Admin Ajax receiver), just like for WC_Ajax refund_line_items()…
Related
Hi I've been trying to get my "update cart" button to work on the cart page made by woocommerce. It is on my own theme and I have added the cart.php template to it. In the woocommerce template it had quantity but it didn't have an easy to use add more or less buttons. So I edited the global/quantity-input.php to have this trait. I have tested the single-products pages to use my new quantity and adding to cart. This works great. But on the cart page the update cart button is disabled unless a change is made, and it doesn't recognize my changes.
Things I've tried that worked:
When I manually go into the inspector and remove the "disable" attribute from the button
When I press "enter" on my keyboard in the quantity input after i press the "-" or "+" button.
Plus and minus do change the quantity in the input field
Typing in the quantity enables the update cart button
Things I've tried that did not work:
Using javascript to target the button and do 'update_cart.disable = false;'
Tried calling a submit on change to automatically adjust the cart
Just simply hope that the form recognizes the quantity change via my buttons
My code for the Javascript
function minus_quantity(e) {
var this_input = this.parentNode.querySelector('input[type=number]');
var current_val = this_input.value;
var new_val = parseInt(current_val) - 1;
this_input.value = new_val;
document.getElementsByName('update_cart').disable = false;
e.preventDefault();
}
function add_quantity(e) {
var current_val = this.parentNode.querySelector('input[type=number]').value;
var new_val = parseInt(current_val) + 1;
this.parentNode.querySelector('input[type=number]').value = new_val;
document.getElementsByName('update_cart').disable = false;
e.preventDefault();
}
My code inside cart.php
<button type="submit" class="button" name="update_cart" value="<?php esc_attr_e( 'Update cart', 'woocommerce' ); ?>"><?php esc_html_e( 'Update cart', 'woocommerce' ); ?></button>
<?php do_action( 'woocommerce_cart_actions' ); ?>
<?php wp_nonce_field( 'woocommerce-cart', 'woocommerce-cart-nonce' ); ?>
My HTML code inside the browser
<button type="submit" class="button" name="update_cart" value="Update cart" disabled="">Update cart</button>
<input type="hidden" id="woocommerce-cart-nonce" name="woocommerce-cart-nonce" value="6090857223">
<input type="hidden" name="_wp_http_referer" value="/cart/?purge_success=1&cache_type=all"><!-- </div>-->
I should mention that my selector on the button isn't working and I don't know why.
Also, I am very new to woocommerce and can't find anything on this topic. Thank you for reading this.
UPDATE 1:
I found this ticket and tried it
Woocommerce 2.6.2 adds disabled attribute to update cart button
I added this to the bottom of my javascript function ( I did make sure it's in a Jquery wrapper btw)
$('button[name="update_cart"]' ).removeProp( 'disabled');
However this did not work either. I used the inspector and it appears to not get anything back with the selector, but when I console log it, I get something back.
The reason why your javascript isn't working is because of two reasons:
The attribute you need to change is not "disable", it should be "disabled".
You are selecting your button from the DOM using getElementsByName, which actually returns an array of all the elements with that name in your page. The way you would access it and change the disabled attribute (assuming you only have one element with that name) would be like this:
document.getElementsByName('update_cart')[0].disabled = false;
However that is bad practice since you could have more than one element with that name and thus I would suggest giving your button an id and then using getElementById instead. You wouldn't need to add the [0] in this case.
I'm attempting to override the URL of the 'Buy Product' button for all External/Affiliate WooCommerce products. The button needs to link to a contact page and pre-fill the 'Subject' form field with the product title included via query string (e.g. Product enquiry: Product Title).
After reading https://stackoverflow.com/a/43947253/4068853 I've been able to get pretty close by adding the following to functions.php:
// Override external button url
function override_external_product_url( $url, $product ){
if ( 'external' === $product->get_type() ) {
// custom add to cart url example
$url = home_url( "/contact/?your-subject=Product enquiry:");
}
return $url;
}
add_filter( 'woocommerce_product_add_to_cart_url', 'override_external_product_url', 10, 2 );
The only thing remaining is to add the product title to the end of the query string. I know the product title can be fetched with <?php the_title_attribute(); ?> but being a PHP noob I'm just not sure how to implement this into the function?
Thanks.
Ended up using get_the_title instead because the_title_attribute was causing an error (product title text duplicating and rendering outside the button markup). Also added url encoding, final code looks like:
// Override external button url
function override_external_product_url( $url, $product ){
if ( 'external' === $product->get_type() ) {
// custom add to cart url example
$url = home_url("/contact/?your-subject=" . urlencode("Product Enquiry: " . get_the_title()));
}
return $url;
}
add_filter( 'woocommerce_product_add_to_cart_url', 'override_external_product_url', 10, 2 );
Trying to achieve something that should be simple, but I've tried 3 approaches with multiple code variations and I just can't make it work. I'm trying to create a button that will appear in place of the "ADD TO CART" button on single product pages when the item is out of stock. Clicking the button will fire a popup contact form.
Is creating an add action in functions the right way to go, or should I replace the normal button with an if statement? I've tried both, so help with coding either would be greatly appreciated.
You can either hook into woocommerce_loop_add_to_cart_args using a filter in your functions.php or edit the template file directly by pulling it into your theme. Either way will require a bit of PHP.
If doing it in your functions.php, it would look something like this (untested but should send you down the right path):
<?php
add_filter( 'woocommerce_loop_add_to_cart_link', 'my_out_of_stock_button' );
function my_out_of_stock_button( $args ){
global $product;
if( $product && !$product->is_in_stock() ){
return 'Contact us';
}
return $args;
}
I don't know what your button code should actually look like or what other information you need to capture, but this is how you could override the "Add to Cart" button and replace it if out of stock.
UPDATE
LoicTheAztec brought up a great point - the filter provided only affects the button on the archive, category, tag overview pages - not the individual product pages. There are no hooks for the individual product page buttons BUT you can copy the templates to your theme and override them.
You'll want to look at the files in templates/single-product/add-to-cart. Use a similar if statement as above:
#simple.php
<?php if ( $product->is_in_stock() ) : ?>
// Standard WooCommerce code
<?php else: ?>
// Your button code
<?php endif; ?>
Just add below code in functions.php file of your enabled theme reference
add_action('woocommerce_after_shop_loop_item', 'themelocation_change_outofstock_to_contact_us', 1);
// for shop page
function themelocation_change_outofstock_to_contact_us() {
global $product;
if (!$product->is_in_stock()) {
remove_action('woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart');
remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart');
//change the link to your contact us page
echo ' Contact Us ';
}
}
// for single page
add_filter('woocommerce_get_availability', 'wcs_custom_get_availability', 1, 2);
function wcs_custom_get_availability($availability, $_product) {
// Change In Stock Text
if ($_product->is_in_stock()) {
$availability['availability'] = __('Available!', 'woocommerce');
}
// Change Out of Stock Text
if (!$_product->is_in_stock()) {
$availability['availability'] = __(' Contact Us ', 'woocommerce');
}
return $availability;
}
I was looking for a way to show a contact button on bespoke products and
#ahwychkchih solution works great. One issue I had though is that schema markup will show as out of stock for those products which is not the case for beskpoke products is just they can't be purchased straight away so I've added this to force in_stock markup for my products. I'm aware that this solution would affect all products so you can always add a product id filter if needed
// Force In Stock schema markup
function fix_my_product_offers_schema ($markup_offer, $product) {
if (!$product->is_in_stock()) {
$markup_offer['availability'] = 'https://schema.org/InStock';
}
return $markup_offer;
}
add_filter('woocommerce_structured_data_product_offer', 'fix_my_product_offers_schema', 1, 2);
I'm using Woocommerce and I've customized my site to display the product titles in a table and when clicked the product is placed via ajax in the Woocommerce mini-cart widget without a page refresh.
When I update to 'Woocommerce 2.5.2' the Ajax add to cart no longer works and the page refreshes.
The current link I use to add a product is:
$html = $html . '<div class="numlist_thumb"><a data-product_id="' . $id1 . '" data-product_sku="' . $number1 . '" class="numbertabanchor add_to_cart_button dp-button product_type_simple" rel="nofollow" href="/?add-to-cart=' . $id1 . '">' . $number1 . '</a></div>';
I would really appreciate any suggestions as to how to add a product via ajax without a page refresh.
This is the theme conflicts with woocommerce. I faced this problem too. So whenever the woocommerce launched any major update, theme also updated according to latest woocommerce. So you have to update your theme according to woocommerce.
Add the "ajax_add_to_cart" class to your <a> tag
As a reference have a look at my code for single-product/add-to-cart/simple.php
<button type="submit" class="single_add_to_cart_button add_to_cart_button button ajax_add_to_cart button--itzel button--text-thick" data-quantity="1" data-product_id="<?php echo $product->id; ?>"><i class="button__icon icon icon-cart"></i><span><?php echo esc_html( $product->single_add_to_cart_text() ); ?></span></button>
You can easily create the add to cart functionality via the [wp_ajax][1] action, and in the callback function you can simply add the following code
add_action( "wp_ajax_custom_add_to_cart", "custom_add_to_cart_callback" );
add_action( "wp_ajax_nopriv_custom_add_to_cart", "custom_add_to_cart_callback" );
function custom_add_to_cart_callback(){
global $woocommerce;
$woocommerce->cart->add_to_cart( $_POST[ 'prod_id' ] );
wp_die();
}
After this you can easily just make an ajax call to the server, where you will post the product id as variable prod_id and add another variable named action with value custom_add_to_cart
I am attempting to add a buy now button in Woocommerce on the product page so there are two buttons:
add to cart
buy now (which will add the product to the cart and redirect to checkout)
I still want add to cart to function as usual.
How can I achieve this? Many thanks.
http://wordpress.org/extend/plugins/woocommerce/
I managed to resolve this by finding this blog post http://samplacette.com/skip-shopping-cart-in-woocommerce/.
If anyone else finds that they are struggling to implement this, this is how I did it (might not be the best solution but it works for me):
I copied the following text into my theme functions.php
/** * Set cart item quantity action *
* Only works for simple products (with integer IDs, no colors etc) *
* #access public
* #return void */
function woocommerce_set_cart_qty_action() {
global $woocommerce;
foreach ($_REQUEST as $key => $quantity) {
// only allow integer quantities
if (! is_numeric($quantity)) continue;
// attempt to extract product ID from query string key
$update_directive_bits = preg_split('/^set-cart-qty_/', $key);
if (count($update_directive_bits) >= 2 and is_numeric($update_directive_bits[1])) {
$product_id = (int) $update_directive_bits[1];
$cart_id = $woocommerce->cart->generate_cart_id($product_id);
// See if this product and its options is already in the cart
$cart_item_key = $woocommerce->cart->find_product_in_cart( $cart_id );
// If cart_item_key is set, the item is already in the cart
if ( $cart_item_key ) {
$woocommerce->cart->set_quantity($cart_item_key, $quantity);
} else {
// Add the product to the cart
$woocommerce->cart->add_to_cart($product_id, $quantity);
}
}
}
}
add_action( 'init', 'woocommerce_set_cart_qty_action' );
And then I modified theme/woocommerce/single-product/add-to-cart/simple.php (make sure you don't midify the plugin files so make a copy and paste into your theme files into a woocommerce folder) to the following (notice that I had removed my quantity input from my code so if you need it,ensure you rework the code to get it working):
<form class="cart single-product" method="post" enctype='multipart/form-data'>
<?php do_action( 'woocommerce_before_add_to_cart_button' ); ?>
<input type="hidden" name="add-to-cart" value="<?php echo esc_attr( $product->id ); ?>" />
<button type="submit" class="single_add_to_cart_button button alt cart-buttton add-to-cart"><?php echo $product->single_add_to_cart_text(); ?></button>
<?php do_action( 'woocommerce_after_add_to_cart_button' ); ?>
</form>
<form class="cart single-product" method="post" enctype='multipart/form-data' action="/checkout?set-cart-qty_<?php echo $product->id;?>=1">
<button type="submit" class="single_add_to_cart_button button alt cart-buttton buy-now">Buy Now</button>
<input type="hidden" name="add-to-cart" value="<?php echo esc_attr( $product->id ); ?>" />
</form>
I added another button next to the existing Add to Cart button but separating the form. The blog post mentions that you can add a hyperlink instead but the above worked for me in terms of the way I needed to customise the page (slightly more long winded)
From blog:
Usage instructions:
Create a hyperlink with a query string argument like so:
?set-cart-qty_=
Where is the numerical ID of your product (something like “167”) and is the >quantity you want set in the user’s shopping cart (most likely this will just be “1”).
Example URL to send user to checkout with exactly one item of product with ID “167” in cart:
http://my.website.com/checkout?set-cart-qty_167=1
I hope the above helps anyone who has a similar problem as I had.
After much searching I was surprised this is not something that is standard.
Here was my solution:
Either use a hook like "woocommerce_single_product_summary"
Or copy the wp-content/plugins/woocommerce/templates/single-product/add-to-cart/simple.php to your child theme like:
wp-content/themes/child-theme/woocommerce/single-product/add-to-cart/simple.php
Edit the file and add the following code where you want the button to appear:
<div class="express-checkout-wrapper">
<a id="dc_express_checkout" href="/checkout/?add-to-cart=<?php echo get_the_ID(); ?>">
Purchase
</a>
</div>
Now the only problem is the button will take you to checkout and add the correct product but without the correct quantity if you changed it so I used js in my custom.js file that is queued in the footer:
// Add and change quantity to express checkout button when the quantity is updated
if($('.cart .qty').length){
var originalUrl = $('#dc_express_checkout').attr('href');
$('.cart .qty').change(function(){
var url = originalUrl + '&quantity=' + $(this).val();
$('#dc_express_checkout').attr('href', url);
});
}
You can change the url from:
href="/checkout/?add-to-cart=<?php echo get_the_ID(); ?>"
to:
href="/cart/?add-to-cart=<?php echo get_the_ID(); ?>"
If you want the button to direct to the cart instead of the checkout page.