Mobile Navigation Question

Anyone know how to get the menu to stop hiding each time I click a dynamic menu that I setup using tutorials I found on the forums. It wasn’t a big deal before when I only had single menu clicks but now it doesn’t really work well cause it hides every time you click the top link that opens up my nav menu.

Ah, yes - the default behaviour of the sidebar menu is to hide when you click something in it!

This is controlled by the Javascript in the theme. I believe you’ve switched to the up-to-date Material Design, so if you look at your standard-page.html you should see something like:

  $('.left-nav').off('click').on('click', 'a, button', function() {
    if ($('.nav-shield').is(":visible")) {
      $('.nav-shield').trigger('click');
    }
  });

You can delete that whole block to prevent the auto-hiding behaviour. (Or, you can use roles to select which Links and Buttons do and don’t trigger an auto-hide of the mobile sidebar.)

1 Like

Awesome thanks, I guess the easiest option will be to maybe on mobile either just set it to always be there or maybe to only hide it after they click a sub menu so that way the menu stays up until they click a sub menu. I would image that is doable based on what you just showed me there. I guess I could somehow set that up as a component or some way to trigger when my submenus are clicked to hide the menu right?

Yeah; here’s some JS code that hides the sidebar only if it’s in mobile mode:

  function hideSidebarIfModal() {
    if ($('.nav-shield').is(':visible')) {
      hideSidebar();
    }
  }

Then, when those links are clicked, you can do this in your (Python) event handler:

self.call_js('hideSidebarIfModal')
1 Like

Great thanks. I’m trying to work on making the mobile experience the best I can.

I might be doing something wrong but even when calling this function when my top menu is clicked it still hides the menu, do I need to remove any of that other JS that is there for hiding the menu? I can see in the supplied js you are using the .nav-shield to check and see if its visible I guess to know we are mobile?

Thanks

Yes, you’ll need to remove the code I pointed out earlier in this thread:

So I have something a bit different in my setup, I haven’t succesfully been able yet to get my template moved over to the new Material UI design, I have a open thread about it.

In my dashboard.html file which is my main html form I have this:

<script>
function hideSidebarIfModal() {
    if ($('.nav-shield').is(':visible')) {
      hideSidebar();
    }
  }   
function toggleSidebar() {
    var s = $('.sidebar');
    if (!s.is(':hidden')) {
        $('.sidebar-click-guard').hide();
        s.addClass('floating').animate({left: -s.width()}, {complete: function() { s.hide(); }});
    } else {
        $('.sidebar-click-guard').show();
        s.show().addClass('floating').css('left', '-100%').css('left', -s.width())
            .animate({left: 0}, {complete: function() { s.removeClass('floating'); }});
    }
}

$(function() {
    $('.sidebar').on("click", function() {
        if (window.innerWidth <= 767) {
            toggleSidebar();
        }
    });
    $('.sidebar-click-guard').on("click", toggleSidebar);
}) 
</script>

I have added in what you gave me but also have the other 2 scripts there, if I remove those then the mobile nav menu breaks.

In my standard-page.html file I have this:

  function hideSidebar() {
    var ln = $('.structure > .nav-holder > .left-nav');
    ln.animate({left: -ln.outerWidth()}, function() {
      ln.removeClass("in-transition shown").addClass("hidden");
    $('.nav-shield').removeClass("shown");
    });
  }
  function showSidebar() {
    var ln = $('.structure > .nav-holder > .left-nav');
    $('.nav-shield').addClass("shown");
    ln.addClass("shown").removeClass("hidden").css({left: "-100%"}).css({left: -ln.outerWidth()}).animate({left: 0}, function() {
      ln.removeClass("in-transition");
    });
  }
  $('.sidebar-toggle, .nav-shield').off('click').on('click', function() {
    var ln = $('.structure > .nav-holder > .left-nav');
    if (ln.is(":visible") || $('.nav-shield').is(".shown")) {
      hideSidebar();
    } else if(!ln.is(":empty")) {
      showSidebar();
    }
  });
  $('.left-nav').off('click').on('click', 'a, button', function() {
    if ($('.nav-shield').is(":visible")) {
      $('.nav-shield').trigger('click');
    }
  });

Removing this seems to have no affect, tell me what I’m doing wrong :frowning:

I figured it out, I had to remove the below from the dashboard.html file, thanks for the help.

$(function() {
    $('.sidebar').on("click", function() {
        if (window.innerWidth <= 767) {
            toggleSidebar();
        }
    });
    $('.sidebar-click-guard').on("click", toggleSidebar);

@meredydd is there any special code or setting in anvil to use when the site is either mobile or something similar?
Now with the way I have it setup it behaves the way I want on mobile but also does it on desktop version so I’m wondering if I’m missing something to tell it to only do this on a mobile site or maybe I screwed something up which is possible I’ve been trying to figure it out.

The way I have it setup atm is I’m hiding the menu only after someone clicks the sub menu and if they click the menu it doesn’t run the function to close the menu.

Hey coming back to this I like your idea of roles, how might I accomplish that? I’m still kind of new to roles.

Thanks

In @meredydd’s example

  $('.left-nav').off('click').on('click', 'a, button', function() {
    if ($('.nav-shield').is(":visible")) {
      $('.nav-shield').trigger('click');
    }
  });

You would replace the 'a, button' with '.anvil-role-foo', create a Role named foo and assign that Role to any Links or Buttons in the sidebar you wanted to enable the auto-hide behaviour for.

To explain: The 'a, button' argument is a JQuery selector selecting the DOM elements to bind this event to. Assigning a Role to a component gives it the anvil-role-foo class (assuming the Role is called foo).

2 Likes

Thanks for the clarification.