Search code examples
javascriptjquerycssmaterialize

Prevent dropdown closing on pressing Tab in Materialize CSS menu


General Info
Working on a menu with an integrated register / login form using a dropdown trigger.

The problem
Matrialize CSS has a default option to disable automatic closing of the menu: closeOnClick: false. This works perfectly fine. The problem is that it still closes the menu when Tab is pressed. Many users (including me) press Tab to quickly navigate through webforms. So I'm trying to prevent this.

Solutions I've tried
Following the advise in this closely related question: Prevent materializecss dropdown to close when clicking inside it I've tried something similar with keydown, keyup and keypress events. None had any effect:

$('.dropdown-button + .dropdown-content').on('keyup', function(event) {
    event.stopPropagation();
});

Acceptable solutions
Solutions are acceptable using html, css, javascript and / or jQuery.

MCVE
Clicking in the dropdown form works fine. Press Tab and it'll close the menu.

$(document).ready(function(){
  $(".dropdown-trigger").dropdown({
	  alignment: 'left',
	  constrainWidth: false,
	  coverTrigger: false,
	  closeOnClick: false,
	  hover: false
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

<ul id="usermenu" class="dropdown-content dropdown-menu">
	<li>
		<div class="row no-bottom">
			<div id="login" class="col s12">
				<form id="form-login">
					<div class="row">
						<div class="col s12">
							<label>Username</label>
							<input type="text" class="browser-default form-input" placeholder="Username" id="username"/>
						</div>
					</div>
					<div class="row no-bottom">
						<div class="col s12">
							<label>Password</label>
							<input type="password" class="browser-default form-input" placeholder="Password" id="password"/>
						</div>
					</div>
				</form>
			</div>
		</div>
	</li>
</ul>
<nav class="nav-center grey darken-3">
	<div class="nav-wrapper">
		<a href="#" data-target="mobile-menu" class="sidenav-trigger hide-on-med-and-up"><i class="material-icons">menu</i></a>
		<ul id="nav-mobile" class="hide-on-small-only">
			<li><a class="dropdown-trigger" href="#" data-target="usermenu">Login<i class="material-icons right">arrow_drop_down</i></a></li>
		</ul>
	</div>
</nav>


Solution

  • I did not realize that event.stopPropagation(); does not prevent other handlers on the same element from running. The solution was quite simple after that:

    $('#form-login').on('keydown', function(event) {
        event.stopPropagation();
    });