Hide grandchild navigation item when there's no product available or up for sale in collection

Solved
New Member
2 1 0

Hello,

 

I'm new to Shopify and couldn't find the answer to my question on this forum or elsewhere despite searching for hours. Hopefully this isn't too complex to achieve.

 

My use case is this (screenshot below):

 

  • I have a dropdown menu with a child / grandchild hierarchy
  • The child navigation items are fixed and are fine as is
  • Each grandchild navigation item links to a dynamic Collection (e.g. Product is of type X)
  • Any of those collections might or might not have at least one product
  • Any of those collections might or might not have at least one product up for sale

menu-hierarchy.png

My request is thus this one: in the instance when there's no product up for sale or no product at all if any of the grandchild collections, I don't want the corresponding granchild menu item to show up at all. IMO this provides for a better user experience and also prevents any clutter.

 

I'm using the Minimal theme and understand there might be 2 files involved with any change:

 

  • snippets/mobile-nav.liquid
  • snippets/site-nav.liquid

Here's the content of site-nav.liquid in case this is helpful:

 

<nav>
  <ul class="site-nav" id="AccessibleNav">
    {% for link in site-nav.links %}
      {% if link.links != blank %}
      {% assign parent_index = forloop.index %}
        <li 
          class="site-nav--has-dropdown {% if link.active %}site-nav--active{% endif %}"
          aria-haspopup="true">
          <a
            href="{{ link.url }}"
            class="site-nav__link"
            data-meganav-type="parent"
            aria-controls="MenuParent-{{ parent_index }}"
            aria-expanded="false"
            {% unless template.name == 'index' %}{% if link.active %}aria-current="page"{% endif %}{% endunless%}>
              {{ link.title | escape }}
              <span class="icon icon-arrow-down" aria-hidden="true"></span>
          </a>
          <ul
            id="MenuParent-{{ parent_index }}"
            class="site-nav__dropdown {% if link.levels == 2 %}site-nav--has-grandchildren{% endif %}"
            data-meganav-dropdown>
            {% for childlink in link.links %}
              {% if childlink.links != blank %}
              {% assign child_index = forloop.index %}
                <li
                  class="site-nav--has-dropdown site-nav--has-dropdown-grandchild {% if childlink.active %}site-nav--active{% endif %}"
                  aria-haspopup="true">
                  <a
                    href="{{ childlink.url }}"
                    class="site-nav__link"
                    aria-controls="MenuChildren-{{ parent_index }}-{{ child_index }}"
                    data-meganav-type="parent"
                    {% unless template.name == 'index' %}{% if childlink.active %}aria-current="page"{% endif %}{% endunless%}
                    tabindex="-1">
                      {{ childlink.title | escape }}
                      <span class="icon icon-arrow-down" aria-hidden="true"></span>
                  </a>
                  <ul
                    id="MenuChildren-{{ parent_index }}-{{ child_index }}"
                    class="site-nav__dropdown-grandchild"
                    data-meganav-dropdown>
                    {% for grandchildlink in childlink.links %}
                      <li{% if grandchildlink.active %} class="site-nav--active"{% endif %}>
                        <a 
                          href="{{ grandchildlink.url }}"
                          class="site-nav__link"
                          data-meganav-type="child"
                          {% unless template.name == 'index' %}{% if grandchildlink.active %}aria-current="page"{% endif %}{% endunless %}
                          tabindex="-1">
                            {{ grandchildlink.title | escape }}
                          </a>
                      </li>
                    {% endfor %}
                  </ul>
                </li>
              {% else %}
                <li{% if childlink.active %} class="site-nav--active"{% endif %}>
                  <a
                    href="{{ childlink.url }}"
                    class="site-nav__link"
                    data-meganav-type="child"
                    {% if childlink.active %}aria-current="page"{% endif %}
                    tabindex="-1">
                      {{ childlink.title | escape }}
                  </a>
                </li>
              {% endif %}
            {% endfor %}
          </ul>
        </li>
      {% else %}
        <li{% if link.active %} class="site-nav--active"{% endif %}>
          <a
            href="{{ link.url }}"
            class="site-nav__link"
            data-meganav-type="child"
            {% unless template.name == 'index' %}{% if link.active %}aria-current="page"{% endif %}{% endunless%}>
              {{ link.title | escape }}
          </a>
        </li>
      {% endif %}
    {% endfor %}
  </ul>
</nav>

 

l hope you can help and am happy to provide you with any clarification you might require.

 

Thanks!

0 Likes

Success.

New Member
2 1 0

Here's the solution I decided to go with. It's not exactly perfect, but works well enough for my immediate needs:

 

  • Create a new top menu item, call it e.g. DISABLED
  • Put menu items without any product or any item up for sale there
  • Ensure the new menu item is invisible on the frontend

Here's how I achieved this:

 

1. With the Minimal theme, under site-nav.liquid

 

{% for childlink in link.links %}
  {% if childlink.title == 'DISABLED' %}
    <style>
      #MenuParent-1>:last-child {display: none;}
    </style>
  {% endif %}
...

And under mobile-nav.liquid

 

{% for childlink in link.links %}
  {% if childlink.title == 'DISABLED' %}
    <style>
      #MobileNav-Parent-1>:last-child {display: none;}
    </style>
  {% endif %}
...

The idea here is we're injecting the above code when looping over the childlink links. Then we:

  • Check if the title is indeed exactly DISABLED
  • Then we inject a CSS style on the fly
  • We narrow the CSS condition to the last child element of the exact desktop/mobile menu ID
  • We then hide it from rendering with display: none;

 

0 Likes