Works on small home project, and want to add checkmark option bellow "Proceed to Checkout" button into Cart page into my Woocommerce site. I found this function, that is add that option:
add_action( 'woocommerce_after_cart', 'bbloomer_add_checkout_privacy_policy', 9 );
function bbloomer_add_checkout_privacy_policy() {
woocommerce_form_field( 'privacy_policy', array(
'type' => 'checkbox',
'class' => array('form-row privacy'),
'label_class' => array('woocommerce-form__label woocommerce-form__label-for-checkbox checkbox'),
'input_class' => array('woocommerce-form__input woocommerce-form__input-checkbox input-checkbox'),
'required' => true,
'label' => 'By proceeding, you are agreeing to our Terms and Conditions',
));
}
// Show notice if customer does not tick
add_action( 'woocommerce_proceed_to_checkout', 'bbloomer_not_approved_privacy' );
function bbloomer_not_approved_privacy() {
if ( ! (int) isset( $_POST['privacy_policy'] ) ) {
wc_add_notice( __( 'Please acknowledge the Terms and Conditions' ), 'error' );
}
}
But seems that something is not fine with this function, because no matter if checked or not, customer can proceed to checkout page. I want to ensure that ONLY customers who will check the checkbox, can proceed to checkout. In opposite, warning message will be shown at top.
Can someone to tell me where is issue with this function or to point me to some working solution? Thanks in advance. This is image how currently looks with this function i posted before.
The following code will work in cart page for your privacy policy checkbox using mandatory jQuery code to make it work as "proceed to checkout" button is just linked to checkout page without submitting any data.
The code will disable the button on start:
It use "Sweet alert 2" JS message to display an error message on button click when the checkbox is not checked:
The complete code:
add_action( 'woocommerce_proceed_to_checkout', 'cart_privacy_policy_checkbox', 5 );
function cart_privacy_policy_checkbox() {
woocommerce_form_field( 'privacy_policy', array(
'type' => 'checkbox',
'class' => array('form-row privacy'),
'label_class' => array('woocommerce-form__label woocommerce-form__label-for-checkbox checkbox'),
'input_class' => array('woocommerce-form__input woocommerce-form__input-checkbox input-checkbox'),
'required' => true,
'label' => sprintf( __( "I've read and accept the %s", "woocommerce" ),
''.__( "Privacy Policy", "woocommerce" ).'' ),
));
// jQuery code start below
?>
<script src="https://unpkg.com/sweetalert2#8.8.1/dist/sweetalert2.all.min.js"></script>
<script src="https://unpkg.com/promise-polyfill#8.1.0/dist/polyfill.min.js"></script>
<script type="text/javascript">
jQuery( function($){
var a = '.checkout-button', b = '#privacy_policy',
c = '<?php echo wc_get_checkout_url(); ?>', d = 'disabled';
// Set disable button state
$(a).addClass(d).prop('href', '#');
// Woocommerce Ajax cart events
$('body').on('updated_cart_totals removed_from_cart', function(){
if( ! ( $(a).hasClass(d) && $(b).prop('checked') ) ){
$(a).addClass(d).prop('href', '#');
}
})
// On button click event
$('body').on('click', a, function(e){
if( ! $(b).prop('checked') ) {
// Disable "Proceed to checkout" button
e.preventDefault();
// disabling button state
if( ! $(a).hasClass(d) ){
$(a).addClass(d).prop('href', '#');
}
// Sweet alert 2
swal({
title: '<?php _e("Pricacy Policy", "woocommerce"); ?>',
text: '<?php _e("Please acknowledge the privacy policy Terms and Conditions", "woocommerce"); ?>',
type: 'error',
timer: 3500,
showConfirmButton: false
});
}
});
// On checkbox change event
$(b).change(function(){
if($(this).prop('checked')){
if( $(a).hasClass(d) ){
$(a).removeClass(d).prop('href', c);
}
} else {
if( ! $(a).hasClass(d) ){
$(a).addClass(d).prop('href', '#');
}
}
});
});
</script>
<?php
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Sweet Alert Two documentation
Thanks a lot for this code!
It works for me, except for when the cart is updated via ajax such as when deleting an item.
In that situation, the checkbox no longer enables the Proceed to Checkout button unless I refresh the page. I finally found a solution:
Add the following snippet to the header to reload the cart page after an item is deleted from the cart.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
jQuery( document.body ).on( 'updated_cart_totals', function () {
location.reload( true );
} );
</script>
Related
Im new in this coding stuff, I researched many sites now and try to build my own checkout field in Woocommerce. It should be a checkout field, when it is checked, some information or warning should plop up, it worked with showing on checkout page normal, but my script doesn't work.
add_filter( 'woocommerce_checkout_fields', 'add_custom_checkout_fields' );
function add_custom_checkout_fields( $fields ) {
$fields['billing']['checkbox_trigger'] = array(
'type' => 'checkbox',
'label' => __('You dont live in Germany?', 'woocommerce'),
'class' => array('form-row-wide'),
'clear' => true
);
return $fields;
}
add_action( 'woocommerce_after_checkout_billing_form', 'echo_notice_billing' );
function echo_notice_billing() {
echo '<div class="billing-notice woocommerce-info" style="display:none">It may take forever</div>';
}
add_action( 'woocommerce_after_checkout_form', 'show_notice_billing' );
function show_notice_billing(){
?>
<script>
jQuery(document).ready(function($){
$('checkbox_trigger').change(function(){
if(this.checked){
$('billing-notice').show();
}
else {
$('billing-notice').hide();
}
});
});
</script>
<?php
}
There are some errors in your jQuery script… Try to replace your related function by this instead:
add_action( 'woocommerce_after_checkout_form', 'show_notice_billing' );
function show_notice_billing(){
?>
<script>
jQuery(function($){
$('#checkbox_trigger').click(function(){
if($(this).is(':checked') ){
$('.billing-notice').show();
}
else {
$('.billing-notice').hide();
}
});
});
</script>
<?php
}
Tested and works.
Hi I added custom field in billing form using this code below.
add_filter('woocommerce_billing_fields', 'custom_woocommerce_billing_fields');
function custom_woocommerce_billing_fields($fields)
{
$fields['billing_options'] = array(
'label' => __('If you pay by Invoice. Please add Your Invoice Number Here ', 'woocommerce'), // Add custom field label
'placeholder' => _x('Invoice Number', 'placeholder', 'woocommerce'), // Add custom field placeholder
'required' => false, // if field is required or not
'clear' => false, // add clear or not
'type' => 'text', // add field type
'class' => array('my-css') // add class name
);
return $fields;
}
I have two payment options 1. Cash on delivery 2.Realex Payments HPP – Credit Card.
Is it possible to show custom field only then 1. Cash on delivery selected as payment option.?
Thank you
The following code will hide billing_options custom optional checkout field when the selected payment method is Cash on delivery ("cod"):
// Conditional Show hide checkout fields based on chosen payment methods
add_action( 'wp_footer', 'conditionally_show_hide_billing_custom_field' );
function conditionally_show_hide_billing_custom_field(){
// Only on checkout page
if ( is_checkout() && ! is_wc_endpoint_url() ) :
?>
<script>
jQuery(function($){
var a = 'input[name="payment_method"]',
b = a + ':checked',
c = '#billing_options_field'; // The checkout field <p> container selector
// Function that shows or hide checkout fields
function showHide( selector = '', action = 'show' ){
if( action == '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 payment method is "cod"
if( $(b).val() !== 'cod' )
showHide( c, 'hide' );
else
showHide( c );
// Live event (When payment method is changed): Show or Hide based on "cod"
$( 'form.checkout' ).on( 'change', a, function() {
if( $(b).val() !== 'cod' )
showHide( c, 'hide' );
else
showHide( c );
});
});
</script>
<?php
endif;
}
Code goes in function.php file of your active child theme (or active theme). tested and works.
In Woocommerce checkout form im trying to hide billing_city and billing_address_1 fields first and after I fill the fields postcode and housenumber the other fields (address_1 and city) has to show.
This is the script, but I does not work well and I dont know what I do wrong:
?>
<script type="text/javascript">
jQuery('input#billing_housenumber').change(function(){
if (this.checked) {
jQuery('#billing_city').fadeIn();
jQuery('#billing_city input').val('');
} else {
jQuery('#billing_city').fadeOut();
}
});
</script>
<?php
Any help is appreciated.
Update 2
There is some errors, mistakes and missing things in your code. Also you should hooked it in a function (or register it as an external file).
I have added at the end a function that add the billing "housenumber" field in checkout (just for testing purpose)…
In the code below I am using some CSS inline styles to hide the billing city and address_1 fields and to show them when they have an additional selector class "on".
Here is a hooked function that will enable this code in checkout only:
add_action( 'wp_footer', 'custom_checkout_script' );
function custom_checkout_script() {
// Only checkout page
if( ! ( is_checkout() && ! is_wc_endpoint_url() ) ) return;
// CSS Styles (Hidding fields)
?>
<style>
#billing_city_field, #billing_address_1_field { display:none !important;}
#billing_city_field.on ,#billing_address_1_field.on { display:block!important;}
</style>
<?php
// Jquery script
?>
<script type="text/javascript">
jQuery( function($){
var a = 'input#billing_housenumber',
b = 'input#billing_postcode',
c = '#billing_city_field,#billing_address_1_field';
// On start
if( $(a).val() != '' && $(b).val() != '' && ! $(c).hasClass('on') ){
$(c).css('display','none !important').addClass('on').show();
console.log('start');
}
// On change: If housenumber and postcode fields are filled, we display other hidden fields
$(a+','+b).on( 'change', function(){
if ( $(a).val() != '' && $(b).val() != '' && ! $(c).hasClass('on') ) {
$(c).css('display','none !important').addClass('on').show( 500 );
console.log('change - in');
} else if( ( $(a).val() == '' || $(b).val() == '' ) && $(c).hasClass('on') ) {
$(c).hide( 200, function(){
$(c).removeClass('on').css('display','block')
});
console.log('change - out');
}
});
});
</script>
<?php
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
This code has been tested with this temporary additional code, that generates the checkout "housenumber" text field (just for testing purpose):
// Add custom checkout field
add_action( 'woocommerce_billing_fields', 'my_custom_checkout_field' );
function my_custom_checkout_field( $fields ) {
$fields['billing_housenumber'] = array(
'class' => array('form-row-wide'),
'label' => __('Housenumber ?'),
'required' => false,
'clear' => true
);
return $fields;
}
Code goes in function.php file of your active child theme (or active theme).
Related: Show or hide html element on chosen shipping method change in Woocommerce
There is one step left. I don't see the housenumber (after a customer purchase a product). So you don't see the housenumber in the mail or in invoice.
This is in the e-mail but I don't see more detail for address:
/**
* #hooked WC_Emails::customer_details() Shows customer details
* #hooked WC_Emails::email_address() Shows email address
*/
do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email );
In my woocommerce website, I have changed the cart page, removed the button "update cart" and create 2 buttons to add and remove items of product like I show in this picture:
When I click on the quantity buttons I want to call the same function if I press the button to update the cart.
For this I am using ajax but it doesn't do anything.
First in my function.php file I have this:
function update_my_cart() {
// here update then cart
var_dump("execute");
}
add_action( 'wp_ajax_update_my_cart', 'update_my_cart' ); // If called from admin panel
add_action( 'wp_ajax_nopriv_update_my_cart', 'update_my_cart' );
add_action( 'wp_enqueue_scripts', 'rct_enqueue_scripts' );
if ( ! function_exists( 'rct_enqueue_scripts' ) ) :
function rct_enqueue_scripts() {
wp_enqueue_script( 'rct-js', get_template_directory_uri() . '/js/themeCoffee.js', array(), '1.0', true );
wp_localize_script('rct-js', 'ajax_object', array('ajax_url' => admin_url( 'admin-ajax.php' )));
}
endif;
And in my jquery file I have this:
updatecart = function(qty) {
var currentVal, data, item_hash, request;
currentVal = void 0;
data = void 0;
item_hash = void 0;
currentVal = parseFloat(qty);
request = $.ajax({
url: 'ajax_object.ajax_url',
method: 'POST',
data: {
quantity: currentVal,
action: 'update_my_cart'
},
dataType: 'html'
});
request.done(function(msg) {
alert('cart update ');
});
request.fail(function(jqXHR, textStatus) {
alert('Request failed: ' + textStatus);
});
};
I obtain this error:
Failed to load resource: the server responded with a status of 404 (Not Found)
Because I try to load my_website/cart/ajax_object.ajax_url.
Thanks in advance!
You have forget this essential process:
add_action('wp_enqueue_scripts', 'add_my_ajax_scripts');
function add_my_ajax_scripts() {
// Here you register your script located in a subfolder `js` of your active theme
wp_enqueue_script( 'ajax-script', get_template_directory_uri().'/js/script.js', array('jquery'), '1.0', true );
// Here you are going to make the bridge between php and js
wp_localize_script( 'ajax-script', 'cart_ajax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
}
Then you will retrieve "ajaxurl" and "cart_ajax" in your javascript file in "url:":
$.ajax({
url: cart_ajax.ajaxurl,
...
})
Your javascript function will not work. Here are some functional examples of what you need to do:
WooCommerce - auto update total price when quantity changed?
Wordpress passing ajax value to a specific page using Wordpress
Using AJAX With PHP on Your WordPress Site Without a Plugin
How to use Ajax with your WordPress Plugin or Theme?
Since WooCommerce 2.6.0, released June 2016, WooCommerce cart page uses Ajax to update cart totals after clicking on Update cart button.
It's no longer needed to create your own Ajax call, the one assigned to Update cart button can be used.
I created a free plugin Ajax Cart AutoUpdate for WooCommerce which updates cart page and mini cart after changing product quantity and provides some customization options for this process.
The most important thing is to set update delay. If user changes quantity again during this delay, it will be reset to full duration. If it's not implemented and you change quantity from 1 to 10 by clicking on increment button, it will trigger 9 Ajax calls instead of 1.
JQuery code is below, I suggest placing it in js file and enqueuing in dependency with jQuery, then it works with jQuery deferred:
var timeout;
jQuery('div.woocommerce').on('change keyup mouseup', 'input.qty', function(){ // keyup and mouseup for Firefox support
if (timeout != undefined) clearTimeout(timeout); //cancel previously scheduled event
if (jQuery(this).val() == '') return; //qty empty, instead of removing item from cart, do nothing
timeout = setTimeout(function() {
jQuery('[name="update_cart"]').trigger('click');
}, 1000 );
});
I have a custom WordPress plugin that is showing me a list of data from database. I am registering it's page via:
add_menu_page(
'Naročila',
'Vsa naročila',
'administrator',
'listaj-narocila',
array( &$this, 'listaj_narocila' )
);
And then of course I have function lista_narocila which is showing me my data.
So, currently my URL is:
http://domain.com/wp-admin/admin.php?page=listaj-narocila
And I show my data from database in a table. Now I have button DELETE and EDIT for each record, but I have a hard time figuring it out, how to register custom "url" or "custom page" inside WordPress that would allow me to have URL:
http://domain.com/wp-admin/admin.php?page=single-narocilo?id=X
I know I can try with add_menu_page but I don't want this page to be in admin menus. Just to be available as URL. Currently I get no access error.
You can create a sub menu page and pass null as its parent:
$parent_slug
Use NULL or set to 'options.php' if you want to create a page that doesn't appear in any menu.
A demo:
add_action('admin_menu', function()
{
# Main page
add_menu_page(
'Vsa',
'Vsa',
'add_users', // Capability, not role
'listaj-narocila',
function(){
printf(
'<h2>%s</h2>%s',
__( 'Main page' ),
admin_url( 'admin.php?page=single-norcilo&id='.rand(1,25) ),
__( 'Hidden sub page' )
);
},
'http://sstatic.net/stackexchange/img/favicon.ico'
);
# Child page
$hook = add_submenu_page(
null,
'Norcilo',
'Norcilo',
'add_users',
'single-norcilo',
function(){
printf(
'<h2>%s</h2>%s',
__( 'Hidden sub page' ),
admin_url( 'admin.php?page=listaj-narocila' ),
__( 'back' )
);
}
);
# Enqueue script in submenu page to fix the current menu indicator
add_action( "admin_footer-$hook", function()
{
echo <<<HTML
<script type="text/javascript">
jQuery(document).ready( function($) {
$('#toplevel_page_listaj-narocila')
.removeClass('wp-not-current-submenu')
.addClass('current');
});
</script>
HTML;
});
});
An alternative approach: https://wordpress.stackexchange.com/a/114818/12615