Skip to content

Instantly share code, notes, and snippets.

@ADTC
Last active April 3, 2023 19:21
Show Gist options
  • Save ADTC/356bc5b35cba74c1c6dcf6ce7d406dcd to your computer and use it in GitHub Desktop.
Save ADTC/356bc5b35cba74c1c6dcf6ce7d406dcd to your computer and use it in GitHub Desktop.
Autocomplete in Search for Shopify - Modifications for Supply theme
{% assign results_box_width = '242px' %}
{% assign results_box_background_color = '#ffffff' %}
{% assign results_box_border_color = '#d4d4d4' %}
<script>
// Source: https://www.huratips.com/tech-tips/how-to-add-autocomplete-for-search-boxes-to-your-shopify-store.html
$(function() {
var closeButtonHTML = '<span class="close-button" title="Close">×</span>';
// Current Ajax request.
var currentAjaxRequest = null;
// Grabbing all search forms on the page, and adding a .search-results list to each.
var searchForms = $('form[action="/search"]').css('position','relative').each(function() {
// Grabbing text input.
var input = $(this).find('input[name="q"]');
// Adding a list for showing search results.
var offSet = input.position().top + input.innerHeight();
$('<ul class="search-results"></ul>').css( { 'position': 'absolute', 'left': '0px', 'top': offSet } ).appendTo($(this)).hide();
// Listening to keyup and change on the text field within these search forms.
input.attr('autocomplete', 'off').bind('keyup change focus', function() {
// What's the search term?
var term = $(this).val()+'*';
// What's the search form?
var form = $(this).closest('form');
// What's the search URL?
var searchURL = '/search?type=product&q=' + term;
// What's the search results list?
var resultsList = form.find('.search-results');
// If that's a new term and it contains at least 3 characters.
// if (term.length > 3 && term != $(this).attr('data-old-term')) {
if (term.length > 3) {
// Show the relust box
resultsList.fadeIn(200);
// Check if it's the same term
if (term == $(this).attr('data-old-term')) {
// Same term again. Don't do anything.
return;
}
// Show that we're searching
resultsList.html('<li><span class="title message">Searching...</span></li>');
// Saving old query.
$(this).attr('data-old-term', term);
// Killing any Ajax request that's currently being processed.
if (currentAjaxRequest != null) currentAjaxRequest.abort();
// Pulling results.
currentAjaxRequest = $.getJSON(searchURL + '&view=json', function(data) {
// Reset results.
resultsList.empty();
// If we have no results.
if(data.results_count == 0) {
resultsList.html('<li><span class="title message">No results</span>'+closeButtonHTML+'</li>');
// resultsList.fadeIn(200);
// resultsList.hide();
} else {
// If we have results.
$.each(data.results, function(index, item) {
// Limit to 7 results
if (index >= 7) return;
var link = $('<a></a>').attr('href', item.url);
link.append('<span class="thumbnail"><img src="' + item.thumbnail + '" /></span>');
link.append('<span class="title">' + item.title + '</span>');
link.wrap('<li></li>');
resultsList.append(link.parent());
});
// The Ajax request will return at the most 10 results (but we limited to 7 results).
// If there are more than 7, let's link to the search results page.
if(data.results_count > 7) {
resultsList.append('<li><span class="title message"><a href="' + searchURL + '">See all ' + data.results_count + ' results</a></span>'+closeButtonHTML+'</li>');
} else {
resultsList.append('<li><span class="title message">No more results</span>'+closeButtonHTML+'</li>');
}
//resultsList.fadeIn(200);
}
// Add click event to close button
$('.search-results .close-button').bind('click', function(){
$('.search-results').fadeOut(200);
});
});
} else {
resultsList.fadeOut(200);
}
});
});
// Clicking outside makes the results disappear.
/*$('body').bind('click', function(){
$('.search-results').hide();
});*/
});
</script>
<!-- Some styles to get you started. -->
<style>
.search-results {
z-index: 19;
list-style-type: none;
width: {{ results_box_width }};
margin: 0;
padding: 0;
background: {{ results_box_background_color }};
border: 1px solid {{ results_box_border_color }};
border-radius: 3px;
-webkit-box-shadow: 0px 4px 7px 0px rgba(0,0,0,0.1);
box-shadow: 0px 4px 7px 0px rgba(0,0,0,0.1);
overflow: hidden;
}
.search-results li {
display: block;
width: 100%;
height: 38px;
margin: 0;
padding: 0;
border-top: 1px solid {{ results_box_border_color }};
line-height: 38px;
overflow: hidden;
}
.search-results li:first-child {
border-top: none;
}
.search-results a {
color: {{ settings.color_body_text }};
}
.search-results .title {
float: left;
width: {{ results_box_width | remove: 'px' | to_number | minus: 50 }}px;
padding-left: 8px;
white-space: nowrap;
overflow: hidden;
/* The text-overflow property is supported in all major browsers. */ text-overflow: ellipsis;
-o-text-overflow: ellipsis;
text-align: left;
}
.search-results .thumbnail {
float: left;
display: block;
width: 32px;
height: 32px;
margin: 3px 0 3px 3px;
padding: 0;
text-align: center;
overflow: hidden;
}
.search-results .thumbnail img {
max-width: 100%;
}
.search-results .message {
color: #858585;
}
.search-results .close-button {
float: right;
font-size: 3em;
color: #858585;
margin-right: 7px;
cursor: pointer;
}
.search-results .close-button:hover {
color: {{ settings.color_body_text }};
}
</style>
@ADTC
Copy link
Author

ADTC commented Sep 24, 2020

This is what it looks like:

molinos-search

Here are the explanations based on the line numbers on the new file. It's best if you see the comparison in Split view.

8: The HTML for a Close button (uses the mathematical multiplication symbol).

19: Added "focus" event so that clicking inside the box would show the results (if not already visible and there's something already searched).

21: Searches partial trailing matches. (foo would match foobar but not barfoo)

29-37: Changed the logic here so that the search is shown if 3 or more characters are searched. The result box is shown even before actual results are found. Because:

39: The result box notifies the user that a "Searching..." action is occuring. This prevents an impatient user from pressing Enter and navigating to the search page itself. The user, seeing the message, would patiently wait for the results to appear.

50-52: Instead of hiding, the search now shows "No results" when there are no results. Also: adds "message" class and Close button.

56-57: Having 10 results seemed too long. I truncated this to 7 results only. If you change the number, be sure to change it in line 66 as well.

64-67: Made some changes to the message, as well as added a Close button.

68-69: When there are no more results, we will still show the message "No more results" below. This allows us again to display the Close button.

71: We don't need this anymore.

73-74: This adds the click event handler for the Close button. Clicking it will hide the result box.

78-79: We'll hide the result box if the search term is too short.

84-86: We won't depend on a click on body to hide the result box, because this gives erratic behavor when interacting with the results. Yes, this will mean that the results box will remain open. That's the reason to introduce the Close button.

93: The very high z-index put the results in front of drop-down menus. I changed it to 19, which is just below the z-index 20 of the menus, so that the results are behind the menu, but still in front of most other things.

118-120: Forcing the color because of the bug in mobile view of Supply theme (the color became white).

141-143: For similar reason, forcing the width of image.

144-146: Messages like "Searching..." and "No results" will have a muted gray color.

147-156: CSS styles for the Close button.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment