Search code examples
htmlcssangularnvda

What is the best approach to make NVDA screen reader to alert the user after a button has been clicked in Angular?


I have an application in Angular. In one of the screen I can search for some data based on which the data gets filtered. There is a reset button to clear the filters. I want to alert the user in NVDA screen reader that the search has been reset after clicking reset button.

I have tried the following approach. But I have some issues. Please help or suggest some better approach. I have simplified the code as follows.

<div>
    <a href="javascript:void(0);" aria-label="Reset search" (click)="resetSearch()"> Reset search
    </a>
    <span id="resetAlert">Search has been reset</span>
</div>

I am making a span element with the message that I want NVDA to read. But this element should not be otherwise detected by screen reader. So I set display none.

On click of reset button, following method is executed.

resetSearch() {
    // Making display block so that screen reader can find the element in DOM
    document.getElementById('resetAlert').style.display = 'block';

    // Removing existing attribute 
    document.getElementById('resetAlert').removeAttribute('role');

    // Setting role attribute so that screen reader alerts as "alert Search has been reset" 
    document.getElementById('resetAlert').setAttribute('role', 'alert');

}

The above logic works fine. But then the element stays in the DOM. If I scroll the page using tab and arrow keys, screen reader detects this element and reads it again. (I want it to read only when reset button is clicked).

I tried to change the display back to none. But it is not working.

resetSearch() {
    
    document.getElementById('resetAlert').style.display = 'block';

    
    document.getElementById('resetAlert').removeAttribute('role');

    
    document.getElementById('resetAlert').setAttribute('role', 'alert');


    // This line doesn't work. May be I am missing something. Please help
    document.getElementById('resetAlert').style.display = 'none';

}

Help me to toggle this span element when button is clicked to make display block and change it immediately to display none or suggest me a better approach for my use case.


Solution

  • I found a solution. I used aria-live on the span element. I have kept the color of span element same as the background color of the parent. I have kept the content of the span element as empty. After reset button is clicked, the content is set to what I want screen reader to read. Then I remove the content after 2 seconds so that while scrolling the page using tab, the screen reader doesn't read it out again.

    <span aria-live="polite" id="test" class="landing-page__alert"></span>
    
    
    resetSearch() {
        document.getElementById('resetAlert').innerHTML = 'Search has been reset';
    
        setTimeout(() => {
           document.getElementById('resetAlert').innerHTML = '';
        }, 2000);
    }