I have a button on a woocommerce page (http://.../product/abcd/) that has a button "Book Appointments Now" that links to another page with form fields to submit (http://.../booking-appointments/?id=1238&sku=1) which has ProductID and SKU on the URL of that product from the previous page.
I want it to auto-populate the ProductID field automatically each time this page loads from the URL parameters.
Any help is appreciated.
To auto populate the product ID and the product SKU in your booking form (page), you should try this (without any guaranty as it can be tested for real on your page form):
add_action( 'wp_footer', 'autopopulate_product_id_script' );
function autopopulate_product_id_script() {
if( isset( $_GET['id'] ) ):
?>
<script type="text/javascript">
(function($){
$('input[name="productid"]').val("<?php echo $_GET['id']; ?>");
$('input[name="productsku"]').val("<?php echo $_GET['sku']; ?>");
})(jQuery);
</script>
<?php
endif;
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
The product id and the product sku need to be passed in url something like: http//www.example.com/booking-page/?id=124&&sku=AH1584
And your <imput> text fields should be something like:
<input type="text" name="productid" val="">
<input type="text" name="productsku" val="">
So for the product sku is something similar, that you will be able to add with ease…
But as javascript is already very active in you "Easy Appointments" booking form, I don't know if this will work.
This answer is related to: Add custom "Booking" button to WooCommerce Product single pages
You can pass the product ID and SKU in the URL and get it via $_GET. Then load it into the input field. Here's an example:
http://www.example.com/?product-id=123&sku=abcd456
Then use $_GET to get the URL parameters:
$productId = $_GET['product-id'];
$sku = $_GET['sku'];
Your input field would be like this:
<label for="product-id">Product ID:</label> <input type="text" name="product-id" id="product-id" value="<?php echo $productId; ?>" disabled>
I even added a disabled attribute to prevent the user/customer from editing the product ID. You can use PHP to secure it from the backend when the form gets submitted.
Related
I have a site with over 20,000 users. Occasionally I need to update the author of a post. However, the sheer amount of users makes the "Author" metabox on the edit post screen unusable. I'm trying to make a custom box where I can input the desired author's ID and change the post author to that ID. Ideally, I would like to do this within the box itself, rather than by way of saving/updating the post.
Here's my custom meta box code:
//Get the post data
$id = get_the_ID();
$author_id= $post->post_author;
<div class="update-author">
<p><strong>Current Author ID:</strong> <?php echo $author_id;?></p>
<p><strong>CHANGE AUTHOR ID TO:</strong></p>
<form id="update-author-form" method="post" action="<?php echo esc_url( admin_url('admin-post.php') ); ?>" >
<input type="hidden" name="action" value="update_author_form">
<input type="hidden" name="post-id" value="<?php echo $id; ?>">
<input type="number" id="update-author-id" name="update-author-id" value="" />
<button id="update-author-button" class="button button-primary button-large">Update Author ID</button>
</form>
</div>
Next, I have my form function built as follows:
function handle_update_author_form() {
$post_id = $_POST['post-id'];
$update_id = $_POST['update-author-id'];
$my_post = array(
'ID' => $post_id,
'post_author' => $update)_id,
);
wp_update_post( $my_post );
}
At this stage, my form button does nothing but refresh the page and send it to the posts screen (I know, I need to change the redirect URL).
Like in comments - I would go for a another approach of removing the original meta_box and replacing it with a new one - or alternatively just use a JS to turn the dropdown list into a searchable field ( for example the excellent select2 plugins - but have others - and also pure JS is quite easy - see example below )
Anyhow - in your code that you posted you are missing the hook where you can apply and invoke your code, for example:
'add_action( 'save_post', 'handle_update_author_form', 10, 1 ); '
Have a look at wp filters and actions.
The suggested (simple) JS solution :
Now, for the simple approach of just using JS to pseudo-search inside the dropdown and therefor there is no real need to interfere with the query or post injections.....
myPlugin.php / myTHeme,php
function admin_enqueue_scripts_callback(){
// We are using select2.js from CDN here ..
//This will add Select2 CSS
wp_enqueue_style( 'select2-css', 'https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/css/select2.min.css', array(), '4.1.0-rc.0');
////This will add Select2 JS
wp_enqueue_script( 'select2-js', 'https://cdn.jsdelivr.net/npm/select2#4.1.0-rc.0/dist/js/select2.min.js', 'jquery', '4.1.0-rc.0');
// Now we need a JavaScript file to initialize the Select2 elements
// here it is staged as a plugin - but a theme would be the same .
wp_enqueue_script( 'select2-init', '/wp-content/plugins/select2-init.js', 'jquery', '4.1.0-rc.0');
}
add_action( 'admin_enqueue_scripts', 'admin_enqueue_scripts_callback' );
select2-init.js
// initialize select2 on author dropdown field with jQuery
jQuery(document).ready(function($) {
$('#post_author_override').select2();
});
voilà !
At this point you will have the pseudo-search implemented that would resolve your problem in a practical way without any new ->queries or $objects and with minimum coding.
Possible / potential caveats
I am not sure what would be the efficiency of filtering 20,000 items.
It would be interesting to know how the select2 JS would perform with such a long list...
But if it is already loaded to the DOM i guess it would be ok ( might take a few seconds to react though )
Please let me know how it performing if you implement the solution.
I have a created a new template inside theme's folder named Pre-Checkout Customer Details where there is a form. and the page looks like:
<?php /* Template Name: Pre-Checkout Customer Details */ ?>
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
get_header(); ?>
<form action="/checkout/?">
<input type="name" name="name">
<input type="date" name="start_date">
<input type="submit" name="Next">
</form>
<?php get_footer(); ?>
Along with that, this page's URL will always contain some parameters such as
?add-to-cart=608&subscribe='weight_loss_plan'
which will look somewhat:
https://challengecenter-q8.com/pre-checkout-customer-details/?add-to-cart=608&subscribe=%D8%A8%D9%86%D8%A7%D8%A1%20%D8%B9%D8%B6%D9%84%20%D8%A3%D8%B4%D8%AA%D8%B1%D8%A7%D9%83%20%D8%A7%D8%B3%D8%A8%D9%88%D8%B9%D9%8A%D9%86%20%D9%88%D8%AC%D8%A8%D8%AA%D9%8A%D9%86
Now when I am clicking on submit, it is showing page not found instead of moving to the cart page. Also, I want the form details to show on the checkout page like: https://challengecenter-q8.com/checkout/?name='value 1'&date='04-04-2021'
How can I achieve that?
Thank you in advance!
Note: “Enable AJAX add to cart buttons on archives” is enabled and “Redirect to the cart page after successful addition”. is disabled.
I would look into using actions to accomplish what you're trying to do. You can use the template_redirect action to check for your URL parameter and programmatically add that item to the cart then redirect to which ever page you would like.
You can simply create an anchor link for the page you're currently on that has the parameter you're needing (in my case 'atc').
Here's a piece of code I use to do this.
add_action('template_redirect', 'mks_add_to_cart');
function mks_add_to_cart(){
$pid = filter_input( INPUT_GET, 'atc', FILTER_VALIDATE_INT );
if( !empty( $pid ) ) {
global $woocommerce;
$woocommerce->cart->add_to_cart( $pid );
wp_redirect( site_url() . '/cart' );
exit;
}}
Use another action for your second part to display on the checkout page. I use Business Bloomer Visual Hook Guide often to reference where I want information to show.
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 have a hidden input field, which I want to fetch in my functions.php, but I keep getting NULL as a return value.
Here is my code:
add_filter('woocommerce_add_cart_item_data', 'add_custom_field_data_to_cart', 10, 2 );
function add_custom_field_data_to_cart($cart_item_data, $product_id, $variation_id) {
$cart_item_data['myHiddenInput'] = $_POST['myHiddenInput'];
return $cart_item_data;
}
Can someone maybe tell me why I get NULL ?
EDIT
The hidden input field is on my archive-products.php of my woocommerce-shop
<input type="hidden" name="myHiddenInput" value="">
The value gets set by using javascript
UPDATE
What I want to achive is, that I have an archive-products page where all my products are listed. Now, above my products I have a tab-menu with the next 5 days of the week. So I click the tab "Wednesday 19." the value of the hidden input gets the date of the active menu-tab:
<input type="hidden" name="chosenDate" value="2018-09-19">
Now I add a product to my cart. Then I click the menu-tab "Friday 21." - the value of the hidden filed gets updated -> I add a product to the cart.
Now when I go to my cart page - I want the products to have the dates listed when they will get delivered (the dates from the menu-tab when they were added)
as #LoicTheAztec Said
You can't pass anything custom from any archive page via ajax add to cart button as if you look to the source code of Ajax add to cart… There is no possible additional arguments or hooks. So you will need to build your own Ajax add to cart functionality, which is something huge and complicated. So your hooked function woocommerce_add_cart_item_data will have no effect
so the best logic is to use Javascript to achieve your goal and you can do it like the below solution:
First Lets add those value inside the add to cart button as an attribute instead of input tag.
for that we are going to us woocommerce_loop_add_to_cart_args hook as follow:
add_filter( 'woocommerce_loop_add_to_cart_args', 'change_item_price', 10, 2 );
function change_item_price( $args, $product ) {
$args['attributes'] = $args['attributes'] + [ 'data-chosen-date' => '2018-09-19' ];
return $args;
}
you can add as many attribute as you want and modify the value through your script and then store those value when the user click add to cart intro session storage and then in the cart page you can get those values and append them to cart table so for example:
add_action( 'wp_footer', 'script' );
function script() {
if ( is_shop() ) {?>
<script>
document.body.addEventListener('click', add_to_cart);
function add_to_cart(e) {
if (e.target.classList.contains('add_to_cart_button')) {
let val = e.target.getAttribute('data-chosen-date');
let product_id = e.target.getAttribute('data-product_id');
sessionStorage.setItem(product_id, val);
}
}
</script>
<?php
}
if ( is_cart() ) {
?>
<script>
var items = document.querySelectorAll("td");
items.forEach(function (item, index) {
if (item.classList.contains('product-remove')) {
var id = item.childNodes[1].getAttribute('data-product_id');
if (sessionStorage.getItem(id)) {
var textnode = document.createElement('p');
textnode.innerHTML = sessionStorage.getItem(id);
item.nextElementSibling.nextElementSibling.appendChild(textnode)
}
}
}); </script>
<?php
}
}
output :
The Date after the item link in the cart table has been retrieved from our storage session and each value we stored is maped with the product id as key in our storage session so we can have different value for each product.
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.