I'm trying to hide the shipping calculator on my cart page (using jQuery) depending on which shipping method is selected, first on page load, and then when a user selects another method or updates the cart, that would enable / disable new shipping methods but I can't seem to make it work.
My Javascript / jQuery is pretty rusty so I don't know what I'm doing wrong.
The code bellow is what I've tried so far. It does work like I want on page load (= if "free shipping" is selected OR if it's the only available shipping method, the shipping calculator will be hidden.
But then when I choose another shipping method, the shipping calculator won't show up again unless I manually reload the page.
It won't work either if the cart is updated with extra product quantities (by increasing the amount of products directly on the cart page) to reach the minimum amount to have free shipping.
jQuery(document).ready(function() {
if(jQuery("*[id*=free_shipping]").is(':checked') || jQuery("*[id*=free_shipping]").is(':hidden') ){
jQuery(".woocommerce-shipping-calculator").css("display","none");
}
else{
jQuery(".woocommerce-shipping-calculator").css("display","block");
}
});
jQuery("input[type=radio]").click(function() {
if(jQuery("*[id*=free_shipping]").is(':checked')){
jQuery(".woocommerce-shipping-calculator").css("display","none !important");
}
else{
jQuery(".woocommerce-shipping-calculator").css("display","block !important");
}
})
Any help would be highly appreciated !
Thanks
thanks a lot for your explanation and code.
It almost works perfectly except when I try to update my cart. If I have a cart worth enough to trigger free shipping (over 150€) and then I remove a product to have a cart bellow 150€ and click "update cart", then regular shipping methods will show but the shipping calculator won't be displayed again.
To have it showing again I'll have to click on one of the shipping methods' radio button.
I've tried to tweek the code you gave me doing something like that but couldn't make it work :/
jQuery(document).ready(function($) {
if(jQuery("*[id*=free_shipping]").is(':checked') || jQuery("*[id*=free_shipping]").is(':hidden') ){
jQuery(".woocommerce-shipping-calculator").css("display","none");
}
else{
jQuery(".woocommerce-shipping-calculator").css("display","block");
}
jQuery('body').on('click', "input[type=radio]",function() {
if(jQuery("*[id*=free_shipping]").is(':checked') || jQuery("*[id*=free_shipping]").is(':hidden')){
setTimeout(function(){jQuery(".woocommerce-shipping-calculator").hide();}, 500);
}
else{
setTimeout(function(){jQuery(".woocommerce-shipping-calculator").show();}, 500);
}
});
});
jQuery("input[type=submit]").on('click', function() {
if(jQuery("*[id*=free_shipping]").is(':checked') || jQuery("*[id*=free_shipping]").is(':hidden')){
setTimeout(function(){jQuery(".woocommerce-shipping-calculator").hide();}, 500);
}
else{
setTimeout(function(){jQuery(".woocommerce-shipping-calculator").show();}, 500);
}
});
I've tried with ".button" instead of "input[type=submit]" and also tried to put this piece of extra code inside the whole jQuery(document).ready(function($) {[...]}).
Also I do have another question : hidding / showing the shipping calculator won't mess with inner WooCommerce functionning right ? Because I've posted on wordpress.org too and someone from Woo Support told me it was fairly complex development topic. So i'm wondering if I should not do it ?
Thanks again !
Try the following script, it will work. In fact, on each radio box selection, shipping selector was reloading and whenever you reload an HTML element so .click() event requires a new binding with that. In jQuery we used to call it .live() earlier and now we use .on(). It keeps the binding intact with the new reloaded element with the same selector or identity.
jQuery(document).ready(function($) {
if(jQuery("*[id*=free_shipping]").is(':checked') || jQuery("*[id*=free_shipping]").is(':hidden') ){
jQuery(".woocommerce-shipping-calculator").css("display","none");
}
else{
jQuery(".woocommerce-shipping-calculator").css("display","block");
}
jQuery('body').on('click', "input[type=radio]",function() {
if(jQuery("*[id*=free_shipping]").is(':checked')){
setTimeout(function(){jQuery(".woocommerce-shipping-calculator").hide();}, 500);
}
else{
setTimeout(function(){jQuery(".woocommerce-shipping-calculator").show();}, 500);
}
});
});
Related
I have this tabs built.
When I click on Round Trip, I want to make disappear that Flight 2 form.
But since that is needed on multi-city, I want it to show back on
multi-city.
I used this
jQuery('#rdbOneWay').attr("class","onewaybuttonchecked");
jQuery('#rdbRoundTrip').attr("class","roundwaybuttonchecked");
jQuery('#rdbMultiCity').attr("class","multiwaybuttonchecked");
jQuery('.ret_date_block').attr("id","noreturndate");
$("#noreturndate").hide();
$(".onewaybuttonchecked").on("click", function(){
$("#noreturndate").hide();
});
$(".roundwaybuttonchecked").on("click", function(){
$("#noreturndate").show();
});
$(".multiwaybuttonchecked").on("click", function(){
$("#noreturndate").show();
});
});
I used this to hide something on the One Way tab.
If:
$(".roundwaybuttonchecked").on("click", function(){
$("#noreturndate").show();
});
If I use here the correct id of Flights 2 to hide it on the Round-Trip, it does its job but when I switch between One-Way and Round-Trip it shows nothing.
This line get's in action when I go from Multi City to Round-Trip.
Any ideas?
You definitely need a conditional in here.
In your JQuery function, try something like this:
function radioButton() {
if (document.getElementById('htmlElement1').checked) {
document.getElementById('htmlElement2').style.visibility = 'visible';
} else {
document.getElementById('htmlElement').style.visibility = 'hidden';
}
Please note that since I cannot view your HTML - I am not sure what elements you are using so where i say htmlElement 1 (or 2) please fill that in with the appropriate elements.
Let me know you results!
Never mind.
I used same code as above
jQuery('#rdbOneWay').attr("class","onewaybuttonchecked");
jQuery('#rdbRoundTrip').attr("class","roundwaybuttonchecked");
jQuery('#rdbMultiCity').attr("class","multiwaybuttonchecked");
jQuery('.pnlFlight2').attr("id","pnlFlight2");
$("#pnlFlight2").hide();
$(".onewaybuttonchecked").on("click", function(){
$("#pnlFlight2").hide();
});
$(".roundwaybuttonchecked").on("click", function(){
$("#pnlFlight2").hide();
});
$(".multiwaybuttonchecked").on("click", function(){
$("#pnlFlight2").show();
});
and it did the trick, I don't know why it didn't work earlier but glad it did now.
I'm working on a shopping cart that asks the user to check the box indicating they agree to the terms of service before they can "review order" and finally make the purchase.
I have to accomplish this with JavaScript by getting the element containing the "review order" and "continue shopping" buttons and changing the inner HTML to be what I need. I have to do it this way because the cart I am using does not give me full control over these elements in the cart source code.
Here is the code I originally came up with, which worked on Chrome, Edge, and other browsers, but not IE.
var x = document.getElementById('CHECKOUT_LINKS');
x.innerHTML = '<div class="checkoutLinksBottom"><input id="tosBox" type="checkbox" name="tosBox">I agree to the Terms of Service<br>Continue ShoppingReview Order</div>';
document.addEventListener('DOMContentLoaded', function() {
document.querySelector('#tosBox').addEventListener('change', changeHandler);
});
var checkbox = document.getElementById("tosBox");
checkbox.checked = true;
checkbox.checked = false;
function changeHandler() {
if (!tosBox.checked)
alert("You must agree to the Terms of Service");
}
function clicker() {
if (!tosBox.checked)
alert("You must agree to the Terms of Service");
else { // Go to review order page
}
}
As you can see the CHECKOUT_LINKS element's inner HTML is changed to what I need on the fly as the page loads. The primary point is to add the id="tosBox" element, then capture the click on id="reviewOrderButton" element and filter it though the simple JS functions changeHandler() and clicker().
In IE developer tools, the console reports 'tosBox' is undefined when I click on id="reviewOrderButton" element. This makes sense when looking at var checkbox = document.getElementById("tosBox"); the variable created is called checkbox, but the variable I try to use later is called tosBox. I simply changed checkbox to tosBox and then everything worked on IE as well.
What's shocking to me is that the original code worked on Chrome and Edge. How did it work? Should I expect it to work and IE is faulting?
I have a page with a lot of elements (~1,500) of the same class on it, and when I execute
$(".pickrow").addClass("vis");
it takes a second or two for the page to reflect the changes. So that users aren't thinking the page was stuck, I'd like to pop-up a small message using:
$("#msgDiv").show();
$(".pickrow").addClass("vis");
$("#msgDiv").hide();
But the msgDiv never shows. If I remove the $("#msgDiv").hide(); the msgDiv appears simultaneously with the application of the added class (after the 1 or 2 seconds it took to add the class).
It seems like the jQuery functions get pooled and run together without any screen updates until they have all completed.
How can I get the msgDiv to appear while the $(".pickrow").addClass("vis"); is processing?
Here's a Demo
You probably want to delay the hide by a few seconds.
$("#msgDiv").show();
$(".pickrow").addClass("vis");
setTimeout(function(){ $("#msgDiv").hide(); },2000);
Or using jQuery's animations queue for timing:
$("#msgDiv").show();
$(".pickrow").addClass("vis");
$("#msgDiv").delay(2000).hide(1); //must make it at least 1 ms to go into the queue
You can go with this approach also
Working DEMO
$(document).on("click",".btn",function(){
$(".msg").show("fast",function(){
$(".pickrow").addClass("vis");
var interval = setInterval(function(){
var picLength = $(".pickrow").length;
var visLength = $(".vis").length;
if(picLength == visLength){
clearInterval(interval);
$(".msg").hide();
}
},500);
});
});
I think if you simplify the code, you would find that it is much more responsive and probably not require the loading message. In your code, you check every single element in an if statement. Rather than do that, you can check one value, then update all of them accordingly.
Here's a demo: http://jsfiddle.net/jme11/3A4qU/
I made a single change to your HTML to set the initial value of the input button to "Show Details". Then in the following code, you can just check whether the value is Show Details and remove the class that hides the .pickrow and update the value of the button to be "Hide Details" (which is better feedback for the user anyway). Likewise, you can add the .hid class to the pickrow if the button value is not "Show Details". This will also normalize all of the classes regardless if some were individually hidden or shown.
$('#showhide').on('click', function(){
if ($(this).val() === 'Show Details') {
$('.pickrow').removeClass('hid');
$(this).val('Hide Details');
} else {
$('.pickrow').addClass('hid');
$(this).val('Show Details');
}
});
Question:
How can I show the number of items in a user's cart using the minicart.js script?
Backstory:
I'm developing a static HTML website that is selling a small number of products using standard PayPal buttons and minicart.js
I'd like to have an area in the header of my website that displays the number of items currently in the "cart", but I can't figure out how to do so. There is no example detailing this functionality on the minicart.js website.
I'm sure it can be done, but I'm at a loss. Any help would be greatly appreciated. Thanks!
You can get like this:
paypal.minicart.cart.items().length
It works for me
I managed to figure out a way to achieve what I'm looking for by finding the necessary variable set through minicart.js and then manipulating it via jQuery.
minicart.js gives me the following variable which outputs the current cart total:
paypal.minicart.cart.total();
I then took that variable and applied some jQuery that converted this variable into a separate variable called "cartTotal" which is checked and updated every time a user interaction happens on the page (ie - a click or a keypress). I found that a brief delay was needed in order for everything to work properly. Interestingly, the keypress check needs a longer delay than the mouse click.
My final (for now) working code is as follows:
$( document ).ready(function() {
var cartTotal = paypal.minicart.cart.total();
$('input#cart').val('$' + cartTotal);
$( "body" ).click(function() {
setTimeout(function() { // Setting slight delay on function to accomodate for button push of removing items from cart
var cartTotal = paypal.minicart.cart.total();
$('input#cart').val('$' + cartTotal);
}, 100);
});
$( "body" ).keypress(function() {
setTimeout(function() { // Setting longer delay on function to accomodate for key push of removing items from cart
var cartTotal = paypal.minicart.cart.total();
$('input#cart').val('$' + cartTotal);
}, 900);
});
I have the following JQuery code which does similar functionality like Stackoverflow where the user clicks on the comment link and it displays the comments or in this case replies to a member's status update, generally it works great except when a member posts a new status update which updates the list of status updates using an ajax async postback in ASP.net MVC.
What happens is if you click on the new item in the list it brings them to a new page instead of doing what the JQuery is suppose to do.
<script type="text/javascript">
$(function() {
$("a[id ^='commentLink-']").click(function() {
match = this.id.match(/commentLink-(\d+)/);
container = $("div#commentContainer-" + match[1])
container.toggle();
if (container.is(":visible")) {
container.load($(this).attr("href"));
} else {
container.html("Loading...");
}
return false; //Prevent default action
});
});
</script>
Note: I think what is causing it is the fact that the new item in the list isn't actually on the page as the list was updated through the ajax so the new html isn't there until the page is refreshed.
Update Okay how would I use this live/event functionality that Paolo Bergantino spoke of in his answer to trigger an ASP.net MVC ActionResult?
Check out the new Events/live feature in jQuery 1.3
Binds a handler to an event (like click) for all current - and future - matched element.
So as you add new items, jQuery should add the click event to them with this.
If for some odd reason you do not want to upgrade to jQuery 1.3, you can check out the livequery plugin.
EDIT in response to update:
The actual code to use .live would be something like this:
$(function() {
$("a[id ^='commentLink-']").live('click', function(event) {
match = this.id.match(/commentLink-(\d+)/);
container = $("div#commentContainer-" + match[1])
container.toggle();
if (container.is(":visible")) {
container.load($(this).attr("href"));
} else {
container.html("Loading...");
}
event.preventDefault();
});
});
The changes that were made are mostly in the 2nd line, where
$("a[id ^='commentLink-']").click(function() {
was replaced by
$("a[id ^='commentLink-']").live('click', function(event) {
I am now also receiving the argument event to use for event.preventDefault(); which is the way you are recommended to stop events by jQuery. If return false; does the trick, though, you can keep that.
I haven't used .live yet, but I think that should do the trick. Make sure that you get jQuery 1.3 in your server before trying this, though. :)