autocomplete
autocomplete copied to clipboard
Sending events in the render function
Discussed in https://github.com/algolia/autocomplete/discussions/1172
Originally posted by JakeSCahill August 9, 2023
I am using render() in my autocomplete instance to customize the display. I want to be able to send events from this customized template. However, I always get Uncaught Error: Before calling any methods on the analytics, you first need to call the 'init' function with appId and apiKey parameters or provide custom credentials in additional parameters..
Events are working fine outside of the render() function.
autocomplete({
container: '#autocomplete',
placeholder: 'Search for docs',
detachedMediaQuery: '',
plugins: [],
insights: true,
defaultActiveItemId: 0,
onStateChange({ state }) {
state.preview = null
},
render({ children, state, render, html, components, createElement }, root) {
const { preview } = state.context;
render(
html`<div class="aa-Grid">
<div class="aa-Results aa-Column">${children}</div>
${preview
? html`<div class="aa-Preview aa-Column doc">
<div class="aa-PanelLayout aa-Panel--scrollable">
${
preview.image.src
? html`<div class="aa-ItemIcon">
<img
src="${preview.image.src}"
alt="${preview.image.alt}"
width="40"
height="40"
/>
</div>`
: ''
}
<div class="breadcrumbs">
<ul>
${preview.breadcrumbs.map(breadcrumb =>
html`<li><a onclick="${(event) => {
event.preventDefault();
event.stopPropagation();
console.log(event)
console.log(state)
state.context.algoliaInsightsPlugin.insights.clickedObjectIDsAfterSearch({
eventName: 'Item Selected',
index: state.context.preview.__autocomplete_indexName,
queryID: state.context.preview.__autocomplete_queryID,
objectIDs: [state.context.preview.objectID],
positions: [state.activeItemId]
})
}}" href="${breadcrumb.u}">${breadcrumb.t}</a></li>`
)}
</ul>
</div>
<h3>
${components.Highlight({
hit: preview,
attribute: 'title',
})}
</h3>
<p>
${components.Highlight({
hit: preview,
attribute: 'intro',
})}
</p>
<div class="toc sidebar">
<div class="toc-menu">
${preview.titles.length > 0 ?
html`<h4>On this page</h4>`
: ''}
<ul>
${preview.titles.map(title =>
html`<li><a href="${preview.objectID}#${title.h}">${components.Highlight({
hit: title,
attribute: 't',
})}</a></li>`
)}
</ul>
</div>
</div>
</div>
</div>`
: ''
}
</div>`,
root
);
},
...
getSources({ query }) {
if (!query) return [];
return [
{
sourceId: 'docs',
getItems() {
return getAlgoliaResults({
searchClient,
queries: [
{
indexName: '{{{env.ALGOLIA_INDEX_NAME}}}',
query,
params: {
clickAnalytics: true,
hitsPerPage: 10,
attributesToSnippet: ['title:7'],
snippetEllipsisText: '…',
facetFilters: ['version: {{#if (or (eq page.component.title 'home')(eq page.component.layout '404'))}}{{{site.components.ROOT.latest.version}}}{{else}}{{{page.version}}}{{/if}}','product: {{#if (or (eq page.component.title 'home') (eq page.component.layout '404'))}}Redpanda{{else}}{{{page.component.title}}}{{/if}}']
},
},
],
})
},
templates: {
noResults({state, html}) {
state.context.preview = null
if (!state.query) return
return html`<div>No results for ${state.query}</div><p>Believe this query should return results?<a href="https://github.com/redpanda-data/documentation/issues/new?title=No%20search%20results%20for%20${state.query}"> Let us know</a>.</p>`;
},
header({html}) {
return html`<span class="aa-SourceHeaderTitle">{{#if (or (eq page.component.title 'home') (eq page.component.layout '404'))}}Redpanda{{else}}{{{page.component.title}}}{{/if}} {{#if (or (eq page.component.title 'home')(eq page.component.layout '404'))}}{{{site.components.ROOT.latest.version}}}{{else}}{{{page.version}}}{{/if}}</span>
<div class="aa-SourceHeaderLine"></div>
`;
},
footer({state, html}) {
if (state.context.preview) {
return html`<div class="aa-Footer">
<a class="aa-ItemLink" href="{{{relativize '/search' }}}?q=${state.query}">View all results</a>
</div>`
}
},
item({ item, components, html }) {
return html`<a class="aa-ItemLink" href="${item.objectID}">
<div class="aa-ItemContent">
<div class="aa-ItemContentBody">
<div class="aa-ItemContentRow">
<div class="aa-ItemContentTitle">
${components.Highlight({
hit: item,
attribute: 'title',
})}
</div>
</div>
<div class="aa-ItemContentRow">
<div class="aa-Breadcrumbs">
<ul>
${item.breadcrumbs.length > 2 && item.breadcrumbs.slice(1, item.breadcrumbs.length - 1).map(breadcrumb =>
html`<li>${breadcrumb.t}</li>`
)}
${item.breadcrumbs.length === 2 && item.breadcrumbs.slice(1).map(breadcrumb =>
html`<li>${breadcrumb.t}</li>`
)}
</ul>
</div>
</div>
</div>
<div class="aa-ItemActions">
<button
class="aa-ItemActionButton aa-DesktopOnly aa-ActiveOnly"
type="button"
title="Open page"
>
<svg
viewBox="0 0 24 24"
width="20"
height="20"
fill="currentColor"
>
<path
d="M18.984 6.984h2.016v6h-15.188l3.609 3.609-1.406 1.406-6-6 6-6 1.406 1.406-3.609 3.609h13.172v-4.031z"
/>
</svg>
</button>
</div>
</div>
</a>`;
},
},
getItemUrl({ item }) {
return item.objectID;
},
onActive({ item, setContext }) {
if (item) {
setContext({ preview: item });
} else {
setContext( { preview: null } );
}
},
},
{
sourceId: 'suggestions',
getItems({ query }) {
return getAlgoliaResults({
searchClient,
queries: [
{
indexName: '{{{env.ALGOLIA_INDEX_NAME}}}_query_suggestions',
query,
params: {
hitsPerPage: 5,
},
},
],
});
},
onSelect({ item, setQuery, setIsOpen, refresh }) {
setQuery(`${item.query} `);
setIsOpen(true);
refresh();
},
templates: {
header({ items, html }) {
if (items.length === 0) {
return null;
}
return html`
<span class="aa-SourceHeaderTitle">
Can't find what you're looking for?
</span>
<div class="aa-SourceHeaderLine" />
`
},
item({ item, components, html }) {
console.log(item)
return html`<div class="aa-QuerySuggestion">
${item.query}
</div>`
},
},
}
];
},
});
})