I'm trying to implement Mapbox on my website. I would like to add on my home page, an autocomplete field.
I know I can add it to the map, but I would like to know if I can use a separated input field to get the job done ? I've not found anything on the Mapbox documentation.
Can someone help me with this ?
Thanks.
The mapbox team has done a good job in showing an example of it in Geocoder
And regarding your query: Yes, you can use your own input field. What you have to do is listen for every keyboard input as shown in this. Take that value as the query parameter and then make the API request as done in search.js and then display the suggestions returned by the API.
If you are using React, then you could very well, use the same code and just modify the styles for your input.
For placement of the input box If you are using leafletjs, then you can add this input as a control else, if you are using mapbox-gl-js, then you can add it as its specific control. The Control API has only fixed positions such as top-right, top-left, bottom etc. If this is not your intended positioning, then you can just place it as a simple div overlay.
AUTCOMPLETE SUGGESTION INPUT BOX WITH MAPBOX API
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Add a geocoder</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"/>
<script src="https://code.jquery.com/jquery-3.4.1.js" type="text/javascript"></script>
<script src="https://unpkg.com/@mapbox/mapbox-sdk/umd/mapbox-sdk.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
* {
box-sizing: border-box;
}
body {
font: 16px Arial;
}
/*the container must be positioned relative:*/
.autocomplete {
position: relative;
display: inline-block;
}
input {
border: 1px solid transparent;
background-color: #f1f1f1;
padding: 10px;
font-size: 16px;
}
input[type=text] {
background-color: #f1f1f1;
width: 100%;
}
input[type=submit] {
background-color: DodgerBlue;
color: #fff;
cursor: pointer;
}
.autocomplete-items {
position: absolute;
border: 1px solid #d4d4d4;
border-bottom: none;
border-top: none;
z-index: 99;
/*position the autocomplete items to be the same width as the container:*/
top: 100%;
left: 0;
right: 0;
}
.autocomplete-items div {
padding: 10px;
cursor: pointer;
background-color: #fff;
border-bottom: 1px solid #d4d4d4;
}
/*when hovering an item:*/
.autocomplete-items div:hover {
background-color: #e9e9e9;
}
/*when navigating through the items using the arrow keys:*/
.autocomplete-active {
background-color: DodgerBlue !important;
color: #ffffff;
}
</style>
</head>
<body>
<h2>Autocomplete</h2>
<p>Start typing:</p>
<!--Make sure the form has the autocomplete function switched off:-->
<form autocomplete="off" action="/action_page.php">
<div class="autocomplete" style="width:300px;">
<input id="myInput" type="text" name="myCountry" placeholder="Country">
</div>
<input type="submit">
</form>
<script>
var geocodingClient = mapboxSdk({accessToken: 'ADD_ACCESS_TOKEN_HERE'});
function autocompleteSuggestionMapBoxAPI(inputParams, callback) {
geocodingClient.geocoding.forwardGeocode({
query: inputParams,
countries: ['In'],
autocomplete: true,
limit: 5,
})
.send()
.then(response => {
const match = response.body;
callback(match);
});
}
function autocompleteInputBox(inp) {
var currentFocus;
inp.addEventListener("input", function (e) {
var a, b, i, val = this.value;
closeAllLists();
if (!val) {
return false;
}
currentFocus = -1;
a = document.createElement("DIV");
a.setAttribute("id", this.id + "autocomplete-list");
a.setAttribute("class", "autocomplete-items");
this.parentNode.appendChild(a);
// suggestion list MapBox api called with callback
autocompleteSuggestionMapBoxAPI($('#myInput').val(), function (results) {
results.features.forEach(function (key) {
b = document.createElement("DIV");
b.innerHTML = "<strong>" + key.place_name.substr(0, val.length) + "</strong>";
b.innerHTML += key.place_name.substr(val.length);
b.innerHTML += "<input type='hidden' data-lat='" + key.geometry.coordinates[1] + "' data-lng='" + key.geometry.coordinates[0] + "' value='" + key.place_name + "'>";
b.addEventListener("click", function (e) {
let lat = $(this).find('input').attr('data-lat');
let long = $(this).find('input').attr('data-lng');
inp.value = $(this).find('input').val();
$(inp).attr('data-lat', lat);
$(inp).attr('data-lng', long);
closeAllLists();
});
a.appendChild(b);
});
})
});
/*execute a function presses a key on the keyboard:*/
inp.addEventListener("keydown", function (e) {
var x = document.getElementById(this.id + "autocomplete-list");
if (x) x = x.getElementsByTagName("div");
if (e.keyCode == 40) {
/*If the arrow DOWN key is pressed,
increase the currentFocus variable:*/
currentFocus++;
/*and and make the current item more visible:*/
addActive(x);
} else if (e.keyCode == 38) { //up
/*If the arrow UP key is pressed,
decrease the currentFocus variable:*/
currentFocus--;
/*and and make the current item more visible:*/
addActive(x);
} else if (e.keyCode == 13) {
/*If the ENTER key is pressed, prevent the form from being submitted,*/
e.preventDefault();
if (currentFocus > -1) {
/*and simulate a click on the "active" item:*/
if (x) x[currentFocus].click();
}
}
});
function addActive(x) {
/*a function to classify an item as "active":*/
if (!x) return false;
/*start by removing the "active" class on all items:*/
removeActive(x);
if (currentFocus >= x.length) currentFocus = 0;
if (currentFocus < 0) currentFocus = (x.length - 1);
/*add class "autocomplete-active":*/
x[currentFocus].classList.add("autocomplete-active");
}
function removeActive(x) {
/*a function to remove the "active" class from all autocomplete items:*/
for (var i = 0; i < x.length; i++) {
x[i].classList.remove("autocomplete-active");
}
}
function closeAllLists(elmnt) {
/*close all autocomplete lists in the document,
except the one passed as an argument:*/
var x = document.getElementsByClassName("autocomplete-items");
for (var i = 0; i < x.length; i++) {
if (elmnt != x[i] && elmnt != inp) {
x[i].parentNode.removeChild(x[i]);
}
}
}
/*execute a function when someone clicks in the document:*/
document.addEventListener("click", function (e) {
closeAllLists(e.target);
});
}
autocompleteInputBox(document.getElementById("myInput"));
</script>
</body>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With