Skip to content

Commit

Permalink
Merge pull request #9 from afosto/Feature/instant-search-settings
Browse files Browse the repository at this point in the history
Feature/instant-search-settings
  • Loading branch information
Rapid0o authored Mar 8, 2022
2 parents e12f8eb + 12d00b7 commit 575426e
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 87 deletions.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,29 @@ search.start();

For more information check the InstantSearch.js [documentation](https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/js/).

### Basic with settings

```js
const client = afostoInstantSearch('my-search-engine-key');

async function initSearch() {
const settings = await client.getSettings();
const [firstIndex] = settings.indexes || [];

const search = instantsearch({
indexName: firstIndex,
searchClient: client,
});

// Do something with the settings.
// For example render filters dynamically.

search.start();
}

initSearch();
```

### React

You can use the initialized Afosto client with the [React InstantSearch](https://github.com/algolia/react-instantsearch) library.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@afosto/instant-search-client",
"version": "1.0.1",
"version": "1.0.2",
"private": false,
"description": "The Afosto InstantSearch client",
"main": "./dist/afosto-instant-search.min.js",
Expand Down
168 changes: 83 additions & 85 deletions playground/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,20 @@
<head>
<meta charset="UTF-8">
<title>Test</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/algolia-min.css"
/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/algolia-min.css" />
<style>
.ais-Hits-list-item img {
margin-right: 10px;
}

.ais-Hits-list-item .hit-name {
font-weight: bold;
margin-bottom: 5px;
margin-bottom: 4px;
margin-top: 12px;
}

.ais-Hits-list-item .hit-release-date {
margin-bottom: 10px;
.ais-Hits-list-item .hit-description {
margin-top: 12px;
}

.ais-Panel {
margin-bottom: 32px;
}

.ais-Pagination-list li {
Expand All @@ -30,20 +28,10 @@
<body>
<div>
<div style="display:flex">
<div id="searchbox"></div>
</div>
<div style="display:flex">
<div style="padding:20px">
<h2>Brands</h2>
<div id="brand-list"></div>

<h2>Supplier</h2>
<div id="supplier-list"></div>

<h2>Length</h2>
<div id="range-slider"></div>
<div id="dynamic-list" style="padding:20px">
</div>
<div style="flex:1;padding:20px">
<div id="searchbox"></div>
<div>
<h2>Products</h2>
<div id="stats-products"></div>
Expand All @@ -58,91 +46,101 @@ <h2>Products</h2>
</div>
<script src="https://cdn.jsdelivr.net/npm/instantsearch.js@4/dist/instantsearch.production.min.js" crossorigin="anonymous"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
const searchClient = afostoInstantSearch('prxxx');
const search = instantsearch({
indexName: 'products',
searchClient,
});
async function initSearchDemo() {
try {
const searchClient = afostoInstantSearch('movies-demo');
const settings = await searchClient.getSettings();
const indexes = settings.indexes || [];
const [firstIndex] = indexes;

search.addWidgets([
instantsearch.widgets.searchBox({
container: '#searchbox',
}),
if (!firstIndex) {
console.error('No index available');
return;
}

instantsearch.widgets.hitsPerPage({
container: '#hits-per-page',
items: [
{ label: '10 hits per page', value: 10, default: true },
{ label: '20 hits per page', value: 20 },
],
const { alias: indexName, filters = [] } = firstIndex;
const filterKeys = filters.map(filter => filter.key);
const search = instantsearch({
indexName,
searchClient,
});

search.addWidgets([
instantsearch.widgets.configure({
facets: ['main_genre', 'release_year_range'],
}),

instantsearch.widgets.refinementList({
container: '#brand-list',
attribute: 'Brand',
operator: 'and',
searchable: false,
showMore: true,
showMoreLimit: 500,
instantsearch.widgets.searchBox({
container: '#searchbox',
}),

instantsearch.widgets.refinementList({
container: '#supplier-list',
attribute: 'Supplier',
operator: 'and',
searchable: false,
showMore: true,
showMoreLimit: 500,
}),
instantsearch.widgets.hitsPerPage({
container: '#hits-per-page',
items: [
{ label: '10 hits per page', value: 10, default: true },
{ label: '20 hits per page', value: 20 },
],
}),

instantsearch.widgets.rangeSlider({
container: '#range-slider',
attribute: 'Length',
precision: 0,
step: 1,
instantsearch.widgets.dynamicWidgets({
container: '#dynamic-list',
facets: [],
transformItems(_, { results }) {
return results.facets.map(facet => facet.name);
},
widgets: filterKeys.map((attribute) => (container) =>
instantsearch.widgets.panel({
templates: {
header({ widgetParams: { attribute } = {} } = {}) {
return attribute;
},
},
})(instantsearch.widgets.refinementList)({ container, attribute, operator: 'and', searchable: false, showMore: true, showMoreLimit: 500 })
),
}),

instantsearch.widgets.pagination({
container: '#pagination',
container: '#pagination',
}),

instantsearch.widgets.stats({
container: '#stats-products',
templates: {
text: `
container: '#stats-products',
templates: {
text: `
{{#hasNoResults}}No results{{/hasNoResults}}
{{#hasOneResult}}1 result{{/hasOneResult}}
{{#hasManyResults}}{{#helpers.formatNumber}}{{nbHits}}{{/helpers.formatNumber}} results{{/hasManyResults}}
found
`,
},
},
}),

instantsearch.widgets.hits({
container: '#hits-products',
templates: {
item: `
<div class="ais-Hits-list-item">
<img src="{{metadata.image}}" align="left" alt="{{metadata.name}}" width="100" />
<div class="hit-name">
{{title}}
</div>
<div class="hit-release-date">Brand: {{Brand}}</div>
<div class="hit-release-date">Length: {{Length}}</div>
<div class="hit-description">
{{description}}
</div>
<div class="price">
&euro;{{price}}
</div>
</div>
`,
},
container: '#hits-products',
templates: {
item: `
<div class="ais-Hits-list-item">
<img src="{{poster}}" alt="{{title}}" width="100%" />
<div class="hit-name">
{{title}} ({{release_year}})
</div>
<div class="hit-description">
{{description}}
</div>
</div>
`,
},
}),
]);
]);

search.start();
} catch (error) {

search.start();
}
}

document.addEventListener('DOMContentLoaded', function() {
initSearchDemo();
});
</script>
</body>
Expand Down
18 changes: 17 additions & 1 deletion src/afostoInstantSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,26 @@ const afostoInstantSearch = (searchEngineKey, options = {}) => {
}

const clientOptions = { ...DEFAULT_OPTIONS, ...(options ?? {}) };
const url = clientOptions.baseUrl?.replace('{key}', searchEngineKey);
const searchRequestAdapter = SearchRequestAdapter();
const searchResponseAdapter = SearchResponseAdapter();

const getSettings = async () => {
try {
const settingsRequestOptions = clientOptions.settingsRequestOptions || {};
const settingsResponse = await fetch(`${url}/settings`, {
...settingsRequestOptions,
method: 'GET',
});
const response = await settingsResponse.json();

return response.data;
} catch (error) {
return {};
}
};

const searchRequest = async context => {
const url = clientOptions.baseUrl?.replace('{key}', searchEngineKey);
const requestOptions = clientOptions.requestOptions || {};
const hasContextFormatter = clientOptions.transformContext && typeof clientOptions.transformContext === 'function';
const hasResponseFormatter = clientOptions.transformResponse && typeof clientOptions.transformResponse === 'function';
Expand Down Expand Up @@ -67,6 +82,7 @@ const afostoInstantSearch = (searchEngineKey, options = {}) => {
}

return {
getSettings,
search,
searchForFacetValues,
};
Expand Down
1 change: 1 addition & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export const DEFAULT_OPTIONS = {
baseUrl: 'https://afosto.io/api/instant/search/{key}',
hitsPerPage: 10,
requestOptions: {},
settingsRequestOptions: {},
threshold: 1,
transformContext: data => data,
transformResponse: data => data,
Expand Down

0 comments on commit 575426e

Please sign in to comment.