Skip to content
This repository has been archived by the owner on Feb 2, 2023. It is now read-only.

Commit

Permalink
feat(instantsearch): Provide an instantsearch.js widget for places
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexandre Stanislawski committed Jun 15, 2016
1 parent a9c68d4 commit e574433
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 3 deletions.
9 changes: 9 additions & 0 deletions docs/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
activate :livereload
config[:places_lib_url] = 'places'
config[:places_autocomplete_dataset_lib_url] = 'placesAutocompleteDataset'
config[:places_instantsearch_widget_lib_url] = 'placesInstantsearchWidget'
config[:instantsearch_lib_url] = 'https://cdn.jsdelivr.net/instantsearch.js/1.6.0/instantsearch.min.js'
config[:instantsearch_googlemaps_lib_url] = 'https://cdn.jsdelivr.net/instantsearch-googlemaps/1.2.4/instantsearch-googlemaps.min.js'
config[:google_maps_lib_url] = 'https://maps.googleapis.com/maps/api/js'
activate :external_pipeline,
name: 'places',
command: 'npm run js:watch -- --output-path docs/.webpack/js',
Expand Down Expand Up @@ -60,6 +64,7 @@
config[:places_lib_version] = ENV['VERSION']
config[:places_cdn_url] = 'https://cdn.jsdelivr.net/places.js/0/places.min.js'
config[:places_autocomplete_dataset_cdn_url] = 'https://cdn.jsdelivr.net/places.js/0/placesAutocompleteDataset.min.js'
config[:places_instantsearch_widget_cdn_url] = 'https://cdn.jsdelivr.net/places.js/0/placesInstantsearchWidget.min.js'

helpers do
def nav_active(path)
Expand All @@ -71,6 +76,10 @@ def nav_active(path)
configure :build do
config[:places_lib_url] = config[:places_cdn_url]
config[:places_autocomplete_dataset_lib_url] = config[:places_autocomplete_dataset_cdn_url]
config[:places_instantsearch_widget_lib_url] = config[:places_instantsearch_widget_cdn_url]
config[:instantsearch_lib_url] = 'https://cdn.jsdelivr.net/instantsearch.js/1.6.0/instantsearch.min.js'
config[:instantsearch_googlemaps_lib_url] = 'https://cdn.jsdelivr.net/instantsearch-googlemaps/1.2.4/instantsearch-googlemaps.min.js'
config[:google_maps_lib_url] = 'https://maps.googleapis.com/maps/api/js'
# this may trigger bad behavior, if so, see
# https:/middleman/middleman-minify-html
activate :minify_html
Expand Down
45 changes: 45 additions & 0 deletions docs/source/documentation.html.md.erb
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,51 @@ All the places.js [options](#options) are available and can be passed to the `pl

You will need an [Algolia account](https://www.algolia.com/) to be able to search into your own data. See the [autocomplete.js dataset example](examples.html#custom-data).

### instantsearch.js

If you're already using instantsearch.js, you can use Algolia Places out of the box. This
widget will do a search of places using Algolia Places and when an adress is selected, it
will update the geolocation point of the instantsearch.js search.

You can include it using a link tag:

```html
<%= javascript_include_tag config[:places_instantsearch_widget_cdn_url] %>
```

The widget is exported as `placesInstantsearchWidget` in the window. It is also available with
npm using:

```js
import widget from 'places.js/placesInstantsearchWidget';
```

The widget accept the same [options as places.js](#options). Because it is an instantsearch.js that
will have an impact on the instantsearch search, it contains other options:


<!-- Indentation is on purpose for <td>s, to allow HTML inside markdown -->
<table class="api">
<thead><tr>
<th>Option</th>
<th>Description</th>
</tr></thead>
<tbody>
<tr>
<td markdown="1">
<div class="api-entry" id="api-options-instantsearch-default-position"><code>defaultPosition</code></div>

Type: **number[]**

</td>
<td markdown="1">
Sets the default position around which the instantsearch search is done, when no element is selected in the places widget.
This position is an array of two numbers, representing the lattitude and the longitude.
</td>
</tr>
</tbody>
</table>

### REST API

Behind the places.js the JavaScript library lies a complete REST API. Read the underlying [REST API documentation](rest.html).
Expand Down
8 changes: 8 additions & 0 deletions docs/source/examples.html.md.erb
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@ Templates are functions called with a [suggestion object](./documentation.html#s
<%= partial '/partials/examples/templates' %>
```

### Instantsearch.js

<%= partial '/partials/examples/instantsearch' %>

```html
<%= partial '/partials/examples/instantsearch' %>
```

### Custom data

Using [Algolia's autocomplete.js](https:/algolia/autocomplete.js) library, you can search in your own data along with showing Algolia Places results.
Expand Down
41 changes: 41 additions & 0 deletions docs/source/partials/examples/_instantsearch.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<input type="search" id="input-map-instantsearch" class="form-control" placeholder="Where are you looking for a coffee?" />
<div id="map-instantsearch-container"></div>

<style>
#map-instantsearch-container {height: 300px};
</style>

<%= javascript_include_tag config[:instantsearch_lib_url] %>
<%= javascript_include_tag config[:places_instantsearch_widget_lib_url] %>
<%= javascript_include_tag config[:instantsearch_googlemaps_lib_url] %>
<%= javascript_include_tag config[:google_maps_lib_url] %>
<script>
(function() {
var search = instantsearch({
appId: 'latency',
apiKey: 'ffc36feb6e9df06e1c3c4549b5af2b31',
indexName: 'starbucks',
searchParameters: {
hitsPerPage: 50
}
});

var searchBox = placesInstantsearchWidget({
container: document.querySelector('#input-map-instantsearch')
});

var map = instantsearchGoogleMaps({
container: document.querySelector('#map-instantsearch-container'),
prepareMarkerData: ({Brand, Name, 'Street Combined': street}) => {
return {
title: `${Brand} - ${Name}`
};
},
refineOnMapInteraction: true
});

search.addWidget(searchBox);
search.addWidget(map);
search.start();
})();
</script>
2 changes: 2 additions & 0 deletions instantsearchWidget.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import widget from './src/instantsearch/widget.js';
module.exports = widget;
4 changes: 2 additions & 2 deletions scripts/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set -e # exit when error, no verbose

printf "\nBuilding places.js library\n"

BUNDLES=( 'places' 'placesAutocompleteDataset' )
BUNDLES=( 'places' 'placesAutocompleteDataset' 'placesInstantsearchWidget' )
LICENSE="/*! ${NAME} ${VERSION:-UNRELEASED} | © Algolia | github.com/algolia/places */"
DIST_DIR="dist/cdn"

Expand All @@ -29,6 +29,6 @@ do
-m \
-o "${dist_file_min}"

gzip_size=$(gzip -9 < $dist_file_min | wc -c | pretty-bytes)
gzip_size=$(gzip -9 < "$dist_file_min" | wc -c | pretty-bytes)
echo "=> $dist_file_min gzipped will weight $gzip_size"
done
44 changes: 44 additions & 0 deletions src/instantsearch/widget.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import places from '../places.js';

/**
* The underlying structure for the Algolia Places instantsearch widget.
*/
class AlgoliaPlacesWidget {
constructor({
defaultPosition = [0, 0],
...placesOptions
}) {
this.defaultPosition = defaultPosition.join(',');
this.placesOptions = placesOptions;
}
init({helper}) {
const placesAutocomplete = places(this.placesOptions);

helper.setQueryParameter('aroundLatLng', this.defaultPosition);

placesAutocomplete.on('change', (opts) => {
const {suggestion: {latlng: {lat, lng}}} = opts;
helper.setQueryParameter('aroundLatLng', `${lat},${lng}`)
.search();
});

placesAutocomplete.on('clear', () => {
helper.setQueryParameter('aroundLatLng', this.defaultPosition)
.search();
});
}
}

/**
* Creates a new instance of the Algolia Places widget. This widget
* sets the geolocation value for the search based on the seelected
* result in the Algolia Places autocomplete. If the input is cleared,
* the position is result to the default position.
* @function
* @param {object} opts configuration object
* @param {number[]} opts.defaultPosition=[0,0] default position as an array of the form [lat, lng]
* @returns {Widget} the algolia places widget
*/
export default function makeAlgoliaPlacesWidget(opts) {
return new AlgoliaPlacesWidget(opts);
}
3 changes: 2 additions & 1 deletion webpack.config.babel.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import {join} from 'path';
export default {
entry: {
places: './index.js',
placesAutocompleteDataset: './autocompleteDataset.js'
placesAutocompleteDataset: './autocompleteDataset.js',
placesInstantsearchWidget: './instantsearchWidget.js'
},
devtool: 'source-map',
output: {
Expand Down

0 comments on commit e574433

Please sign in to comment.