es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

El diálogo modal de Blazor no tiene el enfoque.

Tengo un diálogo personalizado en Blazor. Básicamente funciona bien, pero tiene algunos fallos:

  1. Cuando se presiona la tecla Tab en el teclado, el enfoque salta entre los controles de la página subyacente y no dentro del diálogo.
    1. Cuando se hace clic en Esc o Enter en el teclado, el evento keydown no se activa.

¿Qué falta?


<div class="custom-modal-overlay fade @showClass" style="@style" aria-modal="@Show" aria-hidden="@(!Show)" aria-labelledby="Dialog" @onclick="HandleCancel" @onkeydown="OverlayKeyDown"> <div class="custom-modal-dialog" @onclick:stopPropagation="true"> <div class="custom-modal-header"> <h1>@Title</h1> @if (!ShowCancel) { <div class="cancel-icon" @onclick="HandleCancel"> <span class="material-icons-outlined cancel-icon" role="img" aria-label="Cancel">clear</span> </div> } </div> <div class="custom-modal-content"> @ChildContent </div> <div class="custom-modal-footer"> @if (ShowCancel) { <button type="button" class="btn btn-sm btn-outline-secondary" @onclick="HandleCancel">Cancelar</button> } <button type="submit" class="btn btn-sm btn-primary" @onclick="HandleConfirm">Aceptar</button> </div> </div> </div> @code { <pre><code>[Parameter] public bool ShowCancel { get; set; } = true; [Parameter] public bool Show { get; set; } [Parameter] public EventCallback<bool> ShowChanged { get; set; } [Parameter] public string Title { get; set; } [Parameter] public RenderFragment ChildContent { get; set; } [Parameter] public EventCallback OnCancel { get; set; } [Parameter] public EventCallback OnConfirm { get; set; } private string showClass => Show ? "show" : string.Empty; private string style => Show ? "display: block;" : "display: none;"; private void OverlayKeyDown(KeyboardEventArgs e) { // TODO: Detect what key is hit and take proper action var key = e.Key; Show = false; ShowChanged.InvokeAsync(Show); OnCancel.InvokeAsync(); StateHasChanged(); } private void HandleCancel() { Show = false; ShowChanged.InvokeAsync(Show); OnCancel.InvokeAsync(); } private void HandleConfirm() { Show = false; ShowChanged.InvokeAsync(Show); OnConfirm.InvokeAsync(); } </code></pre> }
Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para solucionar los problemas descritos, se deben realizar los siguientes cambios en el código:

    1. En el método OverlayKeyDown, agregar lógica para detectar si se presiona la tecla Tab y evitar que el evento se propague hacia la página subyacente. Esto se puede hacer utilizando los métodos e.preventDefault() y e.stopPropagation(). Por ejemplo:
    private void OverlayKeyDown(KeyboardEventArgs e) 
    {
        var key = e.Key;
    
        if (key == "Tab")
        {
            e.PreventDefault();
            e.StopPropagation();
        } 
    
        if (key == "Escape")
        {
            Show = false;
            ShowChanged.InvokeAsync(Show);
            OnCancel.InvokeAsync();
    
            e.PreventDefault();
            e.StopPropagation();
        }
    
        if (key == "Enter")
        {
            Show = false;
            ShowChanged.InvokeAsync(Show);
            OnConfirm.InvokeAsync();
    
            e.PreventDefault();
            e.StopPropagation();
        }
    } 
    
    1. En el método OverlayKeyDown, agregar lógica para detectar si se presiona la tecla Enter o Esc y desencadenar el evento correspondiente. Esto se puede hacer utilizando los mismos métodos e.preventDefault() y e.stopPropagation() que antes, seguido de invocar el evento relevante usando InvokeAsync. Por ejemplo:
    private void OverlayKeyDown(KeyboardEventArgs e) 
    {
        var key = e.Key;
    
        if (key == "Tab")
        {
            e.PreventDefault();
            e.StopPropagation();
        } 
    
        if (key == "Escape")
        {
            Show = false;
            ShowChanged.InvokeAsync(Show);
            OnCancel.InvokeAsync();
    
            e.PreventDefault();
            e.StopPropagation();
        }
    
        if (key == "Enter")
        {
            Show = false;
            ShowChanged.InvokeAsync(Show);
            OnConfirm.InvokeAsync();
    
            e.PreventDefault();
            e.StopPropagation();
        }
    } 
    

    Realizando estos cambios, el diálogo será completamente funcional y tanto la navegación con el teclado como el desencadenamiento de eventos funcionarán como se espera.

Comments are closed.