Partial (Wildcard) Search for Responsive Theme

New Member
4 0 0

Hi Britton, I'm using the Pacific Theme. is partial wildcard search possible for this theme? I noticed the liquids are different from the other themes. I tried many codes from the different threads and tried your suggestions on top. Not sure if i am doing it right. When you say paste this at the bottom of the theme.liquid, it would be to paste before the closing body. and for the search.liquid, to paste before {% endunless %} ?
 

0 Likes
Shopify Staff (Retired)
Shopify Staff (Retired)
409 0 60

Hi again Mohammad,

these code snippets insert "OR" between each word as well as appending a * to each. After some testing it looks like it makes the search behave the way that you were wanting. Here is what you put before the closing body tag in theme.liquid:

<script type="text/javascript">
    function wildcard(str) {
     str = str.split(' ');                // will split the string delimited by space into an array of words

     for(var i = 0; i < str.length; i++){               // str.length holds the number of occurrences of the array...
          var limit = str.length - 1; 
          if (i < limit) {
          str[i] = str[i] + "* OR";                   // adds * for wildcard to each array element
          } else if ( i == limit) {
          str[i] = str[i] + "*";
          };                       
     }
     return str.join(' ');                              //  converts the array of words back to a sentence.
}

        $('#search form').submit(function () {
          
            var $searchfield = $('#search #q'),
                searchVal = $searchfield.val();
          
            $searchfield.val(wildcard(searchVal));

        });

{% if template contains 'search' %}
 $('#search-bar form').submit(function () {
          
            var $searchfield = $('#search-bar #q'),
                searchVal = $searchfield.val();
          
            $searchfield.val(wildcard(searchVal));

        });
{% endif %}

</script>

That one snippet at the bottom of theme.liquid does the same job as the two old snippets used to, so you should be able to delete the bit from search.liquid.

As for the Pacific theme, the issue there is that the IDs and classes in my solution are all wrong. Liquid is always the same between themes as it's a Shopify standard. For Pacific, just put this code at the bottom of theme.liquid before the closing body tag:

<script type="text/javascript">
    function wildcard(str) {
     str = str.split(' ');                // will split the string delimited by space into an array of words

     for(var i = 0; i < str.length; i++){               // str.length holds the number of occurrences of the array...
          var limit = str.length - 1; 
          if (i < limit) {
          str[i] = str[i] + "* OR";                   // adds * for wildcard to each array element
          } else if ( i == limit) {
          str[i] = str[i] + "*";
          };                       
     }
     return str.join(' ');                              //  converts the array of words back to a sentence.
}

        $('.header-search-form').submit(function () {
          
            var $searchfield = $('.header-search-input'),
                searchVal = $searchfield.val();
          
            $searchfield.val(wildcard(searchVal));

        });

    {% if template contains 'search' %}
        $('.search-form').submit(function () {
          
            var $searchfield = $('.search-input input'),
                searchVal = $searchfield.val();
          
            $searchfield.val(wildcard(searchVal));

        });
    {% endif %}
</script>

It has been updated to include the OR statements that Mohammad has requested more recently. If you want it to just be the wildcard search though let me know and I can post a simplified version. Remember to back up your theme before trying any of this stuff out!

-Britton

Britton Shopify Guru
1 Like
Shopify Partner
18 0 0

Britton, it works perfectly! Is it possible to hide all the strings that are attached to it? Such as "*" and "OR"? So it displays the search without adding visible javascript?

0 Likes
Highlighted
Shopify Staff (Retired)
Shopify Staff (Retired)
409 0 60

Hi again Mohammed,

It's not that the javascript used is bleeding through into the input field, but rather that the search function requires those characters to be present in order to change how it searches. 

It's possible to not display these extra characters though if you're willing to do some weird things to the theme. Firstly, you need to make some changes in theme.liquid. You need to find this code block:

<div style='display:none'>
      <div id='search_popup' style='padding:30px;'>
        <p class="box-title">SEARCH THIS STORE<p>
        <!-- BEGIN #subs-container -->
        <div id="subs-container" class="clearfix">
          <div id="search">
            <form action="/search" method="get">
              <input  type="text" name="q" id="q" />
            </form>
          </div>  
        </div>
      </div>
    </div>  

and change it to this:

<div style='display:none'>
      <div id='search_popup' style='padding:30px;'>
        <p class="box-title">SEARCH THIS STORE<p>
        <!-- BEGIN #subs-container -->
        <div id="subs-container" class="clearfix">
          <div id="search">
            <form action="/search" method="get">
              {% comment %} dummy input to show what is typed{% endcomment %}
              <input class="dummy" type="text" placeholder="{{ 'general.search.placeholder' | t }}" />
              {% comment %}Actual input for the form which is targeted with jQuery. Is hidden to not show special search characters{% endcomment %}
              <input type="hidden" type="text" name="q" id="q" />
            </form>
          </div>  
        </div>
      </div>
    </div>  

Then, we need to go over to search.liquid. We need to change the search results that get displayed so they don't show our weird search characters. To do that, we add this code to the very top of the file, just below the starting pagination tag:

{% capture results %}{{ 'general.search.results_for_html' | t: terms: search.terms | remove: '*' }}{% endcapture %}
{% assign results_array = results | split: ' ' %}

{% for result in results_array %}
{% unless result contains 'OR' %}
{% assign output = output | append: ' ' | append: result %}
{% endunless %}
{% endfor %}

Then, we need to change what actually gets outputted. To do that, find this line of code:

<p>{{ 'general.search.results_for_html' | t: terms: search.terms }}</p>

and replace it with this:

<p>{{ output }}</p>

Now, we need to change how the search function works on the search page itself. We are going to do that in a very similar way to the homepage search. Find this line of code in search.liquid:

<input type="text" name="q" id="q" />

and replace it with these two lines of code:

<input class="dummy" type="text" placeholder="{{ 'general.search.placeholder' | t }}" />
<input type="hidden" type="text" name="q" id="q" />

The code that we added to the bottom of theme.liquid to make the wildcard searching work in the first place now also requires a bit of an update. Change it to this:

<script type="text/javascript">
    function wildcard(str) {
     str = str.split(' ');                // will split the string delimited by space into an array of words

     for(var i = 0; i < str.length; i++){               // str.length holds the number of occurrences of the array...
          var limit = str.length - 1; 
          if (i < limit) {
          str[i] = str[i] + "* OR";                   // adds * for wildcard to each array element
          } else if ( i == limit) {
          str[i] = str[i] + "*";
          };                       
     }
     return str.join(' ');                              //  converts the array of words back to a sentence.
}

        $('#search form').submit(function () {
          
            var $searchfield = $('#search #q'),
                searchVal = $('#search .dummy').val();
          
            $searchfield.val(wildcard(searchVal));

        });

{% if template contains 'search' %}
 $('#search-bar form').submit(function () {
          
            var $searchfield = $('#search-bar #q'),
                searchVal = $('#search-bar .dummy').val();
          
            $searchfield.val(wildcard(searchVal));

        });
{% endif %}

</script>

I would also recommend adding this to the very bottom of your stylesheet.scss.liquid file in order to keep your searchfields looking good:

#search-bar .dummy {
  width: 300px;
  text-transform: uppercase;
}

#search-popup .dummy {
  text-indent: 0;
  text-align: center;
  text-transform: uppercase;
}

This was a lot of code changing so I hope it goes well! I have it working fine on my test store 

-Britton

Britton Shopify Guru
0 Likes
Shopify Partner
18 0 0

Hmm, it doesn't seem to work for me. It entirely makes the search non-functional and displays no results when making all the changes you've said above. I believe some of the classes may not be matching up correctly?

0 Likes
New Member
4 0 0

Hi Britton, i just wanna say that YOU ARE BRILLIANT! IM SO HAPPPPY. It works! Though it shows the * and OR, but it really doesnt bother me as long as it helps my customers in the search process. THANK YOU BRITTON! Made my day.

0 Likes
Tourist
10 0 2

Thank you guys for binging such great topic and my store's searching ability improves a lot!

To Mohammad & Alison,

       Britton's JS does not work for me too but I found a liquid reference way to remove the * by replacing 

{{ search.terms | escape }} 

with

{{ search.terms | remove:"*" }}

for "value" in search-bar.liquid (im using supply theme), and the result of mine is:

<input type="search" name="q" value="{{ search.terms | remove:"*" }}" placeholder="{{ 'layout.search_bar.placeholder' | t }}" aria-label="{{ 'layout.search_bar.placeholder' | t }}">

      the OR can be removed perfectly by using

{{ search.terms | remove:"*" | remove:"OR" }} 

but if the customers type something like "ORGANIC" the result would become "GANIC" since the "OR" is removed...

      So if you are not selling organic products, oranges, organs or anything with "OR" then your input terms will be fine hahaha...

thanks for great topic again

0 Likes
Tourist
8 0 2

Hi Britton

Will this work with the minimal theme?

I have read some places that I may have to remove the second searchbar, since it will remove the text and only search for "*". However, then there seems to be another a problem, because if you visit the site from a mobile or tablet, it is only using the second search bar and not topsearch bar. This wont be possible if I have removed the seachbar.

Hope that you or somebody else can help.

Thanks.

-Joachim

0 Likes
Shopify Partner
2 0 0

Instead of placing the code in two places you can just add the following to the bottom of theme.liquid:

<script type="text/javascript">
    function wildcard(str) {
		str = str.split(' ');                	// will split the string delimited by space into an array of words

     	for(var i = 0; i < str.length; i++){               // str.length holds the number of occurrences of the array...
          var limit = str.length - 1; 
          if (i < limit) {
          	str[i] = "*" + str[i] + "* OR";                   // adds * for wildcard to each array element
          } else if ( i == limit) {
          	str[i] = "*" + str[i] + "*";
          };                       
     	}
      
     
     	return str.join(' ');                   //  converts the array of words back to a sentence.
	}

  	$("form.search-bar").submit(function (event) {
         
   		var $searchfield = $( event.target ).children("input[name='q']");
          	searchVal = $searchfield.val();
      
      	$searchfield.val(wildcard(searchVal));

    });
  </script>

Then to remove the wildcards (*) and the OR's change your search input box (in search-box.liquid) to:

<input type="search" name="q" value="{{ search.terms | remove:"*" | replace:" OR ", " "}}" placeholder="{{ 'layout.search_bar.placeholder' | t }}" aria-label="{{ 'layout.search_bar.placeholder' | t }}">
  

Hope that helps,

Matt Cannon
www.tiregeek.com 

0 Likes
New Member
2 0 1

Hi, I've tried implementing a few of the solutions to this issue that have been posted on these forums and none of them seem to do anything. I read about having to remove a second search bar but I never had one even appear and the search function is not returning any results that would be expected if the wildcard was working. Is this likely to be a problem with variable naming?

Thanks

0 Likes