How To Add Always Visible Search Bar [Horizon Theme Shopify]

Always Visible Search Bar Shopify

Navigate to Customize > Header Section, then insert the following code into the Custom Liquid.

<style>

.search-modal__button {
  display:none;
}
/* REMOVE THIS LINE TO HIDE ON DESKTOP

@media (min-width: 769px){
predictive-search-component{
  display: none !important;
} }


 @media (max-width: 768px){
.search-modal__button {
    display: none !important;
} } 

*/

</style>


  <predictive-search-component
  class="add-one predictive-search{% if class != blank %} {{ class | strip }}{% endif %}{% if search_position != blank %} predictive-search--{{ search_position }}{% endif %}"
  style="--product-corner-radius: {{ settings.product_corner_radius | default: 8 | append: 'px' }}; --card-corner-radius: {{ settings.card_corner_radius | default: 8 | append: 'px' }};{% if settings.card_title_case == 'uppercase' %} --title-case: uppercase;{% endif %}"
  data-section-id="predictive-search"
  data-search-position="{{ search_position }}"
  data-testid="{{ search_test_id }}"
  data-active-color-scheme="{{ settings.popover_color_scheme }}"
  role="search"
  aria-label="{{ 'content.search_input_label' | t }}"
>
  <form
    action="{{ routes.search_url }}"
    method="get"
    role="search"
    class="predictive-search-form"
    ref="form"
    on:keydown="/onSearchKeyDown"
  >
    <div class="predictive-search-form__header" style="position: relative;">
      <div class="predictive-search-form__header-inner">
        <label
          for="{{ input_id | default: 'Search' }}"
          class="visually-hidden"
        >
          {{- 'content.search_input_label' | t -}}
        </label>
        <input
          class="search-input"
          id="{{ input_id | default: 'Search' }}"
          type="search"
          name="q"
          role="combobox"
          aria-expanded="false"
          aria-owns="predictive-search-results"
          aria-controls="predictive-search-results"
          aria-haspopup="listbox"
          aria-autocomplete="list"
          autocomplete="off"
          placeholder="{{ 'content.search_input_placeholder' | t }}"
          ref="searchInput"
          on:input="/search"
          on:keydown="/onSearchKeyDown"
          on:focus="/expandSearch"
        >
        <input
          name="options[prefix]"
          type="hidden"
          value="last"
        >

        <span class="svg-wrapper predictive-search__icon">
          {{ 'icon-search.svg' | inline_asset_content }}
        </span>
        <button
          type="button"
          class="button-unstyled predictive-search__reset-button"
          aria-label="{{ 'accessibility.reset_search' | t }}"
          ref="resetButton"
          hidden
          onclick="
            document.querySelector('#predictive-search-results')?.style.setProperty('display', 'none');
            this.closest('form').querySelector('.search-input').value = '';
          "
        >
          <span class="svg-wrapper predictive-search__reset-button-icon">
            {{ 'icon-reset.svg' | inline_asset_content }}
          </span>
          <span class="predictive-search__reset-button-text">{{ 'actions.clear' | t }}</span>
        </button>
      </div>
      <button
        type="button"
        class="button predictive-search__close-modal-button"
        aria-label="{{ 'accessibility.close_dialog' | t }}"
        on:click="dialog-component/closeDialog"
        ref="closeModalButton"
        style="position: absolute; top: 10px; right: 10px; z-index: 10;"
      >
        <span class="svg-wrapper" style="font-size: 20px;">×</span>
      </button>
    </div>

    <div class="predictive-search-form__content-wrapper">
      <div
        class="predictive-search-form__content"
        tabindex="-1"
        id="predictive-search-results"
        ref="predictiveSearchResults"
        on:click="/handleModalClick"
      >
        {% render 'predictive-search-empty-state', products_test_id: products_test_id %}
      </div>

      <div class="predictive-search-form__footer">
        <button
          class="button button-primary predictive-search__search-button"
          ref="viewAllButton"
        >
          {{ 'content.search_results_view_all' | t }}
        </button>
      </div>
    </div>
  </form>
</predictive-search-component>



<script>
document.addEventListener('DOMContentLoaded', function() {
  const searchComponent = document.querySelector('predictive-search-component');
  const searchResults = document.querySelector('#predictive-search-results');
  const searchInput = document.querySelector('.search-input');
  
  if (searchComponent && searchResults) {
    let isSearchActive = false;
    
    // Handle click outside to close search
    document.addEventListener('click', function(event) {
      // Check if the search results are visible and click was outside
      if (isSearchActive && !searchComponent.contains(event.target)) {
        // Click was outside the search component, close it
        searchResults.style.display = 'none';
        isSearchActive = false;
        if (searchInput) {
          searchInput.setAttribute('aria-expanded', 'false');
        }
      }
    });
    
    // Handle search input focus/click to show results
    if (searchInput) {
      searchInput.addEventListener('focus', function() {
        if (this.value.length > 0 || searchResults.innerHTML.trim() !== '') {
          searchResults.style.display = 'block';
          isSearchActive = true;
          this.setAttribute('aria-expanded', 'true');
        }
      });
      
      searchInput.addEventListener('input', function() {
        if (this.value.length > 0) {
          searchResults.style.display = 'block';
          isSearchActive = true;
          this.setAttribute('aria-expanded', 'true');
        }
      });
      
      // Also handle click on search input
      searchInput.addEventListener('click', function() {
        if (searchResults.style.display === 'none' || !isSearchActive) {
          searchResults.style.display = 'block';
          isSearchActive = true;
          this.setAttribute('aria-expanded', 'true');
        }
      });
    }
    
    // Handle escape key to close search
    document.addEventListener('keydown', function(event) {
      if (event.key === 'Escape' && isSearchActive) {
        searchResults.style.display = 'none';
        isSearchActive = false;
        if (searchInput) {
          searchInput.setAttribute('aria-expanded', 'false');
          searchInput.blur(); // Remove focus from input
        }
      }
    });
    
    // Prevent clicks inside the search component from bubbling up
    searchComponent.addEventListener('click', function(event) {
      event.stopPropagation();
    });
    
    // Monitor when search results are shown by the theme's original functionality
    const observer = new MutationObserver(function(mutations) {
      mutations.forEach(function(mutation) {
        if (mutation.target === searchResults && mutation.type === 'attributes' && mutation.attributeName === 'style') {
          const display = window.getComputedStyle(searchResults).display;
          if (display !== 'none') {
            isSearchActive = true;
          }
        }
      });
    });
    
    observer.observe(searchResults, {
      attributes: true,
      attributeFilter: ['style']
    });
  }
});
</script>
Vote Here

About

Leave a Comment

Your email address will not be published. Required fields are marked *