Create a Search Experience
Goal: This guide will show you how to add a search input field to your map application, allowing users to find locations within your venue. Search results will be displayed in a list and highlighted on the map.
SDK Concepts Introduced:
Using
mapsindoors.services.LocationsService.getLocations()to fetch locations based on a query.Interacting with the map based on search results:
Highlighting multiple locations:
mapsIndoorsInstance.highlight().Setting the floor:
mapsIndoorsInstance.setFloor().Selecting a specific location:
mapsIndoorsInstance.selectLocation().
Clearing previous highlights and selections:
mapsIndoorsInstance.highlight()(with no arguments) andmapsIndoorsInstance.deselectLocation().Getting current venue information:
mapsIndoorsInstance.getVenue().
Prerequisites
Completion of Step 1: Displaying a Map with Mapbox GL JS.
Your MapsIndoors API Key and Mapbox Access Token should be correctly set up as per Step 1. We will continue using the demo API key
02c329e6777d431a88480a09and venue IDdfea941bb3694e728df92d3dfor this example.
The Code
This guide details the modifications to HTML, CSS, and JavaScript needed to add a search input field, display search results, and dynamically interact with the map based on user searches.
Update index.html
Open your index.html file. The primary structural change to your HTML is the introduction of a dedicated search panel. This panel will house the input field where users type their search queries and an unordered list where the corresponding search results will appear.
Explanation of index.html updates:
A new
divelement with the classpanelis added. Thisdivserves as the main container for all search-related UI elements.Inside the
panel, anotherdivwith the idsearch-uiand the classflex-columnis introduced to arrange the search input and results list vertically.An
<input>element withid="search-input"is the text field for user search queries.An
<ul>(unordered list) element withid="search-results"will be dynamically populated with locations matching the user's query.
Update style.css
Modify your style.css file to incorporate styles for the newly added search panel and its contents. These styles are crucial for ensuring the search interface is user-friendly, visually appealing, and correctly positioned over the map without obstructing it entirely.
Explanation of style.css updates:
.panel: Styles the search panel to float over the map in the top-left corner, with a white background, padding, rounded corners, and a shadow for a modern look.max-heightandoverflow-y: autoensure it's scrollable if results are numerous..flex-column: A utility class using Flexbox to stack child elements (search input, results list) vertically with a small gap..hidden: A utility class to hide elements (display: none;), used initially for the search results list.#search-input: Styles the search input field with padding, border, and font size for readability.#search-results: Styles the unordered list for search results, removing default list styling.#search-results li: Styles individual list items with padding, a bottom border for separation, and a pointer cursor to indicate clickability.#search-results li:last-child: Removes the bottom border from the last list item.#search-results li:hover: Provides a hover effect for list items for better user feedback.
Update script.js
The script.js file sees the most significant changes as it houses the logic for the search functionality.
Explanation of script.js updates:
DOM Element References:
searchInputElementandsearchResultsElementget references to the HTML input field and the unordered list for displaying results, respectively.Initial State: The
searchResultsElementis hidden by default using the.hiddenCSS class.Event Listener: An
inputevent listener is attached tosearchInputElement. This calls theonSearchfunction each time the user types into the search field.onSearch()Function: This is the core of the search logic:It retrieves the current
queryfrom the input field and gets thecurrentVenueusingmapsIndoorsInstance.getVenue(). For more details on venue information, see thegetVenue()reference.It clears any existing highlights from the map using
mapsIndoorsInstance.highlight()(called without arguments). See its API documentation for more on clearing highlights.It deselects any currently selected location using
mapsIndoorsInstance.deselectLocation()(called without arguments). Refer to its API documentation for deselection behavior.If the
querylength is less than 3 characters, it hides thesearchResultsElementand exits to prevent overly broad or empty searches.It prepares
searchParameterswith theq(query) and scopes the search to thecurrentVenue.name. For a comprehensive list of search options, check out the LocationsService.getLocations() documentationIt calls
mapsindoors.services.LocationsService.getLocations(searchParameters)to fetch locations. This asynchronous method returns a Promise..then(locations => { ... }): This block handles the successful response from the LocationsService.locationsis an array of objects, where each object conforms to the Location interface.It clears previous search results by setting
searchResultsElement.innerHTML = null.If no
locationsare found, it displays a "No results found" message in the list.Otherwise, it iterates through each
locationobject:Creates an
<li>element.Sets its
innerHTMLtolocation.properties.name. Thepropertiesobject on an object conforming to theLocationinterface contains various details about the location. For more information, see the Location documentation.Stores
location.idinlistElement.dataset.locationIdfor potential future use.Adds a
clickevent listener to the list item. When clicked:mapsIndoorsInstance.goTo(location): Pans and zooms the map to the clicked location. For more details ongoTo(), see its reference.mapsIndoorsInstance.setFloor(location.properties.floor): Changes the map to the location's floor. To understand floor management, check thesetFloor()documentation.mapsIndoorsInstance.selectLocation(location): Selects and highlights this specific location on the map. For further information, refer to theselectLocation()API documentation.
Appends the new list item to
searchResultsElement.Collects all
location.ids intolocationIdsToHighlight.
Makes the
searchResultsElementvisible by removing the.hiddenclass.Calls
mapsIndoorsInstance.highlight(locationIdsToHighlight)to highlight all found locations on the map simultaneously. Thehighlight()method accepts an array of location IDs. See its API documentation for details on batch highlighting.
.catch(error => { ... }): Handles potential errors during the search request, logging them to the console and displaying an error message in the list.
The
handleLocationClickfunction is now used for both map clicks and search result clicks, ensuring consistent behavior and code reuse.When a user clicks a search result or a POI on the map, the map will center on that location, switch to the correct floor, and select the location.
This pattern will be reused and expanded in later steps.
Expected Outcome
After implementing these changes:
A search panel will be visible in the top-left corner of your map.
Typing 3 or more characters into the search input will trigger a search.
Matching locations will appear as a clickable list below the search input.
All matching locations will be highlighted on the map.
Clicking a location in the list will:
Pan and zoom the map to that location.
Switch to the correct floor if necessary.
Select and distinctively highlight that specific location on the map.
Troubleshooting
Search not working / No results:
Check the browser's developer console (F12) for errors.
Ensure your MapsIndoors API Key (
02c329e6777d431a88480a09for demo) is correct and the MapsIndoors SDK is loaded.Verify
YOUR_MAPBOX_ACCESS_TOKENis correct.Confirm the
venueID (dfea941bb3694e728df92d3dfor demo) is valid and the venue has searchable locations.Make sure the
onSearchfunction is being called (e.g., add aconsole.logat the beginning ofonSearch).
Results list doesn't appear or looks wrong:
Check CSS for the
.panel,#search-results, andlielements. Ensure the.hiddenclass is being correctly added/removed.
Map interactions (goTo, highlight, selectLocation) not working:
Verify
mapsIndoorsInstanceis correctly initialized.Ensure the
locationobjects passed to these methods are valid objects conforming to theLocationinterface.Check for console errors when clicking a search result.
Next Steps
You've now successfully added a powerful search feature to your indoor map! Users can easily find their way to specific points of interest.
Next, learn how to display detailed information about a selected location:
Step 3: Show the Details
Last updated
Was this helpful?