Skip to content

Instantly share code, notes, and snippets.

@osecluna
Last active January 24, 2020 16:07
Show Gist options
  • Save osecluna/6c6deb9f708f77973a6f2a9c08dc6cec to your computer and use it in GitHub Desktop.
Save osecluna/6c6deb9f708f77973a6f2a9c08dc6cec to your computer and use it in GitHub Desktop.
DC Extension to populate a dropdown from an API
{ "MerchandisingZones": [ { "Title": "Fashion", "Image": "/Images/Content/ShopByCategory/SBD_APP_Fashion.jpg", "ImageAlt": "Fashion 100047", "NavigateURL": "/pages/category?nav=n:100047", "NavigationDimension": "100047", "NavigateContentType": "categories" }, { "Title": "Shoes & Handbags", "Image": "/Images/Content/ShopByCategory/SBD_APP_SHL.jpg", "ImageAlt": "Shoes & Handbags 128153", "NavigateURL": "/pages/category?nav=n:128153", "NavigationDimension": "128153", "NavigateContentType": "categories" }, { "Title": "Jewellery", "Image": "/Images/Content/ShopByCategory/SBD_APP_Jewellery.jpg", "ImageAlt": "Jewellery 100101", "NavigateURL": "/pages/category?nav=n:100101", "NavigationDimension": "100101", "NavigateContentType": "categories" }, { "Title": "Beauty", "Image": "/Images/Content/ShopByCategory/SBD_APP_Beauty.jpg", "ImageAlt": "Beauty 100038", "NavigateURL": "/pages/category?nav=n:100038", "NavigationDimension": "100038", "NavigateContentType": "categories" }, { "Title": "Home & Garden", "Image": "/Images/Content/ShopByCategory/SBD_APP_HomeGarden.jpg", "ImageAlt": "Home & Garden 100071", "NavigateURL": "/pages/category?nav=n:100071", "NavigationDimension": "100071", "NavigateContentType": "categories" }, { "Title": "Kitchen", "Image": "/Images/Content/ShopByCategory/SBD_APP_Kitchen.jpg", "ImageAlt": "Kitchen 100072", "NavigateURL": "/pages/category?nav=n:100072", "NavigationDimension": "100072", "NavigateContentType": "categories" }, { "Title": "Health & Fitness", "Image": "/Images/Content/ShopByCategory/SBD_APP_HealthFitness.jpg", "ImageAlt": "Health & Fitness 2058731", "NavigateURL": "/pages/category?nav=n:2058731", "NavigationDimension": "2058731", "NavigateContentType": "categories" }, { "Title": "Electronics", "Image": "/Images/Content/ShopByCategory/SBD_APP_Electronics.jpg", "ImageAlt": "Electronics 100073", "NavigateURL": "/pages/category?nav=n:100073", "NavigationDimension": "100073", "NavigateContentType": "categories" }, { "Title": "Coins", "Image": "/Images/Content/ShopByCategory/SBD_APP_Coins.jpg", "ImageAlt": "Coins 2070604", "NavigateURL": "/pages/category?nav=n:2070604", "NavigationDimension": "2070604", "NavigateContentType": "categories" }, { "Title": "Clearance", "Image": "/Images/Content/ShopByCategory/SBD_APP_Clearance.jpg", "ImageAlt": "Clearance 2037576", "NavigateURL": "/pages/category?nav=n:2037576", "NavigationDimension": "2037576", "NavigateContentType": "categories" } ] }
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,500,700&amp;display=swap">
<style>
body {
font-family: 'Roboto', sans-serif;
}
.ampx-body,
.ampx-link {
font-size: 13px;
}
.ampx-input__container {
display: flex;
flex-wrap: wrap;
flex-direction: column;
margin-bottom: 18px;
}
.ampx-input {
outline: none;
border: 0;
border-bottom: 1px solid #808080;
height: 30px;
flex: 1;
display: block;
margin-top: 0;
padding: 2px 2px 1px 2px;
line-height: 26px;
font-size: 14px;
height: 30px;
background: none;
width: 100%;
}
.ampx-input__label,
.ampx-input__description {
font-size: 11px;
color: #808080;
}
.ampx-input__description {
margin: 4px 0 0 0;
}
.ampx-input:focus {
outline: none;
border-bottom: 2px solid #039be5;
}
.ampx-input__container--error .ampx-input__description {
color: #ff3366;
}
.ampx-input:invalid {
border-color: #ff3366;
box-shadow: none;
-moz-box-shadow: none;
}
.ampx-input__container--error .ampx-input {
border-color: #ff3366;
}
.ampx-input__container--disabled {
opacity: 0.8;
pointer-events: none;
}
</style>
</head>
<body>
<script src="https://unpkg.com/dc-extensions-sdk/dist/dc-extensions-sdk.umd.js"></script>
<div class="ampx-input__container">
<label class="ampx-input__label">Location</label>
<select class="ampx-input" id="locality-dropdown" name="locality">
</select>
</div>
<p class="ampx-body">Value: <span class="input_value"></span></p>
<script>
let dropdown = document.getElementById('locality-dropdown');
dropdown.length = 0;
let defaultOption = document.createElement('option');
defaultOption.text = 'Choose Location';
dropdown.add(defaultOption);
dropdown.selectedIndex = 0;
const url = 'categoryAPI.json';
fetch(url)
.then(
function(response) {
if (response.status !== 200) {
console.warn('Looks like there was a problem. Status Code: ' +
response.status);
return;
}
// Examine the text in the response
response.json().then(function(data) {
let option;
for (let i = 0; i < data.MerchandisingZones.length; i++) {
option = document.createElement('option');
option.text = data.MerchandisingZones[i].Title;
console.log(data.MerchandisingZones[i]);
option.value = data.MerchandisingZones[i].NavigationDimension;
dropdown.add(option);
}
});
}
)
.catch(function(err) {
console.error('Fetch Error -', err);
});
class Extension {
constructor(sdk) {
this.sdk = sdk;
this.currentValue = "";
this.select = document.querySelector("#locality-dropdown");
this.inputValue = document.querySelector(".input_value");
this.setCurrentValue()
.finally(() => {
this.initializeInput();
this.sdk.frame.startAutoResizer();
})
}
async updateFieldValue(value) {
try {
await this.sdk.field.setValue(value);
} catch (err) {
// the field value is not set to the new value, write a warning on the console
console.log(err.message);
}
}
async setCurrentValue() {
try {
const savedValue = await this.sdk.field.getValue();
if (typeof savedValue !== "undefined") {
this.currentValue = savedValue;
}
} catch (err) {
console.log(err);
}
}
initializeInput() {
const { value = "" } = this.sdk.params.instance;
Object.assign(this.select, {
value
});
// set the select value to the saved value if the content item has been previously saved
if (this.currentValue != "")
this.select.value = this.currentValue;
// get the label to show the current select value
this.inputValue.innerHTML = this.select.value;
this.select.onchange = event => this.onInputChange(event);
}
onInputChange({ target: { value } }) {
this.inputValue.innerHTML = value;
this.updateFieldValue(value);
}
}
(async function () {
try {
new Extension(await dcExtensionsSdk.init())
} catch (e) {
console.log('Failed to connect to Extensions SDK')
}
})()
</script>
</body>
</html>
@osecluna
Copy link
Author

osecluna commented Jan 24, 2020

Note that you may have issues with CORS - I had my categoryAPI data hosted in S3 and had to add a CORS header to the S3 bucket as follows:

<AllowedOrigin>null</AllowedOrigin>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment