Skip to content

Instantly share code, notes, and snippets.

@atikju
Last active December 15, 2023 13:40
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save atikju/0c0f3c52174f6e75809d6a86490a7da1 to your computer and use it in GitHub Desktop.
Save atikju/0c0f3c52174f6e75809d6a86490a7da1 to your computer and use it in GitHub Desktop.
Shopify Ajax Search
{% comment %}
This file can be added as a snippet and add it anywhere you want to display
{% endcomment %}
<div id="pageheader">
<div class="util-area">
<div class="search-box">
<form class="search-form" action="/search" method="get" _lpchecked="1">
<i class="icon-mag"></i>
<input type="text" name="q" placeholder="Search" autocomplete="off">
<input type="submit" value="→">
</form>
<div class="results-box" style=""></div>
</div>
</div><!-- /.util-area -->
</div><!-- /#pageheader -->
{%comment%}
This script requires jQuery library.
Add this file right before the body tag closes in your theme.liquid
{% endcomment %}
$(document).ready(function(){
/// Main search input
$('#pageheader .search-box input[type="text"]').bind('focusin focusout', function(e){
$(this).closest('.search-box').toggleClass('focus', e.type == 'focusin');
});
/// Live search
var preLoadLoadGif = $('<img src="{{ 'ajax-load.gif' | asset_url }}" />');
var searchTimeoutThrottle = 500;
var searchTimeoutID = -1;
var currReqObj = null;
var $resultsBox = $('<div class="results-box" />').appendTo('#pageheader .search-box');
$('#pageheader .search-box input[type="text"]').bind('keyup change', function(){
//Only search if search string longer than 2, and it has changed
if($(this).val().length > 2 && $(this).val() != $(this).data('oldval')) {
//Reset previous value
$(this).data('oldval', $(this).val());
// Kill outstanding ajax request
if(currReqObj != null) currReqObj.abort();
// Kill previous search
clearTimeout(searchTimeoutID);
var $form = $(this).closest('form');
//Search term
var term = '*' + $form.find('input[name="q"]').val() + '*';
//URL for full search page
var linkURL = $form.attr('action') + '?type=product&q=' + term;
//Show loading
$resultsBox.html('<div class="load"></div>');
// Do next search (in X milliseconds)
searchTimeoutID = setTimeout(function(){
//Ajax hit on search page
currReqObj = $.ajax({
url: $form.attr('action'),
data: {
type: 'product',
view: 'json',
q: term,
},
dataType: "json",
success: function(data){
currReqObj = null;
if(data.results_total == 0) {
//No results
$resultsBox.html('<div class="note">'+ {{ 'layout.live_search.no_results' | t | json }} +'</div>');
} else {
//Numerous results
$resultsBox.empty();
$.each(data.results, function(index, item){
var xshow = 'wholesale'; //term for products we dont want to show
if(!(item.title.toLowerCase().indexOf(xshow) > -1)) {
var $row = $('<a></a>').attr('href', item.url);
$row.append('<div class="img"><img src="' + item.thumb + '" /></div>');
$row.append('<div class="d-title">'+item.title+'</div>');
$resultsBox.append($row);
}
});
$resultsBox.append('<a href="' + linkURL + '" class="note">{{ 'layout.live_search.see_all' | t }} </a>');
}
}
});
}, searchTimeoutThrottle);
} else if ($(this).val().length <= 2) {
//Deleted text? Clear results
$resultsBox.empty();
}
}).attr('autocomplete', 'off').data('oldval', '').bind('focusin', function(){
//Focus, show results
$resultsBox.fadeIn(200);
}).bind('click', function(e){
//Click, prevent body from receiving click event
e.stopPropagation();
});
$('body').bind('click', function(){
//Click anywhere on page, hide results
$resultsBox.fadeOut(200);
});
//Search box should mimic live search string: products only, partial match
$('.search-form, #search-form').on('submit', function(e){
e.preventDefault();
var term = '*' + $(this).find('input[name="q"]').val() + '*';
var linkURL = $(this).attr('action') + '?type=product&q=' + term;
window.location = linkURL;
});
// search ends
});
{% comment %}
This file needs to be created in your templates. Create a template for search and name it to json.
The final file name would be search.json.liquid
{% endcomment %}
{% layout none %}
{% comment %} Inspired by: http://ecommerce.shopify.com/c/ecommerce-design/t/diy-implementing-autocomplete-with-search-144104 {% endcomment %}
{% paginate search.results by 10 %}
{% capture output %}
{% for result in search.results %}
{% assign resultURL = result.url %}
{% assign thumbURL = result.images[0] | product_img_url: 'thumb' %}
{"title":"{{ result.title | replace: '\\', '\\\\' | replace: '"', '\\"' | replace: '/','\\/' }}",
"url":"{{ result.url | replace: '\\', '\\\\' | replace: '"', '\\"' | replace: '/','\\/' }}",
"thumb":"{{ thumbURL | replace: '\\', '\\\\' | replace: '"', '\\"' | replace: '/','\\/' }}",
"id":{{result.id}} }{% unless forloop.last %},{% endunless %}
{% endfor %}
{% endcapture %}
{% comment %} Output the json object {% endcomment %}
{"results_total":{{paginate.items}},"results":[{{ output | strip_newlines }}]}
{% endpaginate %}
@Lysindr
Copy link

Lysindr commented Jan 14, 2020

Thanks for your great snipper! ( :

@armaantalreja
Copy link

Hey guys - I'm using the shopify buy button on a squarespace website to create a small shop section (yeah I'm a noob). I wanted to add a search functionality and stumbled upon this thread. I tried my hands on it but couldn't crack it. Can this js be embeded and work as a search form? Can you please guide me?

@hammadCodes
Copy link

Thank you man

@zainabbasm000
Copy link

i want to submit with enter button

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