Adding a special instructions field and a "tip" field to checkout.

I'm hoping to add a special instructions field to the checkout page and the option for a customer to add a tip (our checkout is limited to delivery, so this would be very useful).

Any help would be much appreciated.
Comments
  • fc_jedfc_jed FoxyCart Team
    @blicht454

    Where would you want your special instructions field to be located? Since you have a wide range of control on how your checkout looks, there are many ways to go about this.

    The easiest way is to use the Custom Checkout Fields. You can do that by going to your store admin's Template Configuration and checking Add custom form fields to your checkout. Place your HTML code in the text area for the custom checkout fields. You can place your special instructions and format it however you want alongside an input field for the option for a customer to tip. Though, you would have to explicitly add some javascript code to add whatever amount the customer places there to the order total and then render the checkout so that you can see the change reflected.

    You can take cues on how to add an amount to the order total from an input in the custom checkout field in this snippet: https://wiki.foxycart.com/v/2.0/snippets/gift_wrapping_checkbox_on_checkout

    Another way to do it is to customize the checkout template and embed the HTML code inside the block where you want it to be located. You can do that by going to your store admin's Checkout template, select custom template and embed the HTML code from your chosen location here: https://github.com/FoxyCart/2.0-templates/blob/master/checkout.inc.twig

    Let us know if you have additional questions regarding this. We're happy to help.
  • @fc_jed

    That makes sense for the most part, but I'm a little lost on how the Gift Wrapping is helpful to adding a tip. Because the gift wrapping has a set amount but a tip would be a custom amount set by the customer. How can we approach that? The customer will need to see the tip they add and how it changes their total.

    Let me know what you recommend.

    Thanks!
  • fc_jedfc_jed FoxyCart Team
    @blicht454

    Using the gift wrapping code, you could modify it to instead have a checkbox input, have a text/numeric/dropdown/whatever input you want. There would be no need for the condition for the checked attribute. The price in the FC.client.request would then be dependent on the price the customer sets. The key thing to take away from the snippet is the FC.client.request, it's what allows the tip to be added to the cart dynamically.
  • @fc_jed

    Yeah, that makes sense. I'm having a little trouble modifying that code to make it work though. I'm able to change the checkbox to a text field allowing for a custom tip, but I'm unclear on how I can make that tip update to the total. Because there is some logic that changes the total and adds the line item when the box is checked but I'm not sure how to make that happen when a tip is entered. Will we need to require the customer to "confirm" the tip by pressing a button or something?
  • fc_adamfc_adam FoxyCart Team
    @blicht454,

    You're spot on - the existing logic is tied to a change event on the checkbox. You could instead tie to the blur event of the text input - which is triggered whenever the customer moves away from the text input when it has focus. Alternatively you could add in a link or button which when clicked would update the tip amount. Give the following modification of the snippet a try:
    <script>$('body').on('click', '#tip_confirm', function(e){
    e.preventDefault();
    // The FC.client.request() gets new JSON which clears out the shipping.
    // TODO: This will be fixed by FoxyCart, but for now we have a shim.
    var shipping_results = FC.json.shipping_address.shipping_results,
    shipping_service_description = FC.json.shipping_address.shipping_service_description,
    shipping_service_id = FC.json.shipping_address.shipping_service_id;

    var tip_id;
    var tip_existing = 0;
    for (i=0; i < FC.json.items.length; i++) {
    if (FC.json.items[i].code == 'tip') {
    tip_id = FC.json.items[i].id;
    tip_existing = FC.json.items[i].price;
    }
    }

    var tip_new = $("#tip").val() || 0;
    FC.json.tip = tip_new;

    var add_link = 'https://'+FC.settings.storedomain+'/cart?name=Tip&price=' + tip_new + '&code=tip&quantity_max=1';
    var remove_link = 'https://'+FC.settings.storedomain+'/cart?cart=update&quantity=0&id='+tip_id;

    // Add and remove
    if (tip_id && tip_new != tip_existing && tip_new > 0) {
    FC.client.request(remove_link).done(function() {
    FC.client.request(add_link).done(function() {
    FC.json.shipping_address.shipping_results = shipping_results;
    FC.json.shipping_address.shipping_service_description = shipping_service_description;
    FC.json.shipping_address.shipping_service_id = shipping_service_id;
    FC.checkout.render();
    });
    });
    } else {
    var action_link = "";
    if (tip_id && tip_new == 0) {
    action_link = remove_link;
    }
    if (!tip_id && tip_new > 0) {
    action_link = add_link;
    }

    if (action_link != "") {
    FC.client.request(action_link).done(function() {
    FC.json.shipping_address.shipping_results = shipping_results;
    FC.json.shipping_address.shipping_service_description = shipping_service_description;
    FC.json.shipping_address.shipping_service_id = shipping_service_id;
    FC.checkout.render();
    });
    }
    }
    });
    FC.client.on("ready.done", function() {
    for (i=0; i < FC.json.items.length; i++) {
    if (FC.json.items[i].code == 'tip') {
    FC.json.tip = FC.json.items[i].price;
    }
    }
    FC.checkout.renderAdditionalFields();
    });
    </script>
    That new javascript also requires a change to the HTML as well:
    <div class="fc-form-group">
    <div class="col-sm-8 col-sm-offset-3">
    <div class="fc-input-group-container fc-input-group-container--checkbox fc-input-group-container--active">
    <label class="fc-input-group-container__title fc-input-group-container__title--forced fc-form-label">
    Tip
    </label>
    <div class="fc-form-group fc-form-group--multiple-inline">
    <div class="col-xs-4">
    <input type="text" id="tip" value="{{ tip }}" placeholder="Tip" class="fc-form-control fc-form-control--tip">
    </div>
    <div class="col-xs-8">
    <p>
    <button type="button" id="tip_confirm" class="fc-button">Add Tip</button>
    </p>
    </div>
    </div>
    </div>
    </div>
    </div>
    Try that out and see if that suits what you need.
  • @fc_adam

    Yes, this is perfect, thanks!
  • @fc_adam

    Actually just one issue with this: it's taxing the tip amount. Is there a way to make sure the tip is added after the tax or have it as a non-taxed item?
  • fc_adamfc_adam FoxyCart Team
    @blicht454.

    Good question - you'd need to alter the add to cart URL for the tax to add it to a category that was set to not be taxable. That would be specifically on this line:

    var add_link = 'https://'+FC.settings.storedomain+'/cart?name=Tip&price=' + tip_new + '&code=tip&quantity_max=1'
  • @fc_adam

    Got it! Thanks!
Sign In or Register to comment.