diff --git a/assets/js/autosuggest.js b/assets/js/autosuggest.js
index f407566f85..463fcef3b1 100644
--- a/assets/js/autosuggest.js
+++ b/assets/js/autosuggest.js
@@ -275,6 +275,10 @@ function updateAutosuggestBox(options, input) {
itemString += itemHTML;
}
+ if (typeof window.epAutosuggestListItemsHTMLFilter !== 'undefined') {
+ itemString = window.epAutosuggestListItemsHTMLFilter(itemString, options, input);
+ }
+
// append list items to the list
suggestList.innerHTML = itemString;
@@ -655,7 +659,11 @@ function init() {
autosuggestElement.appendChild(autosuggestList);
}
- const clonedElement = autosuggestElement.cloneNode(true);
+ let clonedElement = autosuggestElement.cloneNode(true);
+
+ if (typeof window.epAutosuggestElementFilter !== 'undefined') {
+ clonedElement = window.epAutosuggestElementFilter(clonedElement, element);
+ }
element.insertAdjacentElement('afterend', clonedElement);
};
diff --git a/docs/theme-integration.md b/docs/theme-integration.md
index d14f2a20fc..dd5936807f 100644
--- a/docs/theme-integration.md
+++ b/docs/theme-integration.md
@@ -2,7 +2,7 @@
### Connecting Autosuggest to Your Theme's Search Bar
-When enabled the ElasticPress Autosuggest will automatically be added to any `input[type="search"]` elments on the page, as well as any elements with the `.ep-autosuggest` or `.search-field` classes. You can add autosuggest to additional elements yourself by adding [selectors](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Selectors) as a comma-separated list to the _Autosuggest Selector_ setting under _ElasticPress > Features > Autosuggest > Settings_.
+When enabled, ElasticPress Autosuggest will automatically add itself to any `input[type="search"]` elments on the page, as well as any elements with the `.ep-autosuggest` or `.search-field` classes. You can add Autosuggest to additional elements yourself by adding [selectors](https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Selectors) as a comma-separated list to the _Autosuggest Selector_ setting under _ElasticPress > Features > Autosuggest > Settings_.
You can change or remove the default selectors used by the plugin with the `ep_autosuggest_default_selectors` filter:
```
@@ -32,4 +32,119 @@ You could display the loading gif while suggestions are being fetched with this
.is-loading .loading-indicator {
display: block;
}
-```
\ No newline at end of file
+```
+
+### Customize Suggestion Markup
+
+When ElasticPress Autosuggest renders the list of suggestions, each item is run through a `window.epAutosuggestItemHTMLFilter()` function (if this function is defined). Defining this function in your theme (or a plugin, if appropriate) enables you to customize the markup for suggestions and add or remove fields to be displayed in the suggestion.
+
+The `epAutosuggestItemHTMLFilter()` function must return the HTML for the suggestion as a string, and accept 4 parameters:
+
+1. `itemHTML` _(string)_ The suggestion HTML as a string.
+2. `option` _(object)_ The Elasticsearch record for the suggestion.
+3. `i` _(int)_ The index of the suggestion in the results set.
+4. `searchText` _(string)_ The search term.
+
+This example uses the function to add the post date to the suggestion:
+
+```
+window.epAutosuggestItemHTMLFilter = (itemHTML, option, i, searchText) => {
+ const text = option._source.post_title;
+ const url = option._source.permalink;
+ const postDate = new Date(option._source.post_date).toLocaleString('en', { dateStyle: 'medium' })
+
+ return `
+
+ ${text} (${postDate})
+
+ `;
+}
+```
+
+Note that the `class`, `id`, `role`, `aria-selected`, `data-url`, and `tabindex` attributes in the returned markup must match the default values for those attributes, as they do in the example, to ensure that Autosuggest functions as normal.
+
+### Customize Suggestions List Markup
+
+ElasticPress Autosuggest enables customization of the entire suggestions list using the `window.epAutosuggestListItemsHTMLFilter()` function, (if this function is defined). By defining this function in your theme (or a plugin, if appropriate), you can append or prepend items to the suggestions list, or otherwise make edits to the entire list (rather than individual suggestions).
+
+The `epAutosuggestListItemsHTMLFilter()` function must return the HTML for the suggestions list as a string, and accept 3 parameters:
+
+1. `listItemsHTML` _(string)_ The list items HTML as a string.
+2. `options` _(array)_ The Elasticsearch records for all of the suggestions being listed.
+3. `input` _(Element)_ The DOM element of the input that triggered Autosuggest.
+
+This example uses the function to add a "View All Results" link to the bottom of the suggestions list.
+
+```
+window.epAutosuggestListItemsHTMLFilter = (listItemsHTML, options, input) => {
+ const allUrl = new URL(input.form.action);
+ const formData = new FormData(input.form);
+ const urlParams = new URLSearchParams(formData);
+
+ allUrl.search = urlParams.toString();
+
+ const url = allUrl.toString();
+
+ listItemsHTML += `
+
+ View All Results
+
+ `;
+
+ return listItemsHTML;
+}
+```
+
+Note that the `class`, `role`, `aria-selected`, and `tabindex` attributes in any new items must match the default values for those attributes, as they do in the example, to ensure that Autosuggest functions as normal. Items must also contain a link with the `href` and `data-url` attributes set to the URL that the item should link to.
+
+### Customize the Suggestions Container
+
+Before ElasticPress inserts the markup for Autosuggest into the search form the element to be added is run through a `window.epAutosuggestElementFilter()` function (if this function is defined). This function enables you to modify the markup of the Autosuggest container by defining this function in your theme (or a plugin, if appropriate).
+
+The `epAutosuggestElementFilter()` function must return a DOM element, and accept 2 parameters:
+
+1. `element` _(Element)_ The DOM element being inserted.
+2. `input` _(Element)_ The DOM element Autosuggest is being inserted after.
+
+This example uses the function to add a "Powered by ElasticPress" message to the Autosuggest dropdown.
+
+```
+window.epAutosuggestElementFilter = (element, input) => {
+ const poweredBy = document.createElement('div');
+
+ poweredBy.textContent = 'Powered by ElasticPress';
+
+ element.appendChild(poweredBy);
+
+ return element;
+}
+```
+
+### Customize the Autosuggest Query
+
+To get suggestions for Autosuggest, ElasticPress sends an AJAX request containing an Elasticsearch query to your Autosuggest endpoint. This request can be modified prior to sending via the `window.epAutosuggestQueryFilter()` function (if this function is defined) in order to customize or enhance the request with additional client-side data.
+
+The `epAutosuggestQueryFilter()` function must return a JavaScript object representing the query, and accept 3 parameters:
+
+1. `query` _(Object)_ The Elasticsearch query as a JavaScript object.
+2. `searchText` _(string)_ The search term.
+2. `input` _(Element)_ The DOM element of the input that triggered Autosuggest.
+
+This example uses the function to add the value of a `wp_dropdown_categories()` field as a filter to the search query:
+
+```
+window.epAutosuggestQueryFilter = (query, searchText, input) => {
+ const formData = new FormData(input.form);
+ const category = formData.get('cat');
+
+ if (category) {
+ query.post_filter.bool.must.push({
+ term: {
+ 'terms.category.term_id': parseInt(category, 10),
+ },
+ });
+ }
+
+ return query;
+}
+```