disable multiship to on checkout for downloadable products

jingarijingari Member
in Help edited August 2013
In our store, we allow for both physical and downloadable gifts, and we allow for multiship for the physical gifts. The issue we're having is that on the checkout page, the "shipto" section always appears because the multiship is enabled for the store, even if the customer only selects a downloadable gift that has no shipping associated. Is there a way to prevent the multiship-related "ship to" information from showing up on the checkout page?
«1
Comments
  • winstonwinston FoxyCart Team
    @jingari

    Have you ensured that the category= and code= attributes have been set properly on the downloadable products? Those items should let FoxyCart know that it's working with a downloadable and to not charge / show the shipping information.

    The other option is if you are doing any sort of custom javascript logic for shipping; it could be that it runs the shipping logic no matter the type of product in the cart.

    Feel free to send me the link to a test page and we'll look it over and see if we can help diagnose the issue!
  • brettbrett FoxyCart Team
    Thanks for the info (via whisper). It looks like that might be a bug. We'll take a look.
  • brettbrett FoxyCart Team
    @jingari, that is indeed a quirk on our end. We'll address that in our next release, but in the meantime if you need help working around it (hiding it with some javascript) let us know. Sorry about that.
  • Thanks @brett, some help with writing the javascript code as a work around would be great. We use three distinct shipping categories, only one of which needs any shipping address information to be provided. If there's more info I should provide, let me know.
  • winstonwinston FoxyCart Team
    @jingari,

    The dev who would be best at helping with that is out today, I'll email him this thread and have him check it out when he has a chance!
  • fc_adamfc_adam FoxyCart Team
    @jingari,

    This should work for what you need - include it right before the closing head tag of your checkout template:

    <script type="text/javascript">
    jQuery(document).ready(function() {
    if (FC.checkout.config.hasDownloadables && !FC.checkout.config.hasShippableProducts) {
    jQuery("#fc_address_multiship_container").hide();
    jQuery("#fc_customer_billing").on('change', 'input, select', function() {
    jQuery("#shipto_0_select").val(-1);
    FC.checkout.selectAddress(0, "#shipto_0_select");
    });
    }
    });
    </script>

    This will only hide the shipto section if there are no shippable products but there is downloadable products.
  • Thanks, @fc_adam. For our case, we also have a product category that has "no shipping" but is not a downloadable, these are custom ecards which will be fulfilled separately once the transaction has completed. I modified the script you wrote so that it's just checking whether hasShippableProducts is true, so it hides the Multi-ship to for both downloadables and these "no shipping" products, however in addition to this, I need to add something switch the Ship To address for these "No Shipping" products to the Billing Address as default because while the section is hidden, it is still defaulting to "new address" and waiting for the shipping info to be provided. Is there an easy way to do this?

    Thanks,
    Jessica
  • fc_adamfc_adam FoxyCart Team
    @jingari,

    Actually that code should already be updating the ship to address with the billing address as the billing address fields are being completed...

    Ah I see the mistake - change this line:
    FC.checkout.selectAddress(-1, "#shipto_0_select");
    

    To this:
    FC.checkout.selectAddress(0, "#shipto_0_select");
    
  • Ok, that adjustment is working for the most part, however there is one use case when it doesn't work. If the customer is already logged in when they're arriving at the cart, eg. if they logged in at the checkout page then clicked continue shopping and added more to their cart and went back again. They're already logged in, so they don't need to input their email address and their billing info is already pre-populated, so there are no changes on the billing info fields to trigger the filling of the hidden shipping info. Any ideas on how the info can be added when there is no guaranteeing that they click or modify any of the billing info fields?

    Thanks!
  • fc_adamfc_adam FoxyCart Team
    @jingari,

    Great point - try this:
    jQuery(document).ready(function() {
      if (!FC.checkout.config.hasShippableProducts) {
        jQuery("#fc_address_multiship_container").hide();
        jQuery("#fc_customer_billing").on('change', 'input, select', function() {
          updateShipToAddress();
        });
        
        updateShipToAddress();
      }
    });
    function updateShipToAddress() {
      jQuery("#shipto_0_select").val(-1);
      FC.checkout.selectAddress(0, "#shipto_0_select");
    }
    
  • Great, that works! Thanks very much
  • Hi again,
    I am still seeing an issue where if a customer adds a downloadable product to the cart and then also adds a shippable with multiship product to the cart, the checkout page is confusing. There is an address fields section for the downloadable gift as well as one for the multiship gift. There shouldn't be shipping address fields for downloadable gifts at all. So do I need to actually go through and query each gift in an order and apply the updateShipToAddress function on it so that these address fields don't show up? Or is there an easier way to ensure that Shipping Address Fields only show for items in the order that are being shipped?
  • fc_adamfc_adam FoxyCart Team
    @jingari,

    Ah, yep, that won't cover that situation.

    The javascript will need to be reworked to allow for that situation - where there is a multiship item, but it's not to the customer but to someone else. Give this a try:
    jQuery(document).ready(function() {
    	var needsMe = false;
    	var nonShipping = ["downloaded", "notshipped", "pickup"]
    	for (var i = 0; i < fc_json.products.length; i++) {
    		if (fc_json.products[i].shipto == "Me" && jQuery.inArray(fc_json.products[i].delivery_type, nonShipping) == -1) {
    			needsMe = true;
    		}
    	}
    	if (!needsMe) {
    		jQuery("#fc_shipto_0_container").hide();
    		jQuery("#fc_customer_billing").on('change', 'input, select', function() {
    			updateShipToAddress();
    		});
    
    		updateShipToAddress();
    	}
    });
    function updateShipToAddress() {
      jQuery("#shipto_0_select").val(-1);
      FC.checkout.selectAddress(0, "#shipto_0_select");
    }
    
  • This would work on the first gift in the order, but what about the subsequent gifts?
  • This seems to be working:
    jQuery(document).ready(function() {
        var needsMe = false;
        var nonShipping = ["downloaded", "notshipped", "pickup"]
        for (var i = 0; i < fc_json.products.length; i++) {
        
            if (jQuery.inArray(fc_json.products[i].delivery_type, nonShipping) == -1) {
                needsMe = true;
            }
                var container_id = "#fc_shipto_"+i+"_container";
                if (!needsMe) {
                    jQuery(container_id).hide();
                    jQuery("#fc_customer_billing").on('change', 'input, select', function() {
                        updateShipToAddress(i);
                    });
                    jQuery("#")
                    updateShipToAddress(i);
                }
            
        }
      
    });
    
    function updateShipToAddress(x) {
        var select_id = "#shipto_"+x+"_select";
            jQuery(select_id).val(-1);
            FC.checkout.selectAddress(x,select_id);
    }
    
  • fc_adamfc_adam FoxyCart Team
    @jingari,

    Actually that won't work. You're trying to use the integer of the product from the products array in the JSON to determine the multiship container - which don't match at all.

    Why would you need to hide the multiship addresses? If the person is going to download the item themselves, they don't need to specify a mutliship name - so can't you assume that for anything that is not being shipped, that it will be for the 'Me' address? So if that is the case, you only need to hide the Me address, which is what my script above did - and if it's hidden, it then also automatically updates to match the billing address.
  • You're right, it just happened to work with the order of gifts couple of tests I did. I tried the "Me" and it wasn't hiding correctly. And then it is only hiding the first container (shipto_0_container). I need it to hide all of the containers that do not need to shipping information associated with them, so need to cycle through them all some how.
  • fc_adamfc_adam FoxyCart Team
    @jingari,

    Is it possible with your set up to have a multiship address that doesn't require shipping? From looking at your store, the only time you specify a unqiue multiship name is if you're literally shipping something.
  • Right, the only time we want a multiship address is for the "MAIL" category, the other two categories do not ship and should not be collecting shipping info at the checkout page.
  • fc_adamfc_adam FoxyCart Team
    @jingari,

    I think you might be missing my question there.

    The only time your add to carts allow you to specify a multiship name (so an address that will appear on the checkout as something other than "Me") is when you select a shippable product. Therefore, any multiship address on your checkout apart from "Me" will always need to be displayed - you won't have a need to hide those at all.

    So the two categories you're not wanting to collect shipping details on - they'll be added to the "Me" shipto group on the checkout. That "Me" category is what my last script should be hiding. If you could switch back to that script from your current one, I'll take a look to see why it's not working.
  • Yes, I get that, anytime it's a "Me" it would be a product that shouldn't be shipped anyway so it should have the shipping info fields hidden. The issue is that it's only hiding or updating the ship to info the 0 product, which doesn't work when there are more than one products in the order. I've just switched back to your original code on our checkout page so you can check it out
  • fc_adamfc_adam FoxyCart Team
    @jingari,

    I think the script is working - but there may be some sort of issue with the shipto name for yourself - I'm seeing some products with "me" and some others with "Me". I'm still digging into what might be the root issue here.
  • So is there no correlation between how the products come through in the json and how they're placed into shipto_containers?
  • fc_adamfc_adam FoxyCart Team
    @jingari,

    Your last post there was caught in our spam filter - so I'm not sure when exactly you posted that in relation to the flow of this thread. To answer your question though - there is a correlation - they will be grouped by the their shipto name primarily, and then I'm pretty sure it's the same order as it is in the JSON.
  • Now I'm using the following. Getting the container ID for those items with "Me" as the shipto value and creating an array of them that will then be updated after the billing info has been input. I triggered the update with the payment info so that the billing info will be complete first. So far it's working in my testing, does it set off any alarms for you that I'm missing?

    Thanks!
    <script type="text/javascript">
    jQuery(document).ready(function() {
        var count = 0;
        var noship = [];
        var notDownload = ["ECARD","MAIL"]
      
        for (var i = 0; i < fc_json.products.length; i++) {
            console.info("shipto "+fc_json.products[i].shipto);
            if (jQuery.inArray(fc_json.products[i].category, notDownload) == -1) {
                count++;
            }
        }
    
      
    
       jQuery("#fc_payment").on('change', 'input, select', function() {
               console.info("updating billing info");
               console.info("noship length"+noship.length);
               for(var j=0;j<=noship.length;j++){
                console.info(noship[j]);
                updateShipToAddress(noship[j]);
            }
            });
    
    $(window).bind("load", function() {
      
       console.info("COUNT = "+count);
        //check each shipto_X_address_name if == 'Me', the hide and do updateShipToAddress
        for(var i=0; i<=count;i++){
            var temp = "'input#shipto_1_address_name'";//"#shipto_'+i+'_address_name"';
            var temp = "#shipto_1_select";
            var theval = $('input#shipto_1_address_name').val();
            console.info("theval = "+theval);
            var thesetval = $('input#shipto_'+i+'_address_name').val();
            console.info("thesetval = "+thesetval);
            
            if(thesetval == 'Me'){
                console.info("Got a me");
                var container = '#fc_shipto_'+i+'_container';
               noship.push(i);
               console.info("added noship");
               console.info("NOSHIP[0]= "+noship[0]);
                 jQuery(container).hide();
            }
        }
        
    });
    });
    
  • fc_adamfc_adam FoxyCart Team
    @jingari,

    So I've found out what the issue is here - and I'm surprised it hasn't come up before. If you don't specify a shipto name with the add to cart, then the product is added into the default shipto of "Me". The javascript snippet however adds products to a shipto group of "me". Note the lowercase 'm'. That difference is putting items in two different groups on your checkout - but both are essentially being shipped to the customer.

    So in terms of their ordering - the default shipto - "Me" - will always be first in the order of the page. All other shipto's are then listed after that.

    That said, I don't think your script will work in all cases - you're looping through the variable COUNT to get the different address names, but that's not doing what you expect it to do. You're not actually looping through the different shipto groups - but you're just looping through the amount of products that aren't being shipped. They won't always be the same thing.

    If you correct the multiship snippet to update all references to "me" to be "Me", that should make sure that all of your non-shipped items end up in the exact same shipto group and you don't get that double up. Then, my last snippet that I sent you should work just fine.
  • How would I go about updating the references of "me" to "Me"? Looking at the JSON, I'm not clear why some are "me" and some "Me", it doesn't seem to be based on category.
    Also, what I'm seeing is that the shipto containers with a name associated are coming up first and the "Me" and "me" containers afterwards, so just using the shipto_0_select won't work because the "Me/me" are not always in the first position, so it seems like there needs to be a way to cycle through the actual shipto_X_select values (which is what my attempt was) and hide those based on their value, and then also update those to use the billing address once the billing information has been input, or if the customer is logged in already and billing information filled in, then to update those address on another trigger, payment info changes for example.
  • fc_adamfc_adam FoxyCart Team
    @jingari,

    The Me/me difference is based on the multiship code you have on your site that you grabbed from the wiki. That is the code that adds a select dropdown element onto the page for people to select a MultiShip name or select themselves. Actually - I just realised you may have not added that code yourself, but it may be included in FoxyShop already. In that case, you'll need to find where that javascript is located and update the references as I said. @sparkweb will be able to help point you in the right direction for where that is located.

    In terms of the order - you are right - I just realised that it's all ordered alphabetically rather than "Me' first. Sorry for the confusion from my side with that!

    So taking my earlier script, this should cover what you want:
    jQuery(document).ready(function() {
    	var nonShipping = ["downloaded", "notshipped", "pickup"];
    	shipto = {};
    	jQuery(".fc_shipto_address_name").each(function(i) {
    		shipto[this.value] = {};
    		shipto[this.value]['req'] = false;
    		shipto[this.value]['i'] = i;
    	});
    	for (var i = 0; i < fc_json.products.length; i++) {
    		if (jQuery.inArray(fc_json.products[i].delivery_type, nonShipping) == -1) {
    			shipto[fc_json.products[i].shipto]['req'] = true;
    		}
    	}
    	
    	jQuery("#fc_customer_billing").on('change', 'input, select', function() {
    		updateShipToAddress();
    	});
    	updateShipToAddress();
    });
    function updateShipToAddress() {
    	for (var s in shipto) {
    		if (!shipto[s]['req']) {
    			jQuery("#fc_shipto_" + shipto[s]['i'] + "_container").hide();
    			jQuery("#shipto_" + shipto[s]['i'] + "_select").val(-1);
    			FC.checkout.selectAddress(0, "#shipto_" + shipto[s]['i'] + "_select");
    		}
    	}
    }
    

    To reiterate though - I'd strongly suggest updating the multiship javascript on your site to unify how "me" is treated.
  • sparkwebsparkweb Member, Integration Developer, FoxyShop, Order Desk
    If you'd like to edit the file that comes with FoxyShop you can edit it at wp-content/plugins/foxyshop/js/multiship.jquery.js
  • Thanks for the info @sparkweb. I've updated that file and added the coded from you, @fc_adam however it's still assuming that the "Me" addresses are first, which they aren't they're alphabetical. So if the shipto name for one of the gifts is "Frank" it will be before the "Me" in the shipto_container list. What is happening with this code is that while the "Me" container is being hidden properly, it's not being filled with the billing address information, instead the first shipto container in the list is being filled with billing information, which in this case is the "Frank" address.
Sign In or Register to comment.