1

When the modal is showing, how can I disable key events like TAB? I have multiple buttons and fields in a form on the page that can be selected (focused) by tabbing. I want to disable that when the modal is showing. The application uses Angular and the modal is in a child component.

<button tabindex="0">Button1</button>
<button tabindex="0">Button2</button>
<form>...</form>

<div id="myModal" class="modal fade" role="dialog">
  <div class="modal-dialog">
    <div class="modal-content">...</div>
  </div>
</div>
matchi
  • 533
  • 2
  • 6
  • 17
  • Possible duplicate of [Keep tabbing within modal pane only](https://stackoverflow.com/questions/14572084/keep-tabbing-within-modal-pane-only) – Kos Jan 22 '18 at 13:29
  • @Kos, I'm looking for an Angular typescript solution rather than javascript. So that might be different – matchi Jan 22 '18 at 13:34

4 Answers4

5

You can add your own event listener:

// Your event listener
function preventTab(e) {
  e = e || window.event;
  if (e.keyCode === 9) { // If tab key is pressed
    e.preventDefault() // Stop event from its action
  }
}

// Call this when modal window opens
document.addEventListener(preventTab);

// Call this when modal window closes/unmounts
document.removeEventListener(preventTab);
Michal
  • 4,952
  • 8
  • 30
  • 63
  • Is there a way to do this in Angular typescript? – matchi Jan 22 '18 at 13:30
  • Sure give me a second :) – Michal Jan 22 '18 at 13:32
  • Well the typescript code looks exactly like mine after conversion. I don't do angular or typescript but you should not worry about that. Important things are: 1) define the preventTab handler 2) `addEventListener` when you want to stop the tab key from working 3) `removeEventListener` when you want to make the tab work again – Michal Jan 22 '18 at 13:41
4

I'd suggest something like this - use Renderer2 and listen for a keydown event and filter events by keyCode. Then on modal hide remove that listener.

onShow() {
   this.removeTabKeyListener = this.renderer.listen('document', 'keydown', (event) => {
      if (event.keyCode === 9) { 
        event.preventDefault();
      }
    });
}

onHide() {
  this.removeTabKeyListener();
}

A little example - http://plnkr.co/edit/LdpmCpgapPbrA26fGO9U?p=preview

IlyaSurmay
  • 2,283
  • 12
  • 20
  • How can I initialise the renderer in the component.ts? – matchi Jan 22 '18 at 14:32
  • add it in component's constructor, like I did in the example `constructor(private renderer: Renderer2){}` – IlyaSurmay Jan 22 '18 at 14:42
  • and don't forget to import it from `@angular/core` first – IlyaSurmay Jan 22 '18 at 14:42
  • What type is removeTabKeyListener ? I got a `TypeError: this.removeTabKeyListener is not a function` when calling `onHide()` – matchi Jan 22 '18 at 15:26
  • It's a function. Did you follow the example I made below? http://plnkr.co/edit/LdpmCpgapPbrA26fGO9U?p=preview , file `events.ts` – IlyaSurmay Jan 22 '18 at 15:29
  • I can't view the link - could you paste how you declared `removeTabKeyListener` in the component? – matchi Jan 22 '18 at 15:33
  • `removeTabKeyListener: Function;` If you can't use plunkr for some reason, here's a pastebin link with the code https://pastebin.com/9pviq3Bd – IlyaSurmay Jan 22 '18 at 15:39
  • I created another question for that: https://stackoverflow.com/questions/48385656/listener-is-not-a-function-error-when-trying-to-unbind-renderer-event-listener – matchi Jan 22 '18 at 16:16
0

You can disable tab by preventDafault the keyCode 9 (tab) on keydow:

$(document).keydown(function(e) {
    if (e.keyCode == 9) {
        e.preventDefault();
    }
});

Of course you'll want that on your modal opener and not as is, so it won't permanently disable tabs ;)

Facundo Corradini
  • 3,825
  • 9
  • 24
-1

Try this code it will just disable your tab key when modal is showing.

 $(document).keydown(function(e){
    if (e.which==9) // keycode for tab key
    {
        checkmodal = $('#myModal').is(':visible'); //check modal is opened or not
        if (checkmodal){
            e.preventDefault();
        }
    }
});
Rupal
  • 1,111
  • 6
  • 16