Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simulating a tab keypress using JavaScript

Tags:

I'd like to have the browser act as if the user had pressed the Tab key when they click on something. In the click handler I've tried the following approaches:

var event = document.createEvent('KeyboardEvent');
event.initKeyEvent("keypress", true, true, null, false, false, false, false, 9, 0);
this.input.focus()[0].dispatchEvent(event);

And jQuery:

this.input.focus().trigger({ type : 'keypress', which : 9 });

...which I took from here.

The first approach seems to be the best bet, but doesn't quite work. If I change the last two parameters to 98, 98, indeed, a 'b' is typed into the input box. But 9, 0 and 9, 9 (the former of which I took right from the MDC web site) both give me these errors in firebug under FF3:

Permission denied to get property XULElement.popupOpen
[Break on this error] this.input.focus()[0].dispatchEvent(event);

Permission denied to get property XULElement.overrideValue
[Break on this error] this.input.focus()[0].dispatchEvent(event);

Permission denied to get property XULElement.selectedIndex
[Break on this error] this.input.focus()[0].dispatchEvent(event);

Permission denied to set property XULElement.selectedIndex
[Break on this error] this.input.focus()[0].dispatchEvent(event);

I've heard such (with no clear definition of 'such') events are 'untrusted', which might explain these errors.

The second approach causes whatever value I put as event.which to be passed as event.which, but to no effect (even if I use 98 instead of 9, no 'b' is typed in the box.) If I try setting event.data in the object I'm passing, it ends up undefined when the event is triggered. What follows is the code I'm using to view that:

$('#hi').keypress(function(e) {
  console.log(e);
});

Any other ideas?

like image 499
Kev Avatar asked Mar 31 '09 19:03

Kev


People also ask

Can JavaScript simulate key presses?

If you need keyup events too, it is also possible to simulate keyup events by changing "keydown" to "keyup" in the code snippet. This also sends the event to the entire webpage, hence the document . If you want only a specific element to receive the event, you can substitute document for the desired element.

How do you click a key in JavaScript?

To trigger a click button on ENTER key, We can use any of the keyup(), keydown() and keypress() events of jQuery. keyup(): This event occurs when a keyboard key is released. The method either triggers the keyup event, or to run a function when a keyup event occurs.

How do you press Enter key programmatically in typescript?

You can use: var e = jQuery. Event("keypress"); e. which = 13; //enter keycode e.


2 Answers

The solution I ended up going with is to create a "focus stealer" div (with tabindex = -1--can have the focus but can't be tabbed to initially) on either side of the area in which I want to manually manage the focus. Then I put a bubbling-true event listener for focus and blur on the whole area. When any focus occurs on the area, the tabindex values are changed to -1, and when any blur occurs, they're changed to 0. This means that while focused in the area, you can tab or shift-tab out of it and correctly end up on other page elements or browser UI elements, but as soon as you focus out of there, the focus stealers become tabbable, and on focus they set up the manual area correctly and shunt the focus over to the element at their end, as if you had clicked on one end or the other of the manual area.

like image 130
Kev Avatar answered Sep 17 '22 19:09

Kev


This is the solution I used on our webapp for two custom controls, a pop-up calendar and a pop-up unit / value weight selector (clicking the text box pops up a div with two selects)

function tab_focus(elem)
  var fields = elem.form.getElements()
  for(var i=0;i<fields.length;i++) {
    if(fields[i].id == elem.id){
      for(i=i+1;i<fields.length;i++){
        if(fields[i].type != 'hidden'){
          fields[i].focus()
          return    
        }
      }
      break;
    }
  }
  elem.form.focusFirstElement();
}

This is using the Prototype framework and expects an extended element(ie $('thing_id')) as its parameter.

It gets the form the element belongs to, and loops through the elements of the form until it finds itself.

It then looks for the first element after it that is not hidden, and passes it the focus.

If there are no elements after it in the form, it moves the focus back the to first element in the form. I could instead find the next form on the page through document.forms, but most of our pages use a single form.

like image 24
Tilendor Avatar answered Sep 21 '22 19:09

Tilendor