Skip to content

Commit b644c4b

Browse files
authored
Dropdown does not close when click outside (#1251)
* #1250: Refactor dropdown handling to target toggle elements Update dropdown JS logic to operate on the child element with data-bs-toggle="dropdown" when present, ensuring Bootstrap methods and event listeners are attached to the correct toggle button. Falls back to the parent if no toggle is found, improving alignment with Bootstrap's expected usage. * #1250: Refactor dropdown demos and update ButtonGroup logic - Group dropdowns in demos using btn-group with spacing for better layout and clarity. - Split Dropdown_Demo_14_Methods into separate sections for Show/Hide and Toggle, each with its own dropdown instance. - Apply ButtonGroup class in Dropdown.razor.cs only when Split is true, altering default grouping behavior.
1 parent d4321fc commit b644c4b

File tree

4 files changed

+95
-61
lines changed

4 files changed

+95
-61
lines changed
Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,37 @@
1-
<Dropdown Color="DropdownColor.Secondary" AutoClose="true">
2-
<DropdownToggleButton>Default dropdown</DropdownToggleButton>
3-
<DropdownMenu>
4-
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
5-
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
6-
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
7-
</DropdownMenu>
8-
</Dropdown>
1+
<div class="btn-group gap-3">
2+
<Dropdown Color="DropdownColor.Secondary" AutoClose="true">
3+
<DropdownToggleButton>Default dropdown</DropdownToggleButton>
4+
<DropdownMenu>
5+
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
6+
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
7+
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
8+
</DropdownMenu>
9+
</Dropdown>
910

10-
<Dropdown Color="DropdownColor.Secondary" AutoClose="true" AutoCloseBehavior="DropdownAutoCloseBehavior.Outside">
11-
<DropdownToggleButton>Clickable outside</DropdownToggleButton>
12-
<DropdownMenu>
13-
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
14-
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
15-
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
16-
</DropdownMenu>
17-
</Dropdown>
11+
<Dropdown Color="DropdownColor.Secondary" AutoClose="true" AutoCloseBehavior="DropdownAutoCloseBehavior.Outside">
12+
<DropdownToggleButton>Clickable outside</DropdownToggleButton>
13+
<DropdownMenu>
14+
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
15+
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
16+
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
17+
</DropdownMenu>
18+
</Dropdown>
1819

19-
<Dropdown Color="DropdownColor.Secondary" AutoClose="true" AutoCloseBehavior="DropdownAutoCloseBehavior.Inside">
20-
<DropdownToggleButton>Clickable inside</DropdownToggleButton>
21-
<DropdownMenu>
22-
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
23-
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
24-
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
25-
</DropdownMenu>
26-
</Dropdown>
20+
<Dropdown Color="DropdownColor.Secondary" AutoClose="true" AutoCloseBehavior="DropdownAutoCloseBehavior.Inside">
21+
<DropdownToggleButton>Clickable inside</DropdownToggleButton>
22+
<DropdownMenu>
23+
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
24+
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
25+
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
26+
</DropdownMenu>
27+
</Dropdown>
2728

28-
<Dropdown Color="DropdownColor.Secondary" AutoClose="false">
29-
<DropdownToggleButton>Manual close</DropdownToggleButton>
30-
<DropdownMenu>
31-
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
32-
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
33-
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
34-
</DropdownMenu>
35-
</Dropdown>
29+
<Dropdown Color="DropdownColor.Secondary" AutoClose="false">
30+
<DropdownToggleButton>Manual close</DropdownToggleButton>
31+
<DropdownMenu>
32+
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
33+
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
34+
<DropdownItem To="#" Type="DropdownItemType.Link">Menu item</DropdownItem>
35+
</DropdownMenu>
36+
</Dropdown>
37+
</div>
Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,40 @@
1-
<Dropdown @ref="dropdown1" Color="DropdownColor.Secondary">
2-
<DropdownToggleButton>Dropdown button</DropdownToggleButton>
3-
<DropdownMenu>
4-
<DropdownItem To="#" Type="DropdownItemType.Link">Action</DropdownItem>
5-
<DropdownItem To="#" Type="DropdownItemType.Link">Another action</DropdownItem>
6-
<DropdownItem To="#" Type="DropdownItemType.Link">Something else here</DropdownItem>
7-
</DropdownMenu>
8-
</Dropdown>
1+
<div class="mb-3">
2+
<div class="btn-group gap-3">
3+
<Dropdown @ref="dropdown1" Color="DropdownColor.Secondary">
4+
<DropdownToggleButton>Dropdown button</DropdownToggleButton>
5+
<DropdownMenu>
6+
<DropdownItem To="#" Type="DropdownItemType.Link">Action</DropdownItem>
7+
<DropdownItem To="#" Type="DropdownItemType.Link">Another action</DropdownItem>
8+
<DropdownItem To="#" Type="DropdownItemType.Link">Something else here</DropdownItem>
9+
</DropdownMenu>
10+
</Dropdown>
911

10-
<Button Color="ButtonColor.Primary" @onclick="ShowAsync">Show</Button>
11-
<Button Color="ButtonColor.Primary" @onclick="HideAsync">Hide</Button>
12-
<Button Color="ButtonColor.Primary" @onclick="ToggleAsync">Toggle</Button>
12+
<Button Color="ButtonColor.Primary" @onclick="ShowAsync">Show</Button>
13+
<Button Color="ButtonColor.Primary" @onclick="HideAsync">Hide</Button>
14+
</div>
15+
</div>
1316

14-
@code{
17+
<div>
18+
<div class="btn-group gap-3">
19+
<Dropdown @ref="dropdown2" Color="DropdownColor.Secondary" AutoClose="false">
20+
<DropdownToggleButton>Dropdown button</DropdownToggleButton>
21+
<DropdownMenu>
22+
<DropdownItem To="#" Type="DropdownItemType.Link">Action</DropdownItem>
23+
<DropdownItem To="#" Type="DropdownItemType.Link">Another action</DropdownItem>
24+
<DropdownItem To="#" Type="DropdownItemType.Link">Something else here</DropdownItem>
25+
</DropdownMenu>
26+
</Dropdown>
27+
28+
<Button Color="ButtonColor.Primary" @onclick="ToggleAsync">Toggle</Button>
29+
</div>
30+
</div>
31+
32+
@code {
1533
private Dropdown dropdown1 = default!;
34+
private Dropdown dropdown2 = default!;
1635

1736
private async Task ShowAsync() => await dropdown1.ShowAsync();
1837
private async Task HideAsync() => await dropdown1.HideAsync();
19-
private async Task ToggleAsync() => await dropdown1.ToggleAsync();
38+
39+
private async Task ToggleAsync() => await dropdown2.ToggleAsync();
2040
}

blazorbootstrap/Components/Dropdown/Dropdown.razor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ protected override void OnInitialized()
8989

9090
protected override string? ClassNames =>
9191
BuildClassNames(Class,
92-
(BootstrapClass.ButtonGroup, true),
92+
(BootstrapClass.ButtonGroup, Split),
9393
(Direction.ToDropdownDirectionClass(), true));
9494

9595
/// <summary>

blazorbootstrap/wwwroot/blazor.bootstrap.js

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -399,48 +399,60 @@ window.blazorBootstrap = {
399399
dropdown: {
400400
dispose: (elementId) => {
401401
let dropdownEl = document.getElementById(elementId);
402-
if (dropdownEl != null)
403-
bootstrap?.Dropdown?.getOrCreateInstance(dropdownEl)?.dispose();
402+
if (dropdownEl != null) {
403+
let toggleEl = dropdownEl.querySelector('[data-bs-toggle="dropdown"]') ?? dropdownEl;
404+
bootstrap?.Dropdown?.getOrCreateInstance(toggleEl)?.dispose();
405+
}
404406
},
405407
hide: (elementId) => {
406408
let dropdownEl = document.getElementById(elementId);
407-
if (dropdownEl != null)
408-
bootstrap?.Dropdown?.getOrCreateInstance(dropdownEl)?.hide();
409+
if (dropdownEl != null) {
410+
let toggleEl = dropdownEl.querySelector('[data-bs-toggle="dropdown"]') ?? dropdownEl;
411+
bootstrap?.Dropdown?.getOrCreateInstance(toggleEl)?.hide();
412+
}
409413
},
410414
initialize: (elementId, dotNetHelper) => {
411415
let dropdownEl = document.getElementById(elementId);
412416
if (dropdownEl == null)
413417
return;
414418

415-
dropdownEl.addEventListener('hide.bs.dropdown', function () {
419+
let toggleEl = dropdownEl.querySelector('[data-bs-toggle="dropdown"]') ?? dropdownEl;
420+
421+
toggleEl.addEventListener('hide.bs.dropdown', function () {
416422
dotNetHelper.invokeMethodAsync('bsHideDropdown');
417423
});
418-
dropdownEl.addEventListener('hidden.bs.dropdown', function () {
424+
toggleEl.addEventListener('hidden.bs.dropdown', function () {
419425
dotNetHelper.invokeMethodAsync('bsHiddenDropdown');
420426
});
421-
dropdownEl.addEventListener('show.bs.dropdown', function () {
427+
toggleEl.addEventListener('show.bs.dropdown', function () {
422428
dotNetHelper.invokeMethodAsync('bsShowDropdown');
423429
});
424-
dropdownEl.addEventListener('shown.bs.dropdown', function () {
430+
toggleEl.addEventListener('shown.bs.dropdown', function () {
425431
dotNetHelper.invokeMethodAsync('bsShownDropdown');
426432
});
427433

428-
bootstrap?.Dropdown?.getOrCreateInstance(dropdownEl);
434+
bootstrap?.Dropdown?.getOrCreateInstance(toggleEl);
429435
},
430436
show: (elementId) => {
431437
let dropdownEl = document.getElementById(elementId);
432-
if (dropdownEl != null)
433-
bootstrap?.Dropdown?.getOrCreateInstance(dropdownEl)?.show();
438+
if (dropdownEl != null) {
439+
let toggleEl = dropdownEl.querySelector('[data-bs-toggle="dropdown"]') ?? dropdownEl;
440+
bootstrap?.Dropdown?.getOrCreateInstance(toggleEl)?.show();
441+
}
434442
},
435443
toggle: (elementId) => {
436444
let dropdownEl = document.getElementById(elementId);
437-
if (dropdownEl != null)
438-
bootstrap?.Dropdown?.getOrCreateInstance(dropdownEl)?.toggle();
445+
if (dropdownEl != null) {
446+
let toggleEl = dropdownEl.querySelector('[data-bs-toggle="dropdown"]') ?? dropdownEl;
447+
bootstrap?.Dropdown?.getOrCreateInstance(toggleEl)?.toggle();
448+
}
439449
},
440450
update: (elementId) => {
441451
let dropdownEl = document.getElementById(elementId);
442-
if (dropdownEl != null)
443-
bootstrap?.Dropdown?.getOrCreateInstance(dropdownEl)?.update();
452+
if (dropdownEl != null) {
453+
let toggleEl = dropdownEl.querySelector('[data-bs-toggle="dropdown"]') ?? dropdownEl;
454+
bootstrap?.Dropdown?.getOrCreateInstance(toggleEl)?.update();
455+
}
444456
}
445457
},
446458
googlemaps: {

0 commit comments

Comments
 (0)