jQuery on checkout page for change of shipping method - hide show div 50% works - woocommerce

Adding some jQuery to the WooCommerce checkout page that will hide/show a div based on shipping method (local pickup).
This works initially but due to WooCommerce's ajax loader when switching shipping method the hidden div fades back in when the change has occurred.
I am not sure how to trigger the code again once the switch has happened.
jQuery('form.checkout').on('change','select[name^="shipping_method"]',function() {
var val = jQuery( this ).val();
if (val.match("^local_pickup")) {
jQuery('.flexible-checkout-fields-review_order_before_submit').fadeIn();
} else {
jQuery('.flexible-checkout-fields-review_order_before_submit').fadeOut();
}
});
I expect the div (.flexible-checkout-fields-review_order_before_submit) to only be visible when local pickup is selected, else hide.
Like I say, it works initially, but when you switch the shipping method we are back to square one.
Any thoughts?

I think the issue might be in your first line where you have select[name instead of input[name
Here's some code I use for the same thing so should work for you if you change the name of the element you wish to hide.
I also check and uncheck the ship-to-different-address-checkbox depending on shipping method is selected.
And finally if shipping is required I scroll the page up to the shipping address.
Remove these features if you don't want them.
// When shipping method is selected
jQuery( 'form.checkout' ).on( 'change', 'input[name^="shipping_method"]', function () {
var val = jQuery( this ).val();
if ( val.match( "^local_pickup" ) ) {
jQuery( '#ship-to-different-address-checkbox' ).prop( "checked", false ); // untick shipping checkbox
jQuery( '.shipping_address' ).slideUp(); // hide shipping address
} else {
jQuery( '.shipping_address' ).slideDown(); // show shipping address
jQuery( '#ship-to-different-address-checkbox' ).prop( "checked", true ); // tick shipping checkbox
// scroll to top of shipping address
jQuery('html, body').animate({
scrollTop: jQuery(".shipping_address").offset().top - 120
}, 1500);
}
} );

Related

Moving Coupon error code to bottom of woocommerce checkout page [duplicate]

I would like to change the position of all the coupon code-related WooCommerce messages on the checkout page.
I have successfully moved the coupon code form from its original position (top of the checkout page) to after the order details table (woocommerce_review_order_before_payment hook).
But now the coupon code message placement does not make sense, especially for mobile users, therefore I would like to move all of the coupon code-related messages below the coupon form (at the woocommerce_review_order_before_payment hook).
However, it's important that only messages that are related to coupon codes get moved and not all of the messages.
Here's a list of all the WooCommerce messages that are related to coupon codes:
Message
Message type
When
Coupon code already applied!
woocommerce-error
When you try applying a coupon code that has already been applied to your order.
Coupon "coupon-code" does not exist!
woocommerce-error
When you try applying a nonexistent coupon code.
Please enter a coupon code.
woocommerce-error
When you try applying an empty coupon field.
Coupon has been removed.
woocommerce-message
When you successfully remove a coupon code from your order.
Coupon code applied successfully.
woocommerce-message
When you successfully apply a coupon code to your order.
Could someone please help out?
First, As per said #Pavel Vnukov nested forms are not supported and are not part of the w3c standard. so you have added preventDefault so default action should not be taken.
I have fixed some code changes to the #Pavel Vnukov code to work as per your need.
Try the below code.
(function($){
$('.woocommerce-form-coupon-toggle').remove();
$(document).on("click", 'button[name="apply_coupon"]', function(event) {
event.preventDefault();
$form = $('form[name="checkout"]');
$form.block({message:''});
var data = {
security: wc_checkout_params.apply_coupon_nonce,
coupon_code: $( 'input[name="coupon_code"]' ).val()
};
$.ajax({
type: 'POST',
url: wc_checkout_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'apply_coupon' ),
data: data,
success: function( code ) {
$( '.woocommerce-error, .woocommerce-message' ).remove();
$form.removeClass( 'processing' ).unblock();
if ( code ) {
$( 'button[name="apply_coupon"]' ).parent().after( code );
$( document.body ).trigger( 'update_checkout', { update_shipping_method: false } );
}
},
dataType: 'html'
});
});
})(jQuery);
Tested and Works
It looks like a duplication of Move coupon field after checkout payment in Woocommerce?
Standart coupon form can't be placed before confirmation button - because you will include form in form - nested forms are not supported and are not part of the w3c standard.
You can easily move coupon form after confirmation button. The best way to move coupon block to another place is to use code from above question:
remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form');
add_action( 'woocommerce_review_order_before_payment', 'woocommerce_checkout_coupon_form' );
Another way is to remove coupon form from it standard position and create a custom input with a button. Than you need to add custom js code like from woocommerce source (wp-content/plugins/woocommerce/assets/js/frontend/checkout.js:536)
$(".custom_apply_coupon_code").on("click", function(event) {
var data = {
security: wc_checkout_params.apply_coupon_nonce,
coupon_code: $( 'input[name="coupon_code"]' ).val()
};
$.ajax({
type: 'POST',
url: wc_checkout_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'apply_coupon' ),
data: data,
success: function( code ) {
$( '.woocommerce-error, .woocommerce-message' ).remove();
$form.removeClass( 'processing' ).unblock();
if ( code ) {
$form.before( code );
$form.slideUp();
$( document.body ).trigger( 'update_checkout', { update_shipping_method: false } );
}
},
dataType: 'html'
});
});
Where code will include success or error message.

Contact Form 7, After Mail Send Form Hide and Another Div Show

I want to hide the form after sending the mail in contact form 7. And I want to do another div show with success message in place of the form. Like the screenshot below.
Forms can be hidden with CSS after mail is sent. But I can't do another div show with success message.
.wpcf7-form.sent { display:none; }
you can use the DOM call back wpcf7mailsent in JavaScript to hide the form and show another div.
Basic example
var wpcf7Elm = document.querySelector( '.wpcf7' );
wpcf7Elm.addEventListener( 'wpcf7mailsent', function( event ) {
jQuery(this).hide();
// Some code here to show your custom message element
}, false );
Source
try this code and let me know
var wpcf7Elm = document.querySelector( '.wpcf7' );
wpcf7Elm.addEventListener( 'wpcf7mailsent', function( event ) {
$this = jQuery(this);
$this.children('.ltr_form_area').hide();
$this.children('.ltr_form_success_div').show();
}, false );

Woocommerce disable script opening terms inline

On the checkout page in Woocommerce there is an "I accept terms and conditions" checkbox. The "terms and conditions" is a link, but Woocommerce captures the click event on the link, and instead opens a small popup(?) with the Terms and conditions page.
I would like to disable the script, and have it be just a normal link.
I identified the js code which captures this event. Unfortunately it's a part of checkout.min.js which controls other parts of the checkout experience too, so I would like to keep the rest of the script intact.
i = {
init: function() {
e(document.body).on("click", "a.woocommerce-terms-and-conditions-link", this.toggle_terms)
},
toggle_terms: function() {
if (e(".woocommerce-terms-and-conditions").length)
return e(".woocommerce-terms-and-conditions").slideToggle(), !1
}
};
i.init()
Bonus question, can I change the link to point to an arbitrary url (a pdf in this case)?
cale_b is right.
But because the link already has target="_blank" there is no need for add a new click handler. To archieve that your custom javascript code is load / run after WooCommerce's script you can use wp_add_inline_script.
I use this snippet and it works:
function disable_wc_terms_toggle() {
wp_add_inline_script( 'wc-checkout', "jQuery( document ).ready( function() { jQuery( document.body ).off( 'click', 'a.woocommerce-terms-and-conditions-link' ); } );" );
}
add_action( 'wp_enqueue_scripts', 'disable_wc_terms_toggle', 1000 );
Add this to your theme's functions.php and your done.
You can also do this by removing the woocommerce 'action'. Add this code to your functions.php file:
function stknat01_woocommerce_checkout_t_c_link() {
remove_action( 'woocommerce_checkout_terms_and_conditions', 'wc_terms_and_conditions_page_content', 30 );
}
add_action( 'wp', 'stknat01_woocommerce_checkout_t_c_link' )
WooCommerce uses jQuery, so you can use jQuery's off API to remove the event binding, and then assign your own event listener.
Important: The key to making this work is that your script MUST load / run after WooCommerce's script, otherwise the event won't be there to turn "off". If Woo's script runs after yours, it'll bind the event and yours won't remove it. I've demonstrated one method below, but you might need to use others (such as using a setTimeout):
// no-conflict-safe document ready shorthand
jQuery(function($) {
// wait until everything completely loaded all assets
$(window).on('load', (function() {
// remove the click event, and add your own to redirect
$( document.body )
.off( 'click', 'a.woocommerce-terms-and-conditions-link' )
.on( 'click', location.href='your_full_url_here');
});
});
Next, I anticipate you asking how to open the PDF in a new tab - for answers to that, see this question.
I followed this instructions for the removing inline toggle display of "Terms and conditions". It does not work until following code it is removed from checkout.min.js.
.slideToggle(),!1}},i={init:function(){e(document.body).on("click","a.woocommerce-terms-and-conditions-link",this.toggle_terms)},toggle_terms:function(){if(e(".woocommerce-terms-and-conditions").length)return e(".woocommerce-terms-and-conditions").slideToggle(),!1}};
After removing this line from checkout.min.js my checkout.js is also changed, here it is:
//remove toggle
/*
var wc_terms_toggle = {
init: function() {
$( document.body ).on( 'click', 'a.woocommerce-terms-and-conditions-link', this.toggle_terms );
},
toggle_terms: function() {
if ( $( '.woocommerce-terms-and-conditions' ).length ) {
$( '.woocommerce-terms-and-conditions' ).slideToggle();
return false;
}
}
};
*/
// no-conflict-safe document ready shorthand
jQuery(function($) {
// wait until everything completely loaded all assets
$(window).on('load', (function() {
// remove the click event, and add your own to redirect
$( document.body )
.off( 'click', 'a.woocommerce-terms-and-conditions-link' );
.on( 'click', location.href='https://yoursite.whatever');
});
});
wc_checkout_form.init();
wc_checkout_coupons.init();
wc_checkout_login_form.init();
//wc_terms_toggle.init();
});
Thank you for the script.

Linking to specific ID on another Wordpress page?

I have a header.php, that appears in every single page on my blog, with a navbar that looks like this:
<nav>
<ul>
<li>Logistics</li>
<li>Contact</li>
</ul>
</nav>
But when I click the anchor tag linking to #contact, which is located in page with id 5, as you can see by the php code, nothing happens. I tried using a slash (/#contact) but I keep getting the same behavior. Isn't this the correct way of linking to a specific id on another page?
EDIT: I also have some smooth scrolling code (below) which I think may be related to my issue.
<script>
$( document ).ready( function () {
// Add smooth scrolling to all links
$( "a" ).on( 'click', function ( event ) {
// Make sure this.hash has a value before overriding default behavior
if ( this.hash !== "" ) {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (800) specifies the number of milliseconds it takes to scroll to the specified area
$( 'html, body' ).animate( {
scrollTop: $( hash ).offset().top
}, 800, function () {
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
} );
} // End if
} );
} );
</script>
Thanks!
You have a javascript error.
<script>
$( document ).ready( function () {
// Add smooth scrolling to all links
$( "a" ).on( 'click', function ( event ) {
// Make sure this.hash has a value before overriding default behavior
if ( this.hash !== "" ) {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (800) specifies the number of milliseconds it takes to scroll to the specified area
$( 'html, body' ).animate( {
scrollTop: $( hash ).offset().top
}, 800, function () {
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
} );
} // End if
} );
} );
</script>
Here is the problem. On the home page you have a div with id #contato. On the other pages it is not there.
$( 'html, body' ).animate( {
scrollTop: $( hash ).offset().top
}, 800, function () {
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
} );
Your hash var's value is "#contato", but when js tries to get it's offset you recieve an error saying that it's impossible to read property top of 'undefined'. So, you can try to remove that part of the script from the other pages and only keep it on home. This should work like a charm. If you have any question, please ask.
LE: I'd recommend this method for smooth scroll (I didn't tested it for your case, but it always worked for me)
$(function() {
$('a[href*="#"]:not([href="#"])').click(function() {
if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
if (target.length) {
$('html, body').animate({
scrollTop: target.offset().top
}, 1000);
return false;
}
}
});
});
use
<?php echo get_page_link(5)."#contact"; ?>
instead of get permalink function

WordPress Customizer API - Toggle second checkbox if first is selected: Not saving

I have 2 checkboxes. When 1 is selected then the other one is un-checked. I have used JS to accomplish this and it works fine. But then when I click save, the option that is un-checked does not get saved. If I actually un-check the checkbox with a mouse click then it does save. What's the best way to accomplish the above situation?
PHP Action and JS that I am using:
add_action( 'customize_controls_print_footer_scripts', 'my_customizer_custom_scripts' );
function my_customizer_custom_scripts() { ?>
<script type="text/javascript">
jQuery(document).ready(function() {
/* This one shows/hides the an option when a checkbox is clicked. */
jQuery('#customize-control-checkbox1 input').click(function() {
if (jQuery('#customize-control-checkbox2 input:checked').val() !== undefined) {
jQuery('#customize-control-checkbox2 input').attr('checked', false);
}
});
jQuery('#customize-control-checkbox2 input').click(function() {
if (jQuery('#customize-control-checkbox1 input:checked').val() !== undefined) {
jQuery('#customize-control-checkbox1 input').attr('checked', false);
}
});
});
</script>
<?php
}
Figured it out have to use trigger('click') instead of the attr('checked', false).
So
jQuery('#customize-control-checkbox1 input').attr('checked', false);
Becomes
jQuery('#customize-control-checkbox1 input').trigger('click');

Resources