2
votes

we have been struggling with this problem for weeks and still have not found a solution.

We have a Shopify store with 2000 products and 300 vendors. Each vendor has a "ranking number" which we have assigned to them and entered into the "barcode" field in the variants of every single product.

The goal is that we want Shopify to be able to sort our search results by the Barcode using the liquid "sort" tag like so:

{% assign foo = search.results | sort:'title' %}

However, when we attempt to use this syntax to sort by "barcode" it doesn't return any results

{% assign foo = search.results | sort:'barcode' %}

We have attempted to use 'sort' with all the following arguments but none of them work:

{% assign foo = search.results | sort:'product.barcode' %}
{% assign foo = search.results | sort:'item.barcode' %}
{% assign foo = search.results | sort:'item.variants.first.barcode' %}
{% assign foo = search.results | sort:'items.variants.variant.barcode' %}

etc, but none of them work. If ANYONE can point us in the right direction for which argument/syntax to use to sort our search results by variant.barcode, it would be MUCH APPRECIATED!!!!!

Thanks

1
I don't have any barcodes set up to test this with, but have you tried {% assign foo = search.results | map: 'item' | sort: 'barcode' %} ? The map filter will reduce the search.results to just an array of items, which should then be sortable with the sort filter...Dave B

1 Answers

1
votes

In terms of native functionality you're out of luck.

You can do something like this though by rolling your own.

  1. Manually sort your collections by vendor rank
  2. Limit your search to collection results by creating your own search function or
  3. creat your own search function but make it a "filter" on your current collection and leave the native search alone.

Create Your Own Search:

  1. Put your item results cell in a snippet. collection-product.liquid
  2. Include that snippet in your collecton liquid.
  3. Make a new collection template (collection.search-results.liquid)

collection.search-results.liquid looks something like the following. Your pagination size should match the pagination size of your main collection.

{% layout none %}
{% paginate collection.products by 50 %}
<div class="search-results">
{% for product in collection.products %}
  {% include 'collection-product' %}
{% endfor %}
</div>
{% endpaginate %}

Now your search becomes an input box with some javascript. The fun part. The script below was pulled from a working site. I've trimmed it up somewhat to hopefully make the bones of it clearer but it probably won't run as is. I've removed references to adding a search because for your purposes you want the native custom search.

As to why not just sort the results. You could use this concept to do that but it returns results a page at a time. In order to custom search all the results you'd have to accumulate the results and sort them when the search is finished. Search time then depends heavily on the size of the collection and the user's network speed.

var defaultView = $(".filters-off"); // add this class to your main collection wrapper
var facetView = $("#filter_target"); // <div id="filter_target"></div> below your main collection wrapper

var currentRequest = 0;
function filterCollection(term){
    //[[t1, t2], [t3,t4]]
     // console.log('applying '+ JSON.stringify(facets));

    var anyResults = false;
    var resultsPage=0;
    var PAGE_SIZE = 50;
    var productsFound = 0;
    var collectionPath = location.pathname;

    console.log('get from '+ collectionPath);
    currentRequest = new Date().getTime();

    var viewLink = collectionPath+'?view=search-results'; // same as your layout none template

    function applyFilter(myRequest){
        resultsPage++;
        if(resultsPage > 20) return false; // arbitrary abort for too many results
        if(resultsPage > 1) viewLink+='&page='+resultsPage;
        return $.get(viewLink).then(function(page){
            if(currentRequest != myRequest){
                console.log('mid abort');
                return false;
            }
            var pageProducts = $("div[data-tags]", page); //some markup you added to collection-product snippet to help plucking the product elements
            if(!pageProducts.length) return false;

            console.log('found: '+ pageProducts.length);

            var filteredProducts = pageProducts.filter(function(){
                if($(this).text().indexOf(term) != -1) return true; // search the returned text

                if($(this).attr('data-keywords').indexOf(term) != -1) return true;
                return false;
            });
            if(filteredProducts.length){
                if(!anyResults){
                    anyResults = true;
                    toggleView(true);

                }
                filterView.append(filteredProducts);
                productsFound+= filteredProducts.length;
            }
            return (pageProducts.length == PAGE_SIZE && currentRequest == myRequest) ? applyFilter(myRequest) : false;
        }).then(function(proceed){
            if(currentRequest == myRequest){

                if(!anyResults){
                    toggleView(false, true);
                }
            }
        });
    }
    applyFilter(currentRequest);
}


function toggleView (showFacets, showNoGo){
    facetView.empty();
    $(".filter-progress").empty();
    if(showFacets) {
        defaultView.add('.pagination').hide();

    }else {

        if(!showNoGo){
            defaultView.add('.pagination').show();
        }else {
            $(".no-facets").clone(true).appendTo(facetView).show(); // .no-facets is normally hidden chunk that allows for easy internationaliztion of "No results found" type messages
        }
    }
};