Skip to content

placekit/autocomplete-js

Repository files navigation

PlaceKit Autocomplete JS Library

All-in-one address autocomplete experience for your web apps

NPM LICENSE

Quick startFeaturesReferenceCustomizeAdditional notesLicenseExamples


PlaceKit Autocomplete JavaScript Library is a standalone address autocomplete field for your application, built on top of our PlaceKit JS client. Under the hood it relies on Popper to position the suggestions list, and on Flagpedia to display flags on country results.

If you already use a components library with an autocomplete field, or need a more advanced usage, please refer to our PlaceKit JS client reference.

Framework specific implementations:

✨ Features

  • Standalone and lightweight: about 14kb of JS, and 5kb of CSS, gzipped
  • Cross browser: compatible across all major modern browsers
  • Non-invasive: use and style your own input element
  • Customizable and extensible with events and hooks
  • TypeScript compatible
  • W3C WAI compliant

🎯 Quick start

CDN

First, import the library and the default stylesheet into the <head> tag in your HTML:

<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/@placekit/autocomplete-js@latest/dist/placekit-autocomplete.min.css"
/>
<script src="https://cdn.jsdelivr.net/npm/@placekit/autocomplete-js@latest"></script>

After importing the library, placekitAutocomplete becomes available as a global:

<input type="search" placeholder="Search place..." class="pka-input" id="placekit" />
<script>
  const pka = placekitAutocomplete('<your-public-api-key>', {
    target: '#placekit',
    // other options...
  });
</script>

Or if you are using native ES Modules:

<script type="module">
  import placekitAutocomplete from 'https://cdn.jsdelivr.net/npm/@placekit/autocomplete-js@latest/dist/placekit-autocomplete.esm.mjs';
  const pka = placekitAutocomplete(/* ... */);
  // ...
</script>

NOTE: Make sure to call placekitAutocomplete after the DOM is loaded so the input can be found.

NPM

First, install PlaceKit Autocomplete using npm package manager:

npm install --save @placekit/autocomplete-js

Then import the package and perform your first address search:

// CommonJS syntax:
const placekitAutocomplete = require('@placekit/autocomplete-js');

// ES6 Modules syntax:
import placekit from '@placekit/autocomplete-js';

const pka = placekitAutocomplete('<your-public-api-key>', {
  target: '#placekit',
  // other options...
});

Don't forget to import @placekit/autocomplete-js/dist/placekit-autocomplete.css if you want to use our default style. If you have trouble importing CSS from node_modules, copy/paste its content into your own CSS.

👉 Check out our examples for different use cases!

🧰 Reference

placekitAutocomplete()

PlaceKit Autocomplete initialization function returns a PlaceKit Autocomplete client, named pka in all snippets below.

const pka = placekitAutocomplete('<your-public-api-key>', {
  target: '#placekit',
  countries: ['fr'],
  maxResults: 10,
});
Parameter Type Description
apiKey string API key
options key-value mapping (optional) Global parameters (see options)

⚠️ target must be set when instanciating placekitAutocomplete, all other options can be set later with pka.configure().

pka.input

Input field element passed as target option, read-only.

console.log(pka.input); // <input ... />

pka.options

Options from both PlaceKit Autocomplete and PlaceKit JS client, read-only.

console.log(pka.options); // { "target": <input ... />, "language": "en", "maxResults": 10, ... }
Option From Type Default Description
target AutoComplete string|Element - Target input element or (unique) selector.
panel AutoComplete object? (...) Suggestions panel options, see Panel options.
format AutoComplete object? (...) Formatting options, see Format options.
countryAutoFill AutoComplete boolean? true Automatically detect current country by IP and fill input when types: ['country'].
countrySelect AutoComplete boolean? true Show/hide country selector(1)(2).
maxResults JS client integer 5 Number of results per page.
language JS client string? undefined Preferred language for the results(3), two-letter ISO language code. Supported languages are en and fr. By default the results are displayed in their country's language.
types JS client string[]? undefined Type of results to show. Array of accepted values: street, city, country, administrative, county, airport, bus, train, townhall, tourism. Prepend - to omit a type like ['-bus']. Unset to return all.
countries JS client string[]? undefined Restrict search in specific countries. Array of two-letter ISO country codes(3).
coordinates JS client string? undefined Coordinates to search around. Automatically set when calling pka.requestGeolocation().
  • [1]: Ignored if countries option is set (Country selector is hidden).
  • [2]: When types: ['city'] is set, setting countrySelect: false enables a worldwide city search.
  • [3]: See Coverage for more details.

Panel options

Option Type Default Description
className string undefined Additional panel CSS class(es).
offset integer 4 Gap between input and panel in pixels.
strategy 'absolute' | 'fixed' absolute Popper positioning strategy
flip boolean false Flip position top when overflowing.

Format options

Option Type Default Description
flag (countrycode: string) => string see placekit-autocomplete.js DOM for flags.
icon (name: string, label: string) => string see placekit-autocomplete.js DOM for icons.
sub (item: object) => string see placekit-autocomplete.js Format suggestion secondary text
noResults (query: string) => string see placekit-autocomplete.js Format "no results" text.
value (item: object) => string item.name Format input value when user picks a suggestion.
applySuggestion string "Apply suggestion" ARIA label for "insert" icon.
suggestions string "Address suggestions" ARIA label for role="listbox" suggestions list.
changeCountry string "Change country" ARIA label for entering country selection mode.
cancel string "Cancel" Label for cancelling country selection mode.

pka.configure()

Updates all parameters (except target). Returns the instance so you can chain methods.

pka.configure({
  panel: {
    className: 'my-suggestions',
    flip: true,
  },
  format: {
    value: (item) => `${item.name} ${item.city}`,
  },
  language: 'fr',
  maxResults: 5,
});
Parameter Type Description
opts key-value mapping (optional) Global parameters (see options)

pka.state

Read-only object of input state.

console.log(pka.state); // {dirty: false, empty: false, freeForm: true, geolocation: false}

// `true` after the user modifies the input value.
console.log(pka.state.dirty); // true or false

// `true` whenever the input value is not empty.
console.log(pka.state.empty); // true or false

// `true` if the input has a free form value or `false` if value is selected from the suggestions.
console.log(pka.state.freeForm); // true or false

// `true` if device geolocation has been granted.
console.log(pka.state.geolocation); // true or false

// `true` if panel is in country selection mode.
console.log(pka.state.countryMode); // true or false

The freeForm value comes handy if you need to implement a strict validation of the address, but we don't interfere with how to implement it as input validation is always very specific to the project's stack.

pka.on()

Register event handlers, methods can be chained.

pka.on('open', () => {})
  .on('close', () => {})
  .on('results', (query, results) => {})
  .on('pick', (value, item, index) => {})
  .on('error', (error) => {})
  .on('dirty', (bool) => {})
  .on('empty', (bool) => {})
  .on('freeForm', (bool) => {})
  .on('geolocation', (bool, position, error) => {});
  .on('countryMode', (bool) => {});
  .on('state', (state) => {})
  .on('countryChange', (item) => {});

If you register a same event twice, the first one will be replaced. So, to remove an handler, simply assign undefined:

pka.on('open'); // clears handler for 'open' event

Events

open

Triggered when panel opens.

close

Triggered when panel closes.

results

Triggered when suggestions list gets updated, same as when the user types or enables geolocation.

Parameter Type Description
query string Input value.
results object[] Results returned from API.
pick

Triggered when user selects an item from the suggestion list by clicking on it or pressing ENTER after using the keyboard navigation.

Parameter Type Description
value string Input value (value returned by options.formatValue()).
item object All item details returned from API.
index number Position of the selected item in the suggestions list, zero-based.
error

Triggered on server error.

Parameter Type Description
error object Error details.
dirty

Triggered when the input value changes.

Parameter Type Description
dirty boolean true after the user modifies the value.
empty

Triggered when input value changes.

Parameter Type Description
empty boolean true if input is empty.
freeForm

Triggered when input value changes.

Parameter Type Description
freeForm boolean true on user input, false on pick event.
geolocation

Triggered when state.geolocation value changes (a.k.a. when pka.requestGeolocation is called).

Parameter Type Description
geolocation boolean true if granted, false if denied.
position GeolocationPosition | undefined Passed when geolocation is true.
error string | undefined Geolocation request error message.
countryMode

Triggered when the user toggles the country selection mode. Always false if countries option is set, or if countrySelect is false.

Parameter Type Description
bool boolean true if open, false if closed.
state

Triggered when one of the input states changes.

Parameter Type Description
state object The current input state.
countryChange

Triggered when the current search country changes (either detected by IP, or selected by the user in the country selection mode).

Parameter Type Description
item object Country details returned from API.

pka.handlers

Reads registered event handlers, read-only.

pka.on('open', () => {});
console.log(pka.handlers); // { open: ... }

pka.requestGeolocation()

Requests device's geolocation (browser-only). Returns a Promise with a GeolocationPosition object.

pka.requestGeolocation({ timeout: 10000 }).then((pos) => console.log(pos.coords));
Parameter Type Description
opts key-value mapping (optional) navigator.geolocation.getCurrentPosition options
cancelUpdate boolean (optional) If false (default), suggestions list updates immediately based on device location.

The location will be store in the coordinates global options, you can still manually override it. state.geolocation will be set to true, dispatching both the geolocation and state events.

pka.clearGeolocation()

Clear device's geolocation stored with pka.requestGeolocation.

pka.clearGeolocation();

The global option coordinates will be deleted and the state.geolocation will be set to false, dispatching both the geolocation and state events.

pka.open()

Opens the suggestion panel.

pka.open();

pka.close()

Closes the suggestion panel.

pka.close();

pka.clear()

Clears the input value, focus the field, closes the suggestion panel and clear suggestions if state.geolocation is false or perform an empty search to reset geolocated suggestions otherwise.

pka.clear();

pka.setValue()

Manually set the input value. Useful for third-party wrappers like React.

| Parameter | Type | Description | | --- | --- | --- | --- | | value | string | null (optional) | New input value, operation ignored if undefined or null. | | notify | boolean (optional) | Pass true to dispatch change and input events and update state (default false). |

pka.setValue('new value');
pka.setValue('new value', true); // dispatch `change` and `input` event

NOTE: state.empty will automatically be updated based on the input value if notify: true. state.dirty and state.freeForm remain unchanged until the user focuses the input.

pka.destroy()

Removes the suggestions panel from the DOM and clears all event handlers from window and input that were added by PlaceKit Autocomplete.

pka.destroy();

💅 Customize

You have full control over the input element as PlaceKit Autocomplete doesn't style nor alter it by default. We still provide a style that you can apply by adding the .pka-input class to your input element.

Dark mode

THe whole autocomplete automatically switches to dark mode if <body> has a .dark class or a data-theme="dark" attribute.

You can also activate the dark mode on-demand by wrapping the input with a .dark class or a data-theme="dark" attribute, like <div class="pka-input dark">...</div>. The suggestions panel is appended to the body directly and doesn't share any ancestor with the input field other than <body>, so to activate the dark mode on-demand, pass the .dark class to the panel options:

const pka = placekitAutocomplete('<your-public-api-key>', {
  target: '#placekit',
  panel: {
    className: 'dark',
  },
});

CSS Variables

Colors, border-radius, font and overall scale (in rem) and even icons are accessible over variables:

:root {
  --pka-scale: 1rem;
  --pka-color-accent: 1, 73, 200;
  --pka-color-black: 29, 41, 57;
  --pka-color-darker: 52, 64, 84;
  --pka-color-dark: 152, 162, 179;
  --pka-color-light: 207, 213, 221;
  --pka-color-lighter: 243, 244, 246;
  --pka-color-white: 255, 255, 255;
  --pka-border-radius: 6px;
  --pka-font-family: system-ui, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif,
    'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
  --pka-z-index: 9999;

  --pka-icon-pin: url('...');
  --pka-icon-street: var(--pka-icon-pin);
  --pka-icon-administrative: var(--pka-icon-pin);
  --pka-icon-county: var(--pka-icon-pin);
  --pka-icon-city: url('...');
  --pka-icon-airport: url('...');
  --pka-icon-bus: url('...');
  --pka-icon-train: url('...');
  --pka-icon-townhall: url('...');
  --pka-icon-tourism: url('...');
  --pka-icon-noresults: url('...');
  --pka-icon-clear: url('...');
  --pka-icon-cancel: var(--pka-icon-clear);
  --pka-icon-insert: url('...');
  --pka-icon-check: url('...');
  --pka-icon-switch: url('...');
  --pka-icon-geo-off: url('...');
  --pka-icon-geo-on: url('...');
  --pka-icon-loading: url('...');
}

/* dark mode overrides */
.dark,
[data-theme='dark'] {
  --pka-color-accent: 55, 131, 249;
}

You also have full control over flags and icons DOM with format.flag and format.icon options (see Format options).

For advanced customization, refer to our stylesheet to learn about the available classes if you need to either override some or start a theme from scratch.

⚠️ Additional notes

  • Setting a non-empty value attribute on the <input> will automatically trigger a first search request when the user focuses the input.

⚖️ License

PlaceKit Autocomplete JS Library is an open-sourced software licensed under the MIT license.

⚠️ NOTE: you are not allowed to hide the PlaceKit logo unless we've delivered a special authorization. To request one, please contact us using our contact form.