@geoapify/geocoder-autocomplete
Version:
A JavaScript address autocomplete input, compatible with Leaflet, MapLibre, OpenLayers, and other map libraries for efficient location search and geocoding.
127 lines (126 loc) • 7.89 kB
JavaScript
import countiesData from "../countries.json";
export class DomHelper {
static createInputElement(inputElement, options, container) {
inputElement.classList.add("geoapify-autocomplete-input");
inputElement.setAttribute("type", "text");
inputElement.setAttribute("placeholder", options.placeholder || "Enter an address here");
container.appendChild(inputElement);
}
static addFeatureIcon(element, type, countryCode) {
const iconMap = {
'unknown': 'map-marker',
'amenity': 'map-marker',
'building': 'map-marker',
'street': 'road',
'suburb': 'city',
'district': 'city',
'postcode': 'city',
'city': 'city',
'county': 'city',
'state': 'city'
};
const countryData = countiesData.find(county => countryCode && county.code.toLowerCase() === countryCode.toLowerCase());
if ((type === 'country') && countryData) {
element.classList.add("emoji");
const emojiElement = document.createElement('span');
emojiElement.innerText = countryData.emoji;
element.appendChild(emojiElement);
}
else if (iconMap[type]) {
this.addIcon(element, iconMap[type]);
}
else {
this.addIcon(element, 'map-marker');
}
}
static addIcon(element, icon) {
//FortAwesome icons 5. Licence - https://fontawesome.com/license/free
const icons = {
"close": {
path: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z",
viewbox: "0 0 24 24"
},
"map-marker": {
path: "M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0zM192 272c44.183 0 80-35.817 80-80s-35.817-80-80-80-80 35.817-80 80 35.817 80 80 80z",
viewbox: "0 0 384 512"
},
"road": {
path: "M573.19 402.67l-139.79-320C428.43 71.29 417.6 64 405.68 64h-97.59l2.45 23.16c.5 4.72-3.21 8.84-7.96 8.84h-29.16c-4.75 0-8.46-4.12-7.96-8.84L267.91 64h-97.59c-11.93 0-22.76 7.29-27.73 18.67L2.8 402.67C-6.45 423.86 8.31 448 30.54 448h196.84l10.31-97.68c.86-8.14 7.72-14.32 15.91-14.32h68.8c8.19 0 15.05 6.18 15.91 14.32L348.62 448h196.84c22.23 0 36.99-24.14 27.73-45.33zM260.4 135.16a8 8 0 0 1 7.96-7.16h39.29c4.09 0 7.53 3.09 7.96 7.16l4.6 43.58c.75 7.09-4.81 13.26-11.93 13.26h-40.54c-7.13 0-12.68-6.17-11.93-13.26l4.59-43.58zM315.64 304h-55.29c-9.5 0-16.91-8.23-15.91-17.68l5.07-48c.86-8.14 7.72-14.32 15.91-14.32h45.15c8.19 0 15.05 6.18 15.91 14.32l5.07 48c1 9.45-6.41 17.68-15.91 17.68z",
viewbox: "0 0 576 512"
},
"city": {
path: "M616 192H480V24c0-13.26-10.74-24-24-24H312c-13.26 0-24 10.74-24 24v72h-64V16c0-8.84-7.16-16-16-16h-16c-8.84 0-16 7.16-16 16v80h-64V16c0-8.84-7.16-16-16-16H80c-8.84 0-16 7.16-16 16v80H24c-13.26 0-24 10.74-24 24v360c0 17.67 14.33 32 32 32h576c17.67 0 32-14.33 32-32V216c0-13.26-10.75-24-24-24zM128 404c0 6.63-5.37 12-12 12H76c-6.63 0-12-5.37-12-12v-40c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40zm0-96c0 6.63-5.37 12-12 12H76c-6.63 0-12-5.37-12-12v-40c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40zm0-96c0 6.63-5.37 12-12 12H76c-6.63 0-12-5.37-12-12v-40c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40zm128 192c0 6.63-5.37 12-12 12h-40c-6.63 0-12-5.37-12-12v-40c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40zm0-96c0 6.63-5.37 12-12 12h-40c-6.63 0-12-5.37-12-12v-40c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40zm0-96c0 6.63-5.37 12-12 12h-40c-6.63 0-12-5.37-12-12v-40c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40zm160 96c0 6.63-5.37 12-12 12h-40c-6.63 0-12-5.37-12-12v-40c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40zm0-96c0 6.63-5.37 12-12 12h-40c-6.63 0-12-5.37-12-12v-40c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40zm0-96c0 6.63-5.37 12-12 12h-40c-6.63 0-12-5.37-12-12V76c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40zm160 288c0 6.63-5.37 12-12 12h-40c-6.63 0-12-5.37-12-12v-40c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40zm0-96c0 6.63-5.37 12-12 12h-40c-6.63 0-12-5.37-12-12v-40c0-6.63 5.37-12 12-12h40c6.63 0 12 5.37 12 12v40z",
viewbox: "0 0 640 512"
}
};
var svgElement = document.createElementNS("http://www.w3.org/2000/svg", 'svg');
svgElement.setAttribute('viewBox', icons[icon].viewbox);
svgElement.setAttribute('height', "24");
var iconElement = document.createElementNS("http://www.w3.org/2000/svg", 'path');
iconElement.setAttribute("d", icons[icon].path);
iconElement.setAttribute('fill', 'currentColor');
svgElement.appendChild(iconElement);
element.appendChild(svgElement);
}
static getStyledAddressSingleValue(value, currentValue) {
let displayValue = value;
const valueIndex = (displayValue || '').toLowerCase().indexOf(currentValue.toLowerCase());
if (valueIndex >= 0) {
displayValue = displayValue.substring(0, valueIndex) +
`<strong>${displayValue.substring(valueIndex, valueIndex + currentValue.length)}</strong>` +
displayValue.substring(valueIndex + currentValue.length);
}
return `<span class="main-part">${displayValue}</span>`;
}
static getStyledAddress(featureProperties, currentValue) {
let mainPart;
let secondaryPart;
const parts = featureProperties.formatted.split(',').map((part) => part.trim());
if (featureProperties.name) {
mainPart = parts[0];
secondaryPart = parts.slice(1).join(', ');
}
else {
const mainElements = Math.min(2, Math.max(parts.length - 2, 1));
mainPart = parts.slice(0, mainElements).join(', ');
secondaryPart = parts.slice(mainElements).join(', ');
}
if (featureProperties.nonVerifiedParts && featureProperties.nonVerifiedParts.length) {
featureProperties.nonVerifiedParts.forEach((part) => {
mainPart = mainPart.replace(featureProperties[part], `<span class="non-verified">${featureProperties[part]}</span>`);
});
}
else {
const valueIndex = mainPart.toLowerCase().indexOf(currentValue.toLowerCase());
if (valueIndex >= 0) {
mainPart = mainPart.substring(0, valueIndex) +
`<strong>${mainPart.substring(valueIndex, valueIndex + currentValue.length)}</strong>` +
mainPart.substring(valueIndex + currentValue.length);
}
}
return `<span class="main-part">${mainPart}</span><span class="secondary-part">${secondaryPart}</span>`;
}
static addDropdownIcon(feature, itemElement) {
const iconElement = document.createElement("span");
iconElement.classList.add('icon');
DomHelper.addFeatureIcon(iconElement, feature.properties.result_type, feature.properties.country_code);
itemElement.appendChild(iconElement);
}
static addActiveClassToDropdownItem(items, index) {
for (var i = 0; i < items.length; i++) {
items[i].classList.remove("active");
}
/* Add class "autocomplete-active" to the active element*/
items[index].classList.add("active");
}
static createDropdownItemText() {
const textElement = document.createElement("span");
textElement.classList.add('address');
return textElement;
}
static createDropdownItem() {
const itemElement = document.createElement("div");
itemElement.classList.add('geoapify-autocomplete-item');
return itemElement;
}
}