In my Blazor Server app, I can't get the default Bootstrap dropdown behavior to work: I need the dropdown menu to disappear when I click anywhere outside the menu div.
I tried @onfocusout but if I click inside of one of the form inputs and then click the menu div again, the menu div disappears. I want it to persist in this use case. I just want to have the dropdown menu disappear when I click anywhere other than the dropdown button or its menu & corresponding menu contents.
My code is below - I have removed some form elements to make it easier to skim.
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle data-toggle="dropdown" type="button"
id="userLoginMenuButton" @onclick="(() => this.showUserMenu=!this.showUserMenu)">
<span>Click me!</span>
</button>
<div class="userLoginMenu dropdown-menu dropdown-menu-right @(showUserMenu? "show":"")"
@onfocusout="() => this.showUserMenu = false" aria-labelledby="userLoginMenuButton">
<form class="px-4 py-3">
<div class="form-group">
<label for="exampleDropdownFormEmail1">Email address</label>
<input type="email" class="form-control" id="exampleDropdownFormEmail1" placeholder="[email protected]">
</div>
<button type="submit" class="btn btn-primary">Sign in</button>
</form>
<div class="dropdown-divider"></div>
<AuthorizeView>
<Authorized Context="Auth">
<a class="dropdown-item" href="" @onclick="(() => Logout())">Logout</a>
</Authorized>
<NotAuthorized>
<a class="dropdown-item" href="" @onclick="(() => Login())">Login</a>
</NotAuthorized>
</AuthorizeView>
</div>
</div>
@code{
private bool showUserMenu = false;
public async Task Logout()
{
await ((CustomAuthenticationStateProvider)AuthenticationStateProvider).MarkUserAsLoggedOut();
NavigationManager.NavigateTo("");
}
private void Login()
{
NavigationManager.NavigateTo("/");
}
}
You have to add an event @onfocusout to your DropDown button, this event will trigger a method we will name it OutFocus.
Because it triggers before the DropDown-item Click Event, we add a delay.
On Component:
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" type="button" aria-haspopup="true" aria-expanded="false"
@onclick="e => this.show = !this.show"
@onfocusout="OutFocus">
DropDownText
</button>
<div class="dropdown-menu pre-scrollable @(show? "show":"")" >
<button class="dropdown-item" type="button" >
Item1
</button>
<button class="dropdown-item" type="button" >
Item2
</button>
<button class="dropdown-item" type="button" >
Item3
</button>
</div>
</div>
On code:
@code {
private bool show = false;
private async Task OutFocus() {
await Task.Delay(200);
this.show = false;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With