jQuery event trigger is not working on annotorious and seadragon

135 Views Asked by At

I am trying to get the down arrow keyup event to fire automagically using jQuery. The annotorious/seadragon combination has a listener that opens all preconfigured tags when I press the down arrow.

I have written jQuery code to find the input field, put focus on it and then trigger the keyup event.

    function triggerDownArrowOnInput() {
        $("[id^=downshift][id$=input]").each(function(index) {
            // There should only be 1, but let's not assume.
            console.log(index);
            if (index == 0) {
                console.log("Found an input: " + $(this).attr("id"))
                $(this).focus();
                var event = jQuery.Event("keyup");
                event.keyCode = event.which = 40; // down arrow
                $(this).trigger(event);
            } else {
                console.log("Multiple elements found that match the id: " + $(this).attr("id"));
            } // if
        })
    } // triggerDownArrowOnInput

The focus is working great, but not the trigger. If I manually hit the down arrow key, then the preconfigured tags all appear:

enter image description here

I have tried "keyCode" and "which" separately.

I have tried triggering $(this).keyup(event).

I have tried putting in a delay between the focus call and the trigger/keyup call.

I have tried calling $(document).trigger(event).

I thought maybe I was sending the event to the wrong element, but it appears (going through Dev tools) that only the Input field and the document have the listeners enabled.

No matter what I do, I can't get the event to fire. Any ideas?

Thanks.

3

There are 3 best solutions below

1
On

Have you tried keydown?

var e = jQuery.Event("keydown");
e.which = 40;
e.keyCode = 40
$(this).trigger(e);

function triggerDownArrowOnInput() {
    $("[id^=downshift][id$=input]").each(function(index) {
        // There should only be 1, but let's not assume.
        console.log(index);
        if (index == 0) {
            console.log("Found an input: " + $(this).attr("id"))
            $(this).focus();
            var event = jQuery.Event("keydown");
            event.keyCode = event.which = 40;
            $(this).trigger(event);
        } else {
            console.log("Multiple elements found that match the id: " + $(this).attr("id"));
        }
    })
} // triggerDownArrowOnInput

1
On

I think I've got this working without jQuery, using a KeyboardEvent and dispatchEvent. With my tests I don't think you need the focus before hand either because it's an event on the element, but worth testing this on your application.

function triggerDownArrowOnInput() {
    $("[id^=downshift][id$=input]").each(function(index) {
        // There should only be 1, but let's not assume.
        console.log(index);
        if (index == 0) {
            console.log("Found an input: " + $(this).attr("id"))
            $(this).focus();
            this.dispatchEvent(new KeyboardEvent('keyup',{'keyCode': 40, 'key':'ArrowDown', 'code':'ArrowDown'}));
        } else {
            console.log("Multiple elements found that match the id: " + $(this).attr("id"));
        }
    })
}
0
On

I was able to get the event to fire, but still wasn't able to open the menu on focus. I ended up having to create a development environment for:

recogito/recogito-client-core
recogito/recogito-js
recogito/annotorious
recogito/annotorious-openseadragon

I then modified Autocomplete.jsx in recogito/recogito-client-core, added an OnFocus listener and then added the following code:

const onFocus = evt => {
    if (!isOpen) {
        this.setState({ inputItems: this.props.vocabulary }); // Show all options on focus
        openMenu()
    } // if
} // onFocus

Way more than I wanted to do, but it is working now.