From e57443354958d063cb088304d93879ae8814fe00 Mon Sep 17 00:00:00 2001 From: Alexandre Stanislawski Date: Wed, 15 Jun 2016 11:05:31 +0200 Subject: [PATCH] feat(instantsearch): Provide an instantsearch.js widget for places --- docs/config.rb | 9 ++++ docs/source/documentation.html.md.erb | 45 +++++++++++++++++++ docs/source/examples.html.md.erb | 8 ++++ .../partials/examples/_instantsearch.html.erb | 41 +++++++++++++++++ instantsearchWidget.js | 2 + scripts/build.sh | 4 +- src/instantsearch/widget.js | 44 ++++++++++++++++++ webpack.config.babel.js | 3 +- 8 files changed, 153 insertions(+), 3 deletions(-) create mode 100644 docs/source/partials/examples/_instantsearch.html.erb create mode 100644 instantsearchWidget.js create mode 100644 src/instantsearch/widget.js diff --git a/docs/config.rb b/docs/config.rb index 2dc6f2011..e202f8ab3 100644 --- a/docs/config.rb +++ b/docs/config.rb @@ -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', @@ -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) @@ -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://github.com/middleman/middleman-minify-html activate :minify_html diff --git a/docs/source/documentation.html.md.erb b/docs/source/documentation.html.md.erb index 7690a4e3c..8fb930091 100644 --- a/docs/source/documentation.html.md.erb +++ b/docs/source/documentation.html.md.erb @@ -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: + + + + + + + + + + + + + + +
OptionDescription
+
defaultPosition
+ +Type: **number[]** + +
+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. +
+ ### REST API Behind the places.js the JavaScript library lies a complete REST API. Read the underlying [REST API documentation](rest.html). diff --git a/docs/source/examples.html.md.erb b/docs/source/examples.html.md.erb index 19e07ba51..cca31e774 100644 --- a/docs/source/examples.html.md.erb +++ b/docs/source/examples.html.md.erb @@ -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://github.com/algolia/autocomplete.js) library, you can search in your own data along with showing Algolia Places results. diff --git a/docs/source/partials/examples/_instantsearch.html.erb b/docs/source/partials/examples/_instantsearch.html.erb new file mode 100644 index 000000000..5b257ed55 --- /dev/null +++ b/docs/source/partials/examples/_instantsearch.html.erb @@ -0,0 +1,41 @@ + +
+ + + +<%= 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] %> + diff --git a/instantsearchWidget.js b/instantsearchWidget.js new file mode 100644 index 000000000..cbfec4f57 --- /dev/null +++ b/instantsearchWidget.js @@ -0,0 +1,2 @@ +import widget from './src/instantsearch/widget.js'; +module.exports = widget; diff --git a/scripts/build.sh b/scripts/build.sh index 6d23f2577..a85df3784 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -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" @@ -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 diff --git a/src/instantsearch/widget.js b/src/instantsearch/widget.js new file mode 100644 index 000000000..343a4f02d --- /dev/null +++ b/src/instantsearch/widget.js @@ -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); +} diff --git a/webpack.config.babel.js b/webpack.config.babel.js index 01203dc43..f55d6722e 100644 --- a/webpack.config.babel.js +++ b/webpack.config.babel.js @@ -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: {