We can use this to add an auto-address feature to the Suite Comerce Advance website using the www.smarty.com auto-address API.
JavaScript:
_.extend(AddressEditFieldsView.prototype,{
template: jj_addressbook_addressbook_tpl,
events: _.extend({}, AddressEditFieldsView.prototype.events, {
'keyup [data-action="searchAutoAddress"]': 'searchAddress',
'click [data-action="autoaddress-select"]': 'fetchAddress'
}),
searchAddress: _.debounce(function (e) {
try {
let self = this;
self.autoAddressInput = e.currentTarget.value;
e.preventDefault();
$(".auto-address-validation").text("");
if (self.autoAddressInput !== "" && self.autoAddressInput.length > 3) {
let url = new URL("https://us-autocomplete-pro.api.smarty.com/lookup");
url.searchParams.set("key", "199**********897");
url.searchParams.set("search", self.autoAddressInput);
url.searchParams.set("source", "all");
fetch(url.href).then(res => res.json().then(response => {
self.autoAddressOptions = response.suggestions;
self.setAutoAddressOptions();
if (response.suggestions.length === 0) {
self.throwError("No address with the relative text was found", "error", true, $(".auto-address-validation"))
}
})).catch(error => {
self.throwError("An error occured during fetch address", "error", false, $(".auto-address-validation"))
console.log(error);
})
} else {
self.autoAddressOptions = [];
self.setAutoAddressOptions();
}
} catch (error) {
console.error("ERROR @ searchAddress", error);
}
}, 750),
fetchAddress: function (e) {
try {
$(".auto-address-validation").text("");
let self = this;
let { addr1, secondary, entries, city, state, zipcode } = e.currentTarget.dataset;
if (parseInt(entries) > 1) {
let url = new URL("https://us-autocomplete-pro.api.smarty.com/lookup");
url.searchParams.set("key", "199**********897");
url.searchParams.set("search", addr1);
url.searchParams.set("selected", `${addr1} ${secondary} (${entries}) ${city} ${state} ${zipcode}`);
url.searchParams.set("source", "all");
fetch(url.href).then(res => res.json().then(response => {
self.autoAddressOptions = response.suggestions;
self.setAutoAddressOptions();
})).catch(error => {
self.throwError("An error occured during fetch address", "error", false, $(".auto-address-validation"))
console.log(error);
})
} else {
$('[name="addr1"]').val(addr1);
$('[name="addr2"]').val(secondary);
$('[name="city"]').val(city);
$('[name="country"]').val("US");
$('[name="state"]').val(state);
$('[name="zip"]').val(zipcode);
self.autoAddressOptions = [];
self.setAutoAddressOptions();
}
} catch (error) {
console.error("ERROR @ fetchAddress", error);
}
},
setAutoAddressOptions: function () {
try {
let self = this;
let optionsText = "";
if (self.autoAddressOptions.length > 0) {
_.each(self.autoAddressOptions, addressData => {
optionsText += `<li class="auto-address-options address-edit-fields-group-input" data-action="autoaddress-select" data-addr1="${addressData.street_line ?? ""}" data-secondary="${addressData.secondary ?? ""}" data-entries="${addressData.entries}" data-city="${addressData.city ?? ""}" data-state="${addressData.state ?? ""}" data-zipcode="${addressData.zipcode ?? ""}" > ${addressData.street_line ?? ""}, ${addressData.entries > 1 ? (addressData.secondary !== "" ? `${addressData.secondary} (${addressData.entries} entries),` : ` (${addressData.entries} entries),`) : (addressData.secondary !== "" ? `${addressData.secondary},` : "")} ${addressData.city ?? ""}, ${addressData.state ?? ""}, ${addressData.zipcode ?? ""}</li>`
});
$(".address-lists").html(optionsText);
$(".address-lists").show();
} else {
$(".address-lists").hide();
}
} catch (error) {
console.error("ERROR @ setAutoAddressOptions", error);
}
},
throwError: function (message, type, closable, container) {
try {
let validation = new GlobalViewsMessageView({
message: message,
type: type,
closable: closable,
});
container.html(validation.render().$el.html());
} catch (error) {
console.error("Error @ throwError", error);
}
},
getContext: _.wrap(AddressEditFieldsView.prototype.getContext, function (fn) {
try{
let context = fn.apply(this,_.toArray(arguments).slice(1));
context.autoAddressAvailable = true;
return context
} catch (e) {
console.log("err@barcode2View", e);
}
})
})
Template:
<div class="address-edit-fields">
<div data-type="alert-placeholder"></div>
<small class="address-edit-fields">{{translate 'Required'}} <span class="address-edit-fields-required">*</span></small>
<div class="address-edit-fields-group" data-input="fullname" data-validation="control-group">
<label class="address-edit-fields-group-label" for="{{manage}}fullname">
{{translate 'Full Name'}} <span class="address-edit-fields-group-label-required">*</span>
</label>
<div class="address-edit-fields-group-form-controls" data-validation="control">
<input type="text" class="address-edit-fields-group-input" id="{{manage}}fullname" name="fullname" value="{{fullName}}">
</div>
</div>
{{#if showCompanyField}}
<div class="address-edit-fields-group" {{#if isCompanyFieldMandatory}} data-input="company" data-validation="control-group" {{/if}}>
<label class="address-edit-fields-group-label" for="{{manage}}company">
{{translate 'Company'}}
{{#if isCompanyFieldMandatory}}
<span class="address-edit-fields-group-label-required">*</span>
{{else}}
<p class="address-edit-fields-company-optional-label">{{translate '(optional)'}}</p>
{{/if}}
</label>
<div class="address-edit-fields-group-form-controls" {{#if isCompanyFieldMandatory}} data-validation="control" {{/if}}>
<input type="text" class="address-edit-fields-group-input" id="{{manage}}company" name="company" value="{{company}}" >
</div>
</div>
{{/if}}
<div class="address-edit-fields-group" data-input="addr1" data-validation="control-group">
<label class="address-edit-fields-group-label" for="{{manage}}addr1">
{{translate 'Address'}} <span class="address-edit-fields-input-required">*</span>
</label>
<div class="address-edit-fields-group-form-controls" data-validation="control">
{{#if autoAddressAvailable}}
<input type="text" class="address-edit-fields-group-input" id="{{manage}}addr1" name="addr1" value="{{addressLine1}}" data-action="searchAutoAddress">
<div class="auto-address-validation"></div>
{{else}}
<input type="text" class="address-edit-fields-group-input" id="{{manage}}addr1" name="addr1" value="{{addressLine1}}">
{{/if}}
<small class="address-edit-fields-input-help">{{translate 'Example: 1234 Main Street'}}</small>
{{#if content}}
<small class="address-edit-fields-input-help">{{content}}</small>
{{/if}}
<ul class="address-lists" style="display: none;"></ul>
</div>
</div>
{{#if showAddressFormSecondAddress}}
<div class="address-edit-fields-group address-edit-fields-group-big" data-input="addr2">
<label for="{{manage}}addr2" class="address-edit-fields-addr2-optional-label">
{{translate '(optional)'}}
</label>
<div>
<input type="text" class="address-edit-fields-group-input" id="{{manage}}addr2" name="addr2" value="{{addressLine2}}">
<small class="address-edit-fields-input-help">{{translate 'Example: Apt. 3 or Suite #1516'}}</small>
</div>
</div>
{{/if}}
<div class="address-edit-fields-group" data-input="city" data-validation="control-group">
<label class="address-edit-fields-group-label" for="{{manage}}city">
{{translate 'City'}} <span class="address-edit-fields-input-required">*</span>
</label>
<div class="address-edit-fields-group-form-controls" data-validation="control">
<input type="text" class="address-edit-fields-group-input" id="{{manage}}city" name="city" value="{{city}}">
</div>
</div>
<div class="address-edit-fields-group {{#unless showCountriesField}} hide {{/unless}}" data-view="CountriesDropdown" data-input="country" data-validation="control-group">
</div>
<div class="address-edit-fields-group" data-input="state" data-view="StatesView" data-validation="control-group">
</div>
<div class="address-edit-fields-group" data-input="zip" {{#if isZipOptional}} style="display: none;" {{/if}} data-validation="control-group">
<label class="address-edit-fields-group-label" for="{{manage}}zip">
{{translate 'Zip Code'}} <span class="address-edit-fields-input-required">*</span>
</label>
<div class="address-edit-fields-group-form-controls" data-validation="control">
<input type="text" class="address-edit-fields-group-input" id="{{manage}}zip" name="zip" value="{{zip}}" data-type="zip">
<small class="address-edit-fields-input-help">{{translate 'Example: 94117'}}</small>
</div>
</div>
<div class="address-edit-fields-group" data-input="phone" data-validation="control-group">
<label class="address-edit-fields-group-label" for="{{manage}}phone">
{{translate 'Phone Number'}}
{{#if isPhoneFieldMandatory}}
<span class="address-edit-fields-input-required">*</span>
{{else}}
<p class="address-edit-fields-phone-optional-label">{{translate '(optional)'}}</p>
{{/if}}
</label>
<div class="address-edit-fields-group-form-controls" data-validation="control">
<input type="tel" class="address-edit-fields-group-input" id="{{manage}}phone" name="phone" value="{{phone}}" data-action="inputphone">
<small class="address-edit-fields-input-help">{{translate 'Example: 555-123-1234'}}</small>
</div>
</div>
<div class="address-edit-fields-group" data-input="isresidential">
<label class="address-edit-fields-group-input-checkbox">
<input type="checkbox" id="{{manage}}isresidential" value="T" data-unchecked-value="F" name="isresidential" {{#if isAddressResidential}} checked {{/if}} >
{{translate 'This is a Residential Address'}}
<i class="address-edit-fields-icon-question-sign" data-toggle="tooltip" title="" data-original-title="{{translate 'Indicating that this is a residential address will help us determine the best delivery method for your items.'}}"></i>
</label>
</div>
{{#if showDefaultControls}}
<div class="address-edit-fields-group" data-input="defaultbilling">
<label class="address-edit-fields-group-input-checkbox">
<input type="checkbox" id="{{manage}}defaultbilling" value="T" data-unchecked-value="F" name="defaultbilling" {{#if isAddressDefaultBilling}} checked {{/if}}>
{{#if isCurrentTouchPointCheckout}}
{{translate 'Save as my primary billing address'}}
{{else}}
{{translate 'Make this my default billing address'}}
{{/if}}
</label>
</div>
<div class="address-edit-fields-group" data-input="defaultshipping">
<label class="address-edit-fields-group-input-checkbox">
<input type="checkbox" id="{{manage}}defaultshipping" value="T" data-unchecked-value="F" name="defaultshipping" {{#if isAddressDefaultShipping}} checked {{/if}}>
{{#if isCurrentTouchPointCheckout}}
{{translate 'Save as my primary shipping address'}}
{{else}}
{{translate 'Make this my default shipping address'}}
{{/if}}
</label>
</div>
{{/if}}
</div>
{{!----
Use the following context variables when customizing this template:
manage (String)
showCompanyField (Boolean)
isCompanyFieldMandatory (Boolean)
isPhoneFieldMandatory (Boolean)
showCountriesField (Boolean)
isZipOptional (Boolean)
isAddressResidential (Boolean)
showDefaultControls (Boolean)
isAddressDefaultBilling (Boolean)
isCurrentTouchPointCheckout (Boolean)
isAddressDefaultShipping (Boolean)
showAddressFormSecondAddress (Boolean)
fullName (String)
addressLine1 (String)
city (String)
zip (String)
phone (String)
company (String)
addressLine2 (String)
----}}
SCSS:
#auto-address-container,
div#in-modal-auto-address-container,
.address-edit-fields-group-form-controls:has([name="addr1"]){
position: relative;
}
.address-lists{
display: grid;
background: #F3F3F3;
position: absolute;
top: 50px;
z-index: 50;
width: 300px;
max-height: 350px;
overflow-y: auto;
scrollbar-width: thin;
}
.auto-address-options{
border: 1px solid gray;
padding: 5px;
cursor: pointer;
}
.auto-address-options:hover{
background-color: #0a72e1;
color: #fff;
}
@media (max-width: $screen-sm-max) {
.address-lists{
width: 100%;
}
}