Multiple Flat-Rate Shipping Options - Yes You Can!

jeffphillipsjeffphillips Member
in Help edited April 2008
Soon this will be a *standard* feature through the admin but, at the time of this post, it is not. But that doesn't mean it can't be done! Just have to get creative.

Offering multiple flat-rate shipping options to your customers at checkout is possible. All made doable using the jQuery javascript library implemented with Foxycart. (great jQuery tutorials and info on their site).

Scenario: Lets say you wanted to provide your buyers two or more unique, flat-rate shipping options at checkout (using radio button group). For example;

Please Select a Shipping Method:
(radio) Canada Post: $15.00
(radio) FedEx: $28.00

When the buyer selects an options, the "Shipping&Handling" and "Order Total" will dynamically update to reflect the price.

Here's example Code needed to accomplish this, then I'll explain:
<script type="text/javascript" charset="utf-8">
/* <![CDATA[ */
	$j(document).ready(function(){
		// find the "cart Subtotal" field and insert html code just before it.
		$j("#fc_subtotal").before('<label class="fc_label_left fc_shipping_methods">Shipping Methods</label><p><label><input type="radio" name="shipping_service" onclick="fc_UpdatePrice(-1)" value="1|15" id="shipping_service_1" />Canada Post: $15.00</label><br /><label><input type="radio" name="shipping_service" onclick="fc_UpdatePrice(-1)" value="2|25" id="shipping_service_2" />Puralator: $25.00</label><br /></p>');
	});
/* ]]> */
</script>

Make it work:
    [li](1) the script block must be inserted in your checkout template *after* the ^^cart^^, ^^checkout^^ placeholders. So, down just before your </body> tag should be fine[/li]
    [li](2) "$j(document).ready(function(){...}" is a jQuery call that just says that when this page is done loading, perform the function given between { ... }[/li]
    [li](3) $j("#fc_subtotal").before(' ... '); - a call saying, find the input field with the ID=fc_subtotal, and insert the following HTML code just before it. (yes there is an after paramater too - see the jQuery site for details).

    In my case I used Firebug (a Firefox plugin) to explore the complex html structure of the checkout page. You'll need to do this (or view source) to locate the desired location to insert your new html. So, in my example I'm inserting the html for the shipping options right before the "Cart Subtotal" field that has the id=fc_subtotal"[/li]
    [li](4) Notice each radio input has an "onclick" event handler. E.g. onclick="fc_UpdatePrice(-1)"; With unique values of "value="1|15" and "value=2|25". These are important to get right because this info is used to update prices. The input id's indicated they are "1" and "2" of the shipping_service radio group (ie, shipping_service_1, shipping_service_2). The "value" attributes have the form "id#|price#. That is, "value=1|15" translated is saying, "input with id=1 | has assigned price value of 15 dollars". So, when the user selects an options the "fc_UpdatePrice()" function is called that updates prices accordingly[/li]

    You can rearrange the HTML and use CSS to format things to look better but, this gives a start.

    The wiki FAQ has more examples of how this technique can be used.
Comments
  • brettbrett FoxyCart Team
    edited April 2008
    Awesome.

    We've actually mentioned this possibility to a few people in the past, but nobody ever seemed to be interested in it. (We decided that it was more important for us to focus on actually building this as a "real" option in the admin, so we didn't focus on it ourselves.) There are very few things that can't be accomplished with a bit of jQuery and a healthy dose of Firebug.

    You could conceivably extend this to display different options based on the selected country, which might also be interesting.

    Thanks for sharing this with the community. I'm sure there are a few people that could kiss you for it.
  • jeffphillipsjeffphillips Member
    edited April 2008
    I'll put on some lipstick ;)

    (joking so, nobody get any ideas!)
  • Brett, you bring up something interesting by mentioning the possibility of displaying diff options based on selected country. I have a store that has rights to sell product in Canada but not the U.S. (other partner has rights to U.S.). Is it possible to do conditionals with jQuery?

    E.g:
    if (the country is equal to USA) then {
    hide the payment section and show message "We are not able to sell to USA customers. Please order from the USA store"
    } else if (the country does not equal USA) then {let them purchase}
  • brettbrett FoxyCart Team
    The if/then/else logic would be handled with regular javascript (not jQuery), but it should certainly work (at least theoretically).

    What you'd have to do is add an onchange event to the country field and go from there. Actually, you'd add the check for the country before you did anything (since the country is auto-populated based on a geoIP database, so it might not start out as Canada), then recheck onchange. The only thing that might be odd is the autocomplete code on the country field, but I don't think it'd create any problems.

    If you need help with the js, let me know.
  • I have a question about this implementation: I don't suppose there's a way that the information in the radio buttons (ie destinations and price) could be dynamically controlled by the site owner by updating entries in their CMS (I'm thinking of using ExpressionEngine)? The client for a job I'm working on want to be able to set up their own table of postage rates using Australia Post as an alternative to having live shipping rates.
  • lukeluke FoxyCart Team
    Not currently. They could add some javascript to their checkout template in their CMS and then recache the checkout template on the foxycart side, but that's a two step processes and would take some interesting javascript magic.

    What you're describing is what the "super ship" option would most likely include. Go ahead and vote for it here: http://wiki.foxycart.com/feature_requests
  • I've tried to vote for it, but every time I do the results come back saying it's received 0 results.
  • rwbakerrwbaker Member
    edited October 2008
    This script was a good starting point for me. I updated it to match the new HTML in the checkout page (v4.0). Hope it can help someone else.

    Instead of putting the script in the HTML, I opted to link to the JS file on my own domain. This way, I can update the script easier (and in my own code editor) instead of logging into the FoxyCart admin for every tweak.
    $j(document).ready(function(){
    	$j("ol#fc_shipping_list").before('<div id="fc_shipping_methods_container" class="fc_row fc_shipping_methods_container">
    		<label for="fc_shipping_methods" class="fc_label_left fc_shipping_methods">
    			Shipping Methods
    		</label>
    		<div id="fc_shipping_methods" class="fc_radio_group_container fc_row fc_shipping_methods">
    			<input name="shipping_service_id" id="shipping_service_id" value="0" type="hidden"><input name="shipping_service_description" id="shipping_service_description" value="" type="hidden">
    			<div id="fc_shipping_methods_inner">
    				<label class="fc_label_radio" for="shipping_service_1">
    					<input name="shipping_service" checked="checked" id="shipping_service_1" value="1|3.95" class="fc_radio fc_required" onclick="FC.checkout.updatePrice(-1)" type="radio"><span class="fc_shipping_carrier"></span>
    					<span class="fc_shipping_service">&nbsp;Standard Shipping</span>
    					<span class="fc_shipping_cost"><span class="fc_currency_symbol">$</span>3.95</span>
    				</label>
    				<label class="fc_label_radio" for="shipping_service_2">
    					<input name="shipping_service" id="shipping_service_2" value="2|13.90" class="fc_radio fc_required" onclick="FC.checkout.updatePrice(-1)" type="radio"><span class="fc_shipping_carrier">&nbsp;Warm Weather Shipping</span>
    					<span class="fc_shipping_service"></span>
    					<span class="fc_shipping_cost"><span class="fc_currency_symbol">$</span>13.90</span>
    				</label>
    			</div>
    			<label for="fc_shipping_methods" class="fc_error" style="display: none;">
    				Please select a shipping method.
    			</label>
    		</div>
    	</div>');
    });
    
    
  • yaorexyaorex Member
    edited June 2009
    [moved this comment to a new discussion]
  • brettbrett FoxyCart Team
    Hi yaorex.
    Welcome to FoxyCart.
    What you're describing (adding shipping to the cart, pre-checkout) sounds like something that www.modernash.com is doing. Unfortunately it's a _really_ advanced bit of code going on on that (at least, really advanced for a javascript novice).

    That said, the values you've listed could probably be approximated using a handling fee, something like $9.99 + 10% of order total... That gets you quite close to what you're looking for, and would be pretty easy to do without any advanced javascript.
  • yaorexyaorex Member
    Thanks, brett! That looks like a viable solution for now. Sorry about the double post confusion.
  • Would like to try this idea in v060. I tried to make the jeffphillips code work above and no luck. Any help would be great.
  • brettbrett FoxyCart Team
    edited February 2010
    @erikzett, you actually want this one. That said, I just tried it in 060 and didn't have luck, so post over there if you have questions.

    (In case this is confusing to anybody else reading this thread, I know this because of a discussion on yet another thread ;)
Sign In or Register to comment.