Algolia Places is closing. We can help.

Algolia InstantSearch demo

Introduction #

A full Algolia InstantSearch demo. This example searches 1000 UK pubs (a separate Algolia index) and can be filtered by location and further refined by distance.

View live on CodePen

HTML #

            
<html>

    <head>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@algolia/autocomplete-theme-classic"/>
    </head>
            
    <body>

        <div id="searchbox"></div>
        <div id="placesapi-autocomplete"></div>

        <div class="aa-Autocomplete">
            <div class="aa-Form">
                <div class="aa-InputWrapper">
                    <select id="radius" class="aa-Input" style="padding-left: 20px">
                        <option value="">Any radius</option>
                        <option value="5">5 miles</option>
                        <option value="10">10 miles</option>
                        <option value="15">15 miles</option>
                        <option value="20">20 miles</option>
                        <option value="25">25 miles</option>
                        <option value="30">30 miles</option>
                        <option value="35">35 miles</option>
                        <option value="40">40 miles</option>
                        <option value="45">45 miles</option>
                        <option value="50">50 miles</option>
                    </select>
                </div>
            </div>
        </div>

        <div id="stats"></div>
        <div id="hits"></div>

        <script src="https://cdn.jsdelivr.net/algoliasearch/3/algoliasearch.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/instantsearch.js@4.8.3/dist/instantsearch.production.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/@algolia/autocomplete-js"></script>
        <script src="/assets/js/app.js"></script>

    </body>
</html>
            
        

CSS #

            
body {
    background: black;
    color: white;
    padding-top: 60px;
}

p {
    margin: 0;
}

.algolia-autocomplete {
    width: 100%;
}

.algolia-autocomplete .aa-input,
.algolia-autocomplete .aa-hint {
    width: 100%;
}

.algolia-autocomplete .aa-hint {
    color: #999;
}

.algolia-autocomplete .aa-dropdown-menu {
    width: 100%;
    background-color: #fff;
    border: 1px solid #999;
    border-top: none;
}

.algolia-autocomplete .aa-dropdown-menu .aa-suggestion {
    cursor: pointer;
    padding: 5px 4px;
}

.algolia-autocomplete .aa-dropdown-menu .aa-suggestion.aa-cursor {
    background-color: #b2d7ff;
}

.algolia-autocomplete .aa-dropdown-menu .aa-suggestion em {
    font-weight: bold;
    font-style: normal;
}

.ais-SearchBox-form {
    font-size: 16px;
    height: 4.3rem;
    border-radius: 3px;
    margin-bottom: 20px;
}

.ais-SearchBox-form:before {
    background: none;
}

.ais-SearchBox-input {
    padding-left: 4.5rem;
}

.ais-SearchBox-input::placeholder {
    color: #a4a1bc;
}

#searchbox {
    margin-top: 30px;
}

#stats {
    color: #137fa2;
    font-weight: bold;
}

#stats,
#hits {
    margin-top: 30px;
}

.ais-Hits-item,
.ais-InfiniteHits-item {
    font-size: 14px;
    background: none;
    padding: 0 0 25px 0;
}

.ais-Hits-item p {
    padding-bottom: 7px;
}
            
        

JavaScript #

            
const { autocomplete, getAlgoliaResults } = window["@algolia/autocomplete-js"];

var searchClient = algoliasearch(
    "YOUR_ALGOLIA_APP_ID_HERE",
    "YOUR_ALGOLIA_API_KEY_HERE"
);

const instantSearchIndex = "YOUR_ALGOLIA_INDEX_HERE";

const search = instantsearch({
    searchClient,
    routing: true,
    indexName: instantSearchIndex,
});

search.addWidgets([
    instantsearch.widgets.configure({
        hitsPerPage: 15,
        getRankingInfo: true,
    }),
    instantsearch.widgets.stats({
        container: "#stats",
    }),
        instantsearch.widgets.searchBox({
        container: "#searchbox",
        placeholder: "Search for UK pubs...",
    }),
    instantsearch.widgets.hits({
        container: "#hits",
        templates: {
            item: function (hit) {
                var distance = "";
                if (hit._rankingInfo.geoDistance) {
                    var d = hit._rankingInfo.geoDistance * 0.000621371; // Metres to miles
                    d = d.toFixed(2);
                    var distance = "<p style='color:#137fa2;'>" + d + " miles</p>";
                }
                return `<div>
                            ${distance}
                            <p><strong>${hit.name}</strong></p>
                            <p>${hit.address}</p>
                            <p>${hit.town}, ${hit.postcode}</p>
                        </div>`;
            },
        },
    }),
]);

search.start();

var r = document.querySelector("#radius");
r.onchange = function (e) {
    var radius = this.value;
    if (radius != "") {
        radius = radius * 1609.34; // Miles to metres
        radius = radius.toFixed(0);
    }
    search.helper.setQueryParameter("aroundRadius", radius).search();
};

var searchClient = algoliasearch(
    "DM340JGS49",
    "YOUR_PLACESAPI_KEY_HERE"
);

autocomplete({
    container: "#placesapi-autocomplete",
    detachedMediaQuery: "none",
    placeholder: "Search for places...",
    onReset() {
        search.helper.setQueryParameter("aroundLatLng", "").search();
    },
    onStateChange({ prevState, state }) {
        if (state.query.length == 0) {
            search.helper.setQueryParameter("aroundLatLng", "").search();
        }
    },
    getSources() {
        return [{
            sourceId: "places",
            getItems({ query }) {
                return getAlgoliaResults({
                    searchClient,
                    queries: [
                        {
                            indexName: "places",
                            query,
                        },
                    ],
                });
            },
            templates: {
                item({ item }) {
                    return `${item.name}, ${item.county}, ${item.country}`;
                },
            },
            onSelect: function (event) {
                let latLng = parseFloat(event.item.latitude) + "," + parseFloat(event.item.longitude);
                search.helper.setQueryParameter("aroundLatLng", latLng).search();
                event.setQuery(event.item.name + ", " + event.item.county + ", " + event.item.country);
            },
        }];
    },
});