Reputation: 1572
Is it possible to get a reference to a Bootstrap 5 bootstrap.Modal
via IJSRuntime and save a reference to that instance to later use it?
Example:
I can show a modal with this method:
await _jsRuntime.InvokeVoidAsync("eval", $"new bootstrap.Modal(document.getElementById('myId')).show()");
But I can't hide it the same way because I need to store a reference to the new bootstrap.Modal
creation. How can I do this dynamically (I have a bootstrap modal component) without having to write javascript? Is there some way we can save variables and reference them later through the IJSRuntime?
Upvotes: 3
Views: 1674
Reputation: 1572
After a lot of searching I found that eval
is never the solution. I am not a JavaScript dev but I got this together:
BootstrapModal.razor
@inject IJSRuntime _jsRuntime;
<div class="modal fade" id="@Id" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
@ChildContent
</div>
</div>
</div>
@code {
[Parameter]
public string Id { get; set; }
[Parameter]
public RenderFragment ChildContent { get; set; }
public dynamic Parameter { get; private set; }
protected override void OnInitialized()
{
if (string.IsNullOrEmpty(Id))
{
Id = Guid.NewGuid().ToString();
}
}
public async Task Show(dynamic parameter = null)
{
Parameter = parameter;
await _jsRuntime.InvokeVoidAsync("BootstrapModal.ShowModal", Id);
}
public async Task Hide()
{
await _jsRuntime.InvokeVoidAsync("BootstrapModal.HideModal");
}
}
BootstrapModalInterop.js
window.BootstrapModal = {};
window.BootstrapModal.OpenedModal = null;
window.BootstrapModal.ShowModal = (id) => {
if (window.BootstrapModal.OpenedModal != null) {
window.BootstrapModal.HideModal();
}
window.BootstrapModal.OpenedModal = new bootstrap.Modal(document.getElementById(id));
window.BootstrapModal.OpenedModal.show();
}
window.BootstrapModal.HideModal = () => {
if (window.BootstrapModal.OpenedModal == null) {
return;
}
window.BootstrapModal.OpenedModal.hide();
window.BootstrapModal.OpenedModal = null;
}
Make sure you reference the BootstrapModalInterop.js
file from your hosts file.
You can now natively open and close the modal from blazor code.
Example usage:
...
<button class="btn btn-danger" @onclick="async () => await _deleteModal.Show(discountCode.Id)"><i class="fas fa-trash"></i></button>
...
<BootstrapModal @ref="_deleteModal">
<div class="modal-header">
<h5 class="modal-title">
Delete Discount Code
</h5>
</div>
<div class="modal-body">
<p>
Are you sure that you want to delete this discount code? This cannot be undone!
</p>
</div>
<div class="modal-footer">
<button @onclick="async () => await _deleteModal.Hide()" class="btn btn-secondary">Close</button>
<button @onclick="async () => await Delete((int)_deleteModal.Parameter)" class="btn btn-outline-danger">Delete</button>
</div>
</BootstrapModal>
@code
{
private BootstrapModal _deleteModal;
}
The parameter attribute is optional but I used it to parse the ID of the item I want to delete with it. Later I can get this ID using (int)_deleteModal.Parameter
. I chose a dynamic
type so I can parse in whatever.
Upvotes: 5