Both sides previous revisionPrevious revisionNext revision | Previous revision |
v:2.0:checkout [2019/02/24 23:20] – [An Example] adam | v:2.0:checkout [2023/07/19 13:02] (current) – [A Dropdown Example] adam |
---|
One of the major pieces we wanted to simplify and improve upon when we started FoxyCart was the checkout page. In addition to making it a very dynamic one-page checkout, we also revolutionized (big hypey word, we know, but we feel it's true) the way customers choose between a guest checkout or creating an account. | One of the major pieces we wanted to simplify and improve upon when we started FoxyCart was the checkout page. In addition to making it a very dynamic one-page checkout, we also revolutionized (big hypey word, we know, but we feel it's true) the way customers choose between a guest checkout or creating an account. |
| |
No longer will your customers be presented with inputs for their email and password, only to submit the form and be told that they don't have a user, and that if they'd like to register they can click the teeny tiny link in the bottom right. Odds are they don't care about registering; they just want to buy your wares as quickly as possible. Our unique approach automatically determines whether the customer has an account, and also presents easy options to checkout as a guest user if desired (and configured for your store). | No longer will your customers be presented with inputs for their email and password, only to submit the form and be told that they don't have a user, and that if they'd like to register they can click the teeny tiny link in the bottom right. Odds are they don't care about registering; they just want to buy your wares as quickly as possible. Our unique approach automatically determines whether the customer has an account, and also presents easy options within the [[https://admin.foxycart.com/admin.php?ThisAction=TemplateConfig|templates configuration settings]] to checkout as a guest user if desired (and configured for your store). |
| |
The checkout is also highly flexible, and can be modified in a variety of ways. HTML, CSS, and JavaScript are all available for you to perform advanced customizations both of the design and the functionality. | The checkout is also highly flexible, and can be modified in a variety of ways. HTML, CSS, and JavaScript are all available for you to perform advanced customizations both of the design and the functionality. |
<code html> | <code html> |
<div class="fc-form-group "> | <div class="fc-form-group "> |
<div class="col-md-8 col-md-offset-3" data-fc-error-for="referral_source" data-fc-error-class="fc-alert-container--error"> | <div class="col-sm-8 col-sm-offset-3" data-fc-error-for="referral_source" data-fc-error-class="fc-alert-container--error"> |
<div class="fc-input-group-container fc-input-group-container--checkbox fc-input-group-container--active"> | <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"> | <label class="fc-input-group-container__title fc-input-group-container__title--forced fc-form-label"> |
| |
<div class="fc-form-group"> | <div class="fc-form-group"> |
<div class="col-md-8 col-md-offset-3" data-fc-error-class="fc-alert-container--error"> | <div class="col-sm-8 col-sm-offset-3"> |
<div class="fc-input-group-container fc-input-group-container--textarea fc-input-group-container--active"> | <div class="fc-input-group-container fc-input-group-container--textarea fc-input-group-container--active"> |
<label class="fc-input-group-container__title fc-input-group-container__title--forced fc-form-label"> | <label class="fc-input-group-container__title fc-input-group-container__title--forced fc-form-label"> |
Message, gift information and/or special instructions | Order Notes (optional) |
</label> | </label> |
<div class="fc-form-group"> | <div class="fc-form-group"> |
<textarea name="Order_Notes" aria-required="false" autocomplete="off" class="fc-form-control" placeholder="Please type your Message, gift information and/or special instructions here">{{ Order_Notes }}</textarea> | <textarea name="Order_Notes" id="Order_Notes" aria-required="false" autocomplete="off" class="fc-form-control" placeholder="Questions? Feedback? Let us know!" style="background:#fff; height:5em;">{{ Order_Notes }}</textarea> |
</div> | </div> |
</div> | </div> |
| |
This code will then be inserted in your checkout page, right under the "almost done" heading on the default checkout template (above the password entry, terms of service, and the main checkout button). Go ahead and load up your checkout to see what you just added. It should look something like this: | This code will then be inserted in your checkout page, right under the "almost done" heading on the default checkout template (above the password entry, terms of service, and the main checkout button). Go ahead and load up your checkout to see what you just added. It should look something like this: |
{{ https://www.evernote.com/shard/s1/sh/1d29183a-c291-4284-9fc0-fdd72dc51a1a/ac39524686564fb6c5a43c60de7b1527/deep/0/Banners-and-Alerts-and-The-Man-Can!-Stuff-Secure-Checkout.png |Thanks to Corganics.com for beta testing 2.0. That's why they're on our screenshots :)}} | {{ https://i.ibb.co/5KLtPvy/foxycheckout.png |Thanks to Corganics.com for beta testing 2.0. That's why they're on our screenshots :)}} |
| |
Note that the HTML we've entered here can be anything at all, but this example is using the same structure as the default template. That way it automatically gets the appropriate styling. | Note that the HTML we've entered here can be anything at all, but this example is using the same structure as the default template. That way it automatically gets the appropriate styling. |
{% set options = ["Social Media", "Advertising", "Online Search", "Word Of Mouth", "Other"] %} | {% set options = ["Social Media", "Advertising", "Online Search", "Word Of Mouth", "Other"] %} |
<div class="fc-form-group "> | <div class="fc-form-group "> |
<div class="col-md-8 col-md-offset-3" data-fc-error-for="referral_source" data-fc-error-class="fc-alert-container--error"> | <div class="col-sm-8 col-sm-offset-3" data-fc-error-for="referral_source" data-fc-error-class="fc-alert-container--error"> |
<div class="fc-input-group-container fc-input-group-container--checkbox fc-input-group-container--active"> | <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"> | <label class="fc-input-group-container__title fc-input-group-container__title--forced fc-form-label"> |
</div> | </div> |
</div> | </div> |
| </div> |
| </code> |
| |
| ==== A Radio Inputs Example ==== |
| This example uses a similar approach as above, using a line of twig code at the top to set the values of the radio buttons as an array: |
| <code>{% set options = {"Monday": "Monday - First Delivery", "Wednesday": "Wednesday - Second Delivery", "Friday": "Friday - Third Delivery"} %}</code> |
| |
| This array sets out what options are present in the radio inputs - setting both the value for the input ("Monday") and the label shown to the customer ("Monday - First Delivery") - so can be edited to add or remove options as required. |
| |
| <code html> |
| {% set options = {"Monday": "Monday - First Delivery", "Wednesday": "Wednesday - Second Delivery", "Friday": "Friday - Third Delivery"} %} |
| <div class="fc-form-group "> |
| <div class="col-sm-8 col-sm-offset-3" data-fc-error-for="{% for option in options %}Delivery_{{ loop.index }} {% endfor %}" data-fc-error-class="fc-alert-container--error"> |
| <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"> |
| Delivery Day (required) |
| </label> |
| <div class="fc-form-group"> |
| <p>What day would you like to receive your delivery?</p> |
| {% for option, label in options %} |
| <div class="fc-input-group-container--radio"> |
| <label class="fc-form-label" for="Delivery_{{ loop.index }}"><input class="fc-form-control" type="radio" name="Delivery" value="{{ option }}" id="Delivery_{{ loop.index }}" {% if Delivery == option %}checked{% endif %} aria-required="true" data-fc-required /> |
| {{ label }}</label> |
| </div> |
| {% endfor %} |
| </div> |
| </div> |
| </div> |
| </div> |
| </code> |
| |
| ==== A Checkbox Example ==== |
| |
| This is a quick example of a standalone optional checkbox field for the checkout. |
| |
| Special note is that this also includes a hidden input with the same name as the checkbox included just above it in the HTML. This ensures that a value is always passed for the attribute with the transaction. A HTML form only accepts a single instance of a given input name, and a checkbox is only submitted if it's checked. With that in mind - if the checkbox isn't checked, then the hidden input is passed with the transaction. If the checkbox is checked though, then as it's the second input with the same name, it will be the value passed with the transaction. |
| |
| <code html> |
| <div class="fc-form-group"> |
| <div class="col-sm-8 col-sm-offset-3 fc-checkout__additional-field--custom-checkbox"> |
| <div class="fc-input-group-container fc-input-group-container--checkbox"> |
| <label class="fc-input-group-container__title fc-form-label fc-form-label--custom-checkbox"> |
| <input type="hidden" name="my_custom_checkbox" value="0" /> |
| <input type="checkbox" |
| id="my_custom_checkbox" |
| name="my_custom_checkbox" |
| value="1" |
| class="fc-form-control fc-form-control--custom-checkbox" |
| {{ checked(my_custom_checkbox == '1') }} /> |
| My Checkbox Label |
| </label> |
| </div> |
| </div> |
| </div> |
| </code> |
| |
| ==== A Multilingual Example ==== |
| |
| If your store is making use of [[..:template_sets|Template Sets]] to offer [[..:i18n|multilingual]] functionality on your store, you will also want to have your custom checkout fields show in the respective languages too. Here's a quick example of achieving that with the referral field from the first example above. |
| |
| You would obviously need to expand this to match the different languages you offer on your store, as selected in the template sets language dropdown. This example assumes that the default template set uses English, but there are also template sets using German and French. |
| |
| <code html> |
| {% set referral_label = "Referred by... (required)" %} |
| {% set referral_description = "Please let us know who referred you." %} |
| |
| {% if language == "german" %} |
| {% set referral_label = "Empfohlen von... (erforderlich)" %} |
| {% set referral_description = "Bitte teilen Sie uns mit, wer Sie empfohlen hat." %} |
| {% elseif language == "french" %} |
| {% set referral_label = "Référencé par... (obligatoire)" %} |
| {% set referral_description = "Veuillez nous indiquer qui vous a référé." %} |
| {% endif %} |
| |
| <div class="fc-form-group "> |
| <div class="col-sm-8 col-sm-offset-3" data-fc-error-for="referral_source" data-fc-error-class="fc-alert-container--error"> |
| <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"> |
| {{ referral_label }} |
| </label> |
| <div class="fc-form-group"> |
| <p>{{ referral_description }}</p> |
| <input type="text" id="referral_source" name="referral_source" placeholder="" autocomplete="off" class="fc-form-control" formnovalidate="" aria-required="true" value="{{ referral_source }}" data-fc-required> |
| </div> |
| </div> |
| </div> |
</div> | </div> |
</code> | </code> |
<!-- Radio --> | <!-- Radio --> |
<input type="radio" name="Delivery" value="Monday" {% if Delivery == "Monday" %}checked{% endif %} /> | <input type="radio" name="Delivery" value="Monday" {% if Delivery == "Monday" %}checked{% endif %} /> |
<input type="radio" name="Delivery" value="Tuesday" {% if Delivery == "Tuesday" %}checked{% endif %} /></code> | <input type="radio" name="Delivery" value="Tuesday" {% if Delivery == "Tuesday" %}checked{% endif %} /> |
| |
| <!-- Select Dropdown --> |
| {% set options = ["Social Media", "Advertising", "Online Search", "Word Of Mouth", "Other"] %} |
| <select name="referral_source" id="referral_source" class="fc-form-control" aria-required="true" data-fc-required> |
| <option value="">Please select</option> |
| {% for option in options %} |
| <option value="{{ option }}" {% if referral_source == option %}selected{% endif %}>{{ option }}</option> |
| {% endfor %} |
| </select> |
| </code> |
| |
**If your field name includes accented characters, or if you're setting it up as a hidden field (one prepended with ''h:'')**, then you'll need to access it in a slightly different way using Twig's global ''_context'' object. This is because the colon or accented characters in the field name changes how it needs to be referenced, as a string rather than an object. If you had a field with a ''name'' of ''h:hidden_field'', you would access it as ''_context['h:hidden_field']'' in Twig. | **If your field name includes accented characters, or if you're setting it up as a hidden field (one prepended with ''h:'')**, then you'll need to access it in a slightly different way using Twig's global ''_context'' object. This is because the colon or accented characters in the field name changes how it needs to be referenced, as a string rather than an object. If you had a field with a ''name'' of ''h:hidden_field'', you would access it as ''_context['h:hidden_field']'' in Twig. |
{% endfor %} | {% endfor %} |
{% endif %}</code> | {% endif %}</code> |
| ==== Passing Custom Fields to the Custom Shipping Code ==== |
| Include a data attribute of ''data-fc-shipping-custom-field'' to capture the information from a customer on the checkout related to the shipping. Review [[https://wiki.foxycart.com/v/2.0/shipping#passing_custom_fields_to_the_custom_shipping_endpoint|this link]] for complete information on custom fields (''fx:custom_fields'') in custom shipping code or endpoint using ''data-fc-shipping-custom-field''. |
===== Pre-Populating the Checkout with Customer Information ===== | ===== Pre-Populating the Checkout with Customer Information ===== |
Though we generally recommend [[.:sso|Single Sign-On]] and synching [[.:customers|customers]] via [[.:api|the API]], there are certain situations where you may want to pre-populate the customer's billing or shipping fields without using SSO or the API. | Though we generally recommend [[.:sso|Single Sign-On]] and synching [[.:customers|customers]] via [[.:api|the API]], there are certain situations where you may want to pre-populate the customer's billing or shipping fields without using SSO or the API. |