Use Address Autofill for Online Checkout (Javascript)
This example combines several Mapbox Search JS elements together to simulate an online checkout experience. It includes form filling from autofill, a visual reference Minimap, and an address confirmation step.
Fill out the form below. Try one of the following user flows, or experiment on your own.
Scenario 1: Search for Address and Autofill form
- Start typing an address into the address field
- Choose a suggested address
- Confirm the address' location on the minimap
- Click the Continue button
- Confirm the final address, or go back and change it
Scenario 2: Manually fill form and confirm address
- Manually enter an incomplete or inaccurate address into the form fields
- Click the Continue button
- If the address is not an exact match for a known address, the address confirmation dialog will open
- Choose whether to use the suggested address or to continue with the one you entered
- Confirm the final address, or go back and change it
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Use Address Autofill for Online Checkout (Javascript)</title>
<!-- Default styling. Feel free to remove! -->
<link href="https://api.mapbox.com/mapbox-assembly/v1.3.0/assembly.min.css" rel="stylesheet">
<script id="search-js" defer="" src="https://api.mapbox.com/search-js/v1.0.0-beta.24/web.js"></script>
</head>
<body>
<div class="round border border--gray-lighter px12 py24" style="min-height: 550px;">
<div class="wmax600 mx-auto">
<div class="address-page">
<h4 class="txt-l txt-bold mb6">Shipping Address</h4>
<!-- address form with `autocomplete` attributes on each address input -->
<form class="flex flex--column">
<!-- first and last name -->
<div class="grid grid--gut12">
<div class="col w-1/2">
<label class="txt-s txt-bold color-gray mb3">First Name</label>
<input class="input mb12" name="first-name" required="">
</div>
<div class="col w-1/2">
<label class="txt-s txt-bold color-gray mb3">Last Name</label>
<input class="input mb12" name="last-name" required="">
</div>
</div>
<!-- address-line1 with search icon -->
<label class="txt-s txt-bold color-gray mb3">Address</label>
<div class="relative color-gray">
<input class="input mb12" autocomplete="address-line1" name="address-line1" required="">
<svg class="absolute" viewBox="0 0 18 18" xml:space="preserve" width="20" height="20" fill="currentColor" style="top: 8px; right: 8px">
<path d="M7.4 2.5c-2.7 0-4.9 2.2-4.9 4.9s2.2 4.9 4.9 4.9c1 0 1.8-.2 2.5-.8l3.7 3.7c.2.2.4.3.8.3.7 0 1.1-.4 1.1-1.1 0-.3-.1-.5-.3-.8L11.4 10c.4-.8.8-1.6.8-2.5.1-2.8-2.1-5-4.8-5zm0 1.6c1.8 0 3.2 1.4 3.2 3.2s-1.4 3.2-3.2 3.2-3.3-1.3-3.3-3.1 1.4-3.3 3.3-3.3z">
</path>
</svg>
</div>
<!-- address-line2 -->
<label class="txt-s txt-bold color-gray mb3">Apartment, suite, etc. (optional)</label>
<input class="input mb12" autocomplete="address-line2" name="address-line2">
<!-- address-level2, address-level1, postal-code -->
<div class="grid grid--gut12 mb12">
<div class="col w-1/3">
<label class="txt-s txt-bold color-gray mb3">City</label>
<input class="input mb12" autocomplete="address-level2" name="address-level2" required="">
</div>
<div class="col w-1/3">
<label class="txt-s txt-bold color-gray mb3">State / Region</label>
<input class="input mb12" autocomplete="address-level1" name="address-level1" required="">
</div>
<div class="col w-1/3">
<label class="txt-s txt-bold color-gray mb3">ZIP / Postcode</label>
<input class="input" autocomplete="postal-code" name="postal-code" required="">
</div>
</div>
<!-- minimap for visual confirmation-->
<div id="minimap-container" class="none h180 wfull relative mt18 mb60"></div>
<!-- continue button -->
<div class="mb12 submit-btns align-r">
<button type="submit" class="btn round">
Continue
</button>
</div>
</form>
<!-- end address form -->
</div>
</div>
<!-- confirmation page -->
<div class="confirm-page none">
<div class="confirm-order-blurb">
<h4 class="txt-l txt-bold mb6">Confirm Order</h4>
<p class="mb24">
Review your order and shipping details below. This is only an example, so we aren't going to ship
anything
to you.
</p>
</div>
<div class="order-submitted-blurb none mb24">
<h4 class="txt-l txt-bold mb6">Order Submitted!</h4>
<p class="mb12">
Your order is on the way!
</p>
<div class="txt-ms border-b color-blue color-blue-dark-on-hover link restart-button inline-block">Try this example again</div>
</div>
<!-- order details -->
<div class="round border border--gray-light px18 py6 flex mb24">
<div class="txt-bold mr24 w60">Order</div>
<div class="flex-child-grow">1 - Mapbox Developer Tee Shirt</div>
</div>
<!-- shipping address -->
<div class="round border border--gray-light px18 py6 flex mb24">
<div class="txt-bold mr24 w60">Ship To</div>
<div class="flex-child-grow" id="shipping-address"></div>
<div>
<div class="txt-ms border-b color-blue color-blue-dark-on-hover link change-address-button">Change</div>
</div>
</div>
<div class="mb12 submit-btns align-r">
<button type="submit" class="btn round submit-order-button">
Submit Order
</button>
</div>
</div>
</div>
<script>
// TO MAKE THE MAP APPEAR YOU MUST
// ADD YOUR ACCESS TOKEN FROM
// https://account.mapbox.com
const ACCESS_TOKEN = 'YOUR_MAPBOX_ACCESS_TOKEN';
let autofillCollection;
let minimap;
// show the minimap
function showMap() {
const el = document.getElementById("minimap-container");
el.classList.remove("none");
}
function showConfirmPage() {
document.querySelector('.address-page').classList.add('none')
document.querySelector('.confirm-page').classList.remove('none')
}
function showAddressPage() {
document.querySelector('.address-page').classList.remove('none')
document.querySelector('.confirm-page').classList.add('none')
}
function showSubmittedPage() {
document.querySelector('.submit-order-button').classList.add('none')
document.querySelector('.confirm-order-blurb').classList.add('none')
document.querySelector('.change-address-button').classList.add('none')
document.querySelector('.order-submitted-blurb').classList.remove('none')
}
function restartExample() {
window.location.reload();
}
// build out HTML to display the shipping address as formatted text
function buildAddressHTML(formData) {
let addressHTML = `${formData.get('first-name')} ${formData.get('last-name')}<br/>`
addressHTML += `${formData.get('address-line1 address-search')}<br/>`
if (formData.get('address-line2')) addressHTML += `${formData.get('address-line2')}<br/>`
addressHTML += `${formData.get('address-level2')} ${formData.get('address-level1')} ${formData.get('postal-code')}`
return addressHTML
}
// click listener for for the "Change" link
document.querySelector('.change-address-button').addEventListener('click', showAddressPage)
// click listener for for the "Submit Order" button
document.querySelector('.submit-order-button').addEventListener('click', showSubmittedPage)
// click listener for for the "Try this example again" link
document.querySelector('.restart-button').addEventListener('click', restartExample)
// Autofill initialization
window.addEventListener('load', function () {
mapboxsearch.config.accessToken = ACCESS_TOKEN;
// autofill() automatically binds address search to the address-line1 input
autofillCollection = mapboxsearch.autofill({});
// initialize a minimap
minimap = new MapboxAddressMinimap();
minimap.canAdjustMarker = true;
minimap.satelliteToggle = true;
minimap.onSaveMarkerLocation = (lnglat) => {
console.log(`Marker moved to ${lnglat}`);
};
// append the minimap to the page
const minimapContainer = document.getElementById("minimap-container");
minimapContainer.appendChild(minimap);
// when the user selects a suggested address, show the minimap
autofillCollection.addEventListener(
"retrieve",
async (e) => {
if (minimap) {
minimap.feature = e.detail.features[0];
showMap();
}
}
);
// when the form is submitted, use confirmAddress() to confirm the address
const form = document.querySelector("form");
form.addEventListener("submit", async (e) => {
e.preventDefault();
const result = await mapboxsearch.confirmAddress(form, {
minimap: true,
skipConfirmModal: (feature) => {
return ['exact'].includes(
feature.properties.match_code.confidence
)
}
});
// if no change is suggested, the address is confirmed. continue to the confirmation page
if (result.type === 'nochange') {
const formData = new FormData(e.target)
// populate the form data to the confirmation page
document.getElementById('shipping-address').innerHTML = buildAddressHTML(formData)
showConfirmPage();
}
});
})
</script>
</body>
</html>
Was this example helpful?