Usage
nebula.autocompleteSearch(element, types)
Parameters
element
(Required) (Object (or String)) The jQuery object (or selector) of the search input field
Default: None
types
(Optional) (String) A comma-separated string of post types to include
Default: 'any'
Examples
Include only posts and pages in search.
nebula.loadJS(nebula.site.resources.scripts.nebula_jquery_ui, 'jquery-ui').then(function(){ //Ensure jQuery-UI JS is loaded jQuery('#example-input').on('keyup paste', function(){ //Add the listener nebula.autocompleteSearch(jQuery(this), 'post,page'); }); }); nebula.loadCSS(nebula.site.resources.styles.nebula_jquery_ui); //Load the jQuery-UI CSS too
Search all post types by simply using the WordPress core "s" class.
<input class="s" type="text" placeholder="Search this site..." />
Customize the post types in an HTML form without needing to re-write any JavaScript
<input class="search" type="text" data-types="post,page" />
Additional Notes
For an easier implementation, you could simply add the class s
to the search input. See autocompleteSearchListeners().
On keypress or paste, this function triggers nebula_autocomplete_search_start.
On autocomplete success, nebula_autocomplete_search_success is triggered.
When search results are available, nebula_autocomplete_search_results is triggered, otherwise nebula_autocomplete_search_no_results is triggered if no results are available.
On AJAX error, this function triggers nebula_autocomplete_search_error.
Source File
Located in /assets/js/modules/search.js on line 131.
No Hooks
This function does not have any filters or actions available. Request one?nebula.autocompleteSearch = function(element, types = ''){ if ( typeof element === 'string' ){ element = jQuery(element); } if ( types && Array.isArray(types) ){ types = types.join(','); //Convert an array to to a comma-separated string } nebula.dom.document.trigger('nebula_autocomplete_search_start', element); nebula.timer('(Nebula) Autocomplete Search', 'start'); nebula.timer('(Nebula) Autocomplete Response', 'start'); if ( element.val().trim().length ){ if ( element.val().trim().length >= 2 ){ //This checks the length for animation but the minlength (below) handles it for autocomplete //Add "searching" class for custom Nebula styled forms element.closest('form').addClass('searching'); setTimeout(function(){ element.closest('form').removeClass('searching'); }, 10_000); //Swap magnifying glass on Bootstrap input-group element.closest('.input-group').find('.fa-search').removeClass('fa-search').addClass('fa-spin fa-spinner'); } else { element.closest('form').removeClass('searching'); element.closest('.input-group').find('.fa-spin').removeClass('fa-spin fa-spinner').addClass('fa-search'); } let typesQuery = ''; if ( types ){ typesQuery = '&types=' + types; } if ( typeof element.autocomplete !== 'function' ){ nebula.help('nebula.autocompleteSearch requires jQuery UI. Load that library before calling this function', '/functions/autocompletesearch/'); return false; } element.autocomplete({ //jQuery UI dependent position: { my: 'left top-2px', at: 'left bottom', collision: 'flip', }, source: async function(request, sourceResponse){ let searchResults = nebula.memoize('get', 'autocomplete search (' + request.term.toLowerCase() + ') [' + typesQuery + ']'); //Try from stored memory first if ( !searchResults ){ var fetchResponse = await fetch(nebula.site.home_url + '/wp-json/nebula/v2/autocomplete_search?term=' + request.term + typesQuery, {importance: 'high'}).then(function(fetchResponse){ return fetchResponse.json(); }).then(function(fetchData){ searchResults = nebula.memoize('set', 'autocomplete search (' + request.term.toLowerCase() + ') [' + typesQuery + ']', fetchData); //Add to stored memory }).catch(function(error){ nebula.dom.document.trigger('nebula_autocomplete_search_error', request.term); nebula.debounce(function(){ ga('send', 'exception', {'exDescription': '(JS) Autocomplete AJAX error: ' + error, 'exFatal': false}); nebula.crm('event', 'Autocomplete Search AJAX Error'); }, 1500, 'autocomplete error buffer'); element.closest('form').removeClass('searching'); element.closest('.input-group').find('.fa-spin').removeClass('fa-spin fa-spinner').addClass('fa-search'); }); } nebula.dom.document.trigger('nebula_autocomplete_search_success', searchResults); ga('set', nebula.analytics.metrics.autocompleteSearches, 1); var noSearchResults = ' (No Results)'; //Prep the string if ( searchResults ){ nebula.dom.document.trigger('nebula_autocomplete_search_results', searchResults); nebula.prefetch(searchResults[0].link); jQuery.each(searchResults, function(index, value){ value.label = value.label.replaceAll(/&/g, '\&'); }); noSearchResults = ''; } else { nebula.dom.document.trigger('nebula_autocomplete_search_no_results'); } nebula.debounce(function(){ let thisEvent = { category: 'Internal Search', action: 'Autocomplete Search' + noSearchResults, //GA4 name: "search" request: request, term: request.term.toLowerCase(), noResults: ( noSearchResults )? true : false, }; nebula.dom.document.trigger('nebula_event', thisEvent); ga('send', 'event', thisEvent.category, thisEvent.action, thisEvent.term); if ( typeof fbq === 'function' ){fbq('track', 'Search', {search_string: thisEvent.term});} if ( typeof clarity === 'function' ){clarity('set', thisEvent.category, thisEvent.term);} nebula.crm('identify', {internal_search: thisEvent.term}); }, 1500, 'autocomplete success buffer'); ga('send', 'timing', 'Autocomplete Search', 'Server Response', Math.round(nebula.timer('(Nebula) Autocomplete Search', 'lap')), 'Each search until server results'); sourceResponse(searchResults); //Respond to the jQuery UI Autocomplete now element.closest('form').removeClass('searching').addClass('autocompleted'); element.closest('.input-group').find('.fa-spin').removeClass('fa-spin fa-spinner').addClass('fa-search'); }, focus: function(event, ui){ event.preventDefault(); //Prevent input value from changing. }, select: function(event, ui){ let thisEvent = { category: 'Internal Search', action: 'Autocomplete Click', //GA4 name: "select_content" ui: ui, label: ui.item.label, external: ( typeof ui.item.external !== 'undefined' )? true : false, }; ga('set', nebula.analytics.metrics.autocompleteSearchClicks, 1); nebula.dom.document.trigger('nebula_autocomplete_search_selected', thisEvent.ui); nebula.dom.document.trigger('nebula_event', thisEvent); ga('send', 'event', thisEvent.category, thisEvent.action, thisEvent.label); ga('send', 'timing', 'Autocomplete Search', 'Until Navigation', Math.round(nebula.timer('(Nebula) Autocomplete Search', 'end')), 'From first initial search until navigation'); if ( thisEvent.external ){ window.open(ui.item.link, '_blank'); } else { window.location.href = ui.item.link; } }, open: function(){ element.closest('form').addClass('autocompleted'); let heroAutoCompleteDropdown = jQuery('.form-identifier-nebula-hero-search'); heroAutoCompleteDropdown.css('max-width', element.outerWidth()); }, close: function(){ element.closest('form').removeClass('autocompleted'); }, minLength: 3, //Require at least 3 characters }).data('ui-autocomplete')._renderItem = function(ul, item){ let thisSimilarity = ( typeof item.similarity !== 'undefined' )? item.similarity.toFixed(1) + '% Match' : ''; let listItem = jQuery("<li class='" + item.classes + "' title='" + thisSimilarity + "'></li>").data("item.autocomplete", item).append("<a href='" + item.link + "'> " + item.label.replaceAll(/\\/g, '') + "</a>").appendTo(ul); return listItem; }; let thisFormIdentifier = element.closest('form').attr('id') || element.closest('form').attr('name') || element.closest('form').attr('class'); element.autocomplete('widget').addClass('form-identifier-' + thisFormIdentifier); } };
Override
To override or disable this JavaScript function, simply redeclare it with the exact same function name.
nebula.autocompleteSearch = function(element, types){ //Write your own code here, leave it blank, or return false. }