Skip to Content

autocompleteSearch()

Run an AJAX autocomplete search using jQuery UI.

JavaScript July 2, 2019

Usage

JavaScript
nebula.autocompleteSearch(element, types)

Parameters

element
(Required) (Object (or String)) The jQuery object (or selector) of the search input field
Default: None

types
(Optional) (Array) An array of post types to include
Default: ['any']

Parameter Notes

types is not required, but will error if used and not a valid array.

Request or provide clarification »

Examples

Include only posts and pages in search.

JavaScript
jQuery('#example-input').on('keypress paste', function(){
    nebula.autocompleteSearch(jQuery(this), ['post', 'page']);
});

Search all post types by simply using the WordPress core "s" class.

HTML
<input class="s" type="text" placeholder="Search this site..." />

Additional Notes

For an easier implementation, you could simply add the class s to the search input. See initAutocompleteSearch().

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/nebula.js on line 2030.

JavaScript
nebula.autocompleteSearch = function(element, types){
    if ( typeof element === 'string' ){
        element = jQuery(element);
    }

    if ( types && !Array.isArray(types) ){
        console.error('nebula.autocompleteSearch requires 2nd parameter to be an array.');
        ga('send', 'exception', {'exDescription': '(JS) nebula.autocompleteSearch requires 2nd parameter to be an array', 'exFatal': false});
        return false;
    }

    nebula.dom.document.trigger('nebula_autocomplete_search_start', element);
    nebula.timer('(Nebula) Autocomplete Search [Start]', 'start');
    nebula.timer('(Nebula) Autocomplete Response [Start]', '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');
            }, 10000);

            //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');
        }

        var postTypes = '';
        if ( types ){
            postTypes = '&types=' + JSON.stringify(types);
        }

        element.autocomplete({ //jQuery UI dependent
            position: {
                my: "left top-2px",
                at: "left bottom",
                collision: "flip",
            },
            source: function(request, response){
                jQuery.get({ //Eventually update this to fetch with ES6
                    url: nebula.site.home_url + '/wp-json/nebula/v2/autocomplete_search?term=' + request.term + postTypes,
                    success: function(data){
                        nebula.dom.document.trigger('nebula_autocomplete_search_success', data);
                        ga('set', nebula.analytics.metrics.autocompleteSearches, 1);

                        if ( data ){
                            nebula.dom.document.trigger('nebula_autocomplete_search_results', data);
                            nebula.prefetch(data[0].link);

                            jQuery.each(data, function(index, value){
                                value.label = value.label.replace(/&#038;/g, "\&");
                            });

                            var noSearchResults = '';
                        } else {
                            nebula.dom.document.trigger('nebula_autocomplete_search_no_results');
                            var noSearchResults = ' (No Results)';
                        }

                        nebula.debounce(function(){
                            var thisEvent = {
                                category: 'Internal Search',
                                action: 'Autocomplete Search' + noSearchResults,
                                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});}
                            nebula.nv('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');
                        response(data);
                        element.closest('form').removeClass('searching').addClass('autocompleted');
                        element.closest('.input-group').find('.fa-spin').removeClass('fa-spin fa-spinner').addClass('fa-search');
                    },
                    error: function(XMLHttpRequest, textStatus, errorThrown){
                        nebula.dom.document.trigger('nebula_autocomplete_search_error', request.term);
                        nebula.debounce(function(){
                            ga('send', 'exception', {'exDescription': '(JS) Autocomplete AJAX error: ' + textStatus, 'exFatal': false});
                            nebula.nv('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');
                    },
                    timeout: 60000
                });
            },
            focus: function(event, ui){
                event.preventDefault(); //Prevent input value from changing.
            },
            select: function(event, ui){
                var thisEvent = {
                    category: 'Internal Search',
                    action: 'Autocomplete Click',
                    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');
                var 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){
            var thisSimilarity = ( typeof item.similarity !== 'undefined' )? item.similarity.toFixed(1) + '% Match' : '';
            var listItem = jQuery("<li class='" + item.classes + "' title='" + thisSimilarity + "'></li>").data("item.autocomplete", item).append("<a href='" + item.link + "'> " + item.label.replace(/\\/g, '') + "</a>").appendTo(ul);
            return listItem;
        };
        var 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.

JavaScript
nebula.autocompleteSearch = function(element, types){
    //Write your own code here, leave it blank, or return false.
}