Simonski
Simonski

Reputation: 121

Shopify Predictive Search Ajax Call

I'm quite new to shopify, liquid and all that comes with it.
I try to implement predective search on shopify and I just don't know why I'm not even getting the alert of the Ajax call that is in the following code. I put it in my "theme.liquid" file right above the closing body tag. I assume if it would work, there should be the alert right when opening the page, no? Goki is a vendor, many products are shown when I search for it on my page. My code looks like this:

<script>
jQuery.getJSON("/search/suggest.json", {
  "q": "goki",
  "resources": {
    "type": "product",
    "limit": 4,
    "options": {
      "unavailable_products": "last",
      "fields": "title,product_type,variants.title"
    }
  }
}).done(function(response) {
  var productSuggestions = response.resources.results.products;
  if (productSuggestions.length > 0) {
    var firstProductSuggestion = productSuggestions[0];
    alert("The title of the first product suggestion is: " + firstProductSuggestion.title);
  }
});
</script>


Any help would be very very much appreciated! Thank you!

Upvotes: 0

Views: 1703

Answers (2)

fox molder
fox molder

Reputation: 1

Please create an snippet name "predictive-search.liquid" and insert the below code inside the Snippet.After that include this snippet where you want to use.

document.addEventListener("DOMContentLoaded", function () {
    const searchInput = document.getElementById("search-input");
    const resultsContainer = document.getElementById("predictive-results");
    const clearButton = document.getElementById("clear-search");

    searchInput.addEventListener("input", function () {
        let query = searchInput.value.trim();

        // Show/hide clear button
        clearButton.style.display = query.length > 0 ? "block" : "none";

        if (query.length < 2) {
            resultsContainer.innerHTML = "";
            return;
        }

        fetch(`/search/suggest.json?q=${query}&resources[type]=product`)
            .then(response => response.json())
            .then(data => {
                 var s_url = `/search?q=${query}&type=product`;
                //alert(s_url);
                resultsContainer.innerHTML = "";

                if (data.resources.results.products.length > 0) {
                    var k = 0;
                    let resultsHTML = "<ul>";
                    data.resources.results.products.forEach(product => {
                        if(k<5){
                        resultsHTML += `
                            <li>
                                <a href="${product.url}">
                                    <img src="${product.image}" alt="${product.title}">
                                    <span>${product.title}</span>
                                </a>
                            </li>
                        `;
                        }

                      k++;
                    });
                    resultsHTML += "</ul>";
                    if(k>5){
                      resultsHTML += "<p class='predictive_results_viewmore'><a href='"+s_url+"'>View more products</a></p>";
                    }
                    resultsContainer.innerHTML = resultsHTML;
                  
                } else {
                    resultsContainer.innerHTML = "<p class='predictive_results_notfound'>No products found</p>";
                }
            })
            .catch(error => console.error("Error fetching product search:", error));
    });

    // Clear input when clicking the clear button
    clearButton.addEventListener("click", function () {
        searchInput.value = "";
        resultsContainer.innerHTML = "";
        clearButton.style.display = "none";
    });
});
.search-container {
    position: relative;
    width: 100%;
    max-width: 400px;
    margin: 0 auto;
}

.search-box {
    position: relative;
    display: flex;
    align-items: center;
    background: #fff;
    border: 1px solid rgba(54, 124, 54, 0.15);
    border-radius: 5px;
    padding: unset;
    border-bottom: unset;  
}

.search-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 10px;
    color: #888;
}

.search-icon svg {
    width: 18px;
    height: 18px;
}

#search-input {
  flex: 1;
  border: none;
  outline: none;
  padding: 8px;
  font-size: 14px;
  height: 40px;
}

.clear-button {
  background: none;
  border: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  padding: 0 10px;
}

.clear-button svg {
    width: 16px;
    height: 16px;
    color: #888;
}

.clear-button:hover svg {
    color: #555;
}

.search-results {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: #fff;
    border: 1px solid rgba(54, 124, 54, 0.15);
    border-top: none; /* Ensures there's no double border between input and results */
    border-radius: 0 0 5px 5px; /* Round only bottom corners */
    max-height: 350px;
    overflow-y: auto;
    z-index: 1000;
  -webkit-overflow-scrolling: touch;
}

.search-results ul {
    list-style: none;
    padding: 0;
    margin: 0;
}

.search-results li {
  padding: 2px 10px;
  display: flex;
  align-items: center;
  border-bottom: 1px solid rgba(54, 124, 54, 0.15);
  font-size: 12px;
  margin: 0px;
}

.search-results li img {
    width: 40px;
    height: 40px;
    object-fit: cover;
    margin-right: 10px;
    border-radius: 5px;
}

.search-results li a {
    text-decoration: none;
    color: #333;
    display: flex;
    align-items: center;
    width: 100%;
}

.search-results li:hover {
    background: #f4f4f4;
}

.coll-module-header{
  padding-bottom: 50px !important;
}

.coll_search_container{
  margin-bottom: 30px;
  margin-left: 10px;
  margin-right: 10px;
}

.predictive_results_viewmore{
  font-size: 12px;
}

.predictive_results_notfound{
  font-size: 12px;
}
<div class="search-container">
    <div class="search-box">
        <span class="search-icon">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <circle cx="11" cy="11" r="8"></circle>
                <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
            </svg>
        </span>
        <input type="text" id="search-input" placeholder="Search for products..." autocomplete="off">
        <button id="clear-search" class="clear-button" style="display: none;">
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <line x1="18" y1="6" x2="6" y2="18"></line>
                <line x1="6" y1="6" x2="18" y2="18"></line>
            </svg>
        </button>
    </div>
    <div id="predictive-results" class="search-results"></div>
</div>

Upvotes: 0

Simonski
Simonski

Reputation: 121

I solved it. I created an own variable AjaxData with all the 'resources' parameter before entering the JQuery call. There I don't use the variable to create the url, it's just used to define param in the call, not to change the url. -that's the trick

Upvotes: 0

Related Questions