Selectonemenu of Primefaces selects an item by pressing a hot key with CTRL

Asked

Viewed 1,169 times

4

I have JSF forms with some keyboard shortcuts, for example, CTRL+S triggers Submit to save data.

The problem is that when a key combination is pressed into a field <p:selectOneMenu>, the first item starting with S (as the example) is selected and then the form is submitted.

It is possible to reproduce this behavior by accessing the showcase, selecting the first field and pressing CTRL+The. In Chrome at least it will select the first option and then open the "Open File" dialog" (Open).

My intention is for the component to ignore the typed letter if a special key is pressed.

I tested the html component SELECT and the jQuery UI combo and the same behavior does not occur. By the way, Primefaces uses a wrapper different for a field input.

I tried to add a return false both in the attribute event onkeydown how much in the onkeyup as per User Guide. Nothing done.

I even tried to add keyboard events by jQuery with preventDefault() and return false. Nothingness.

Well, before you download the source of Primefaces and start poking around, does anyone have any idea how to get around this situation?


Updating

More details about the component.

Opening the showcase page, clicked on the first component and left the SELECT open.

I pressed F12 to open the console and typed document.activeElement. The result was a input:

<input id="j_idt18:j_idt22_focus" name="j_idt18:j_idt22_focus" type="text" readonly="readonly">

I understand that this is the field that really gets the value and receives the events. It must have an Event Handler that selects the item when pressing a letter, but it certainly lacked a treatment for the case of special keys like CTRL and SHIFT.

  • In which element did you try to cancel the event? I don’t know anything about the first faces, but by the linked example it seems that it would have to be on .ui-selectonemenu-panel or something inside it. That’s it?

  • In my windows the CTR fires "save the page", and the S choose the first optionselect starting with S. I’m not sure I quite understand the problem.

  • @bfavaretto The events onkeydown and onkeyup are from the PF component and I didn’t get to see where they were injected into the generated code. Already jQuery codes I injected into a field input which is hidden. In my tests, I found that this hidden field stays in focus while the field is selected.

  • @Sergio If you have an item that starts with the letter "S" and you press CTRL+S to save, in addition to opening the dialog, the item starting with the letter "S" will be selected. The user will save the registration with the wrong item without realizing.

  • Probably the listeners of the first faces themselves are executed before yours, and then it’s too late to cancel.

  • Aha... I’ve figured out the problem. what you’re like if(CTR pressionado) ignorar a outra tecla right?

  • @Sergio Exatamente!

  • @bfavaretto That’s probably it. I couldn’t think of a way around it.

Show 3 more comments

1 answer

5


I bypassed the problem by recovering a later version of the Primefaces library from the SVN repository. Some Javascript functions were fixed.

I extracted the fixed functions and added a Javascript file to overwrite the incorrect version with problems.

The code is:

/**
 * Fix for selectOneMenu when key is pressed along with CTRL
 */
PrimeFaces.widget.SelectOneMenu = PrimeFaces.widget.SelectOneMenu.extend({

    bindKeyEvents: function() {
        var $this = this;

        this.focusInput.on('keydown.ui-selectonemenu', function(e) {
            var keyCode = $.ui.keyCode,
            key = e.which;

            switch(key) {
                case keyCode.UP:
                case keyCode.LEFT:
                    $this.highlightPrev(e);
                break;

                case keyCode.DOWN:
                case keyCode.RIGHT:
                    $this.highlightNext(e);
                break;

                case keyCode.ENTER:
                case keyCode.NUMPAD_ENTER:
                    $this.handleEnterKey(e);
                break;

                case keyCode.TAB:
                    $this.handleTabKey();
                break;

                case keyCode.ESCAPE:
                    $this.handleEscapeKey(e);
                break;
            }
        })
        .on('keyup.ui-selectonemenu', function(e) {
            var keyCode = $.ui.keyCode,
            key = e.which;
            switch(key) {
                case keyCode.UP:
                case keyCode.LEFT:
                case keyCode.DOWN:
                case keyCode.RIGHT:
                case keyCode.ENTER:
                case keyCode.NUMPAD_ENTER:
                case keyCode.TAB:
                case keyCode.ESCAPE:
                break;

                default:
                    var text = $(this).val(),
                    matchedOptions = null;

                    clearTimeout($this.searchTimer);

                    matchedOptions = $this.options.filter(function() {
                        return $(this).text().toLowerCase().indexOf(text.toLowerCase()) === 0;
                    });

                    if(matchedOptions.length) {
                        var highlightItem = $this.items.eq(matchedOptions.index());
                        if($this.panel.is(':hidden')) {
                            $this.selectItem(highlightItem);
                        }
                        else {
                            $this.highlightItem(highlightItem);
                            PrimeFaces.scrollInView($this.itemsWrapper, highlightItem);
                        }
                    }

                    $this.searchTimer = setTimeout(function(){
                        $this.focusInput.val('');
                    }, 1000);

                break;
            }
        });
    }
});

Browser other questions tagged

You are not signed in. Login or sign up in order to post.