Modify jQuery autocomplete not to submit eagerly on Enter

后端 未结 4 952
悲哀的现实
悲哀的现实 2021-01-14 22:55

Our users complain that when they press the enter key after pasting or typing values in a jQuery autocomplete widget the form is submitted.

It\'s extremely annoyin

4条回答
  •  一生所求
    2021-01-14 23:31

    It seems like jQuery UI didn't left a backdoor to customize the widget out of the box, so what you can do is override the autocomplete function to register a callback for the onkeypress event, capture the Enter and stop the propagation so it won't submit the form if the widget is open=visible.

    Here how it goes:

    function cancelAutocompleteSumbission(e) {
        // Make sure this is a nodeElement and the button pressed was Enter-Return
        if (!this.nodeType || e.which != 13)
            return;
    
        // If the widget is visible we simply want to close the widget.
        if ($(this).autocomplete('widget').is(':visible')) {
            $(this).autocomplete('close');
            return false;
        }
    }
    // Making a private scope to avoid naming collision.
    $.fn.autocomplete = (function () {
        // Cache the old autocomplete function.
        var oldAutocomplete = $.fn.autocomplete;
    
        // This will be the new autocomplete function.
        return function () {
            // If the first argument isn't "destroy" which 
            // should restore the input to it's initial state.
            if (!/^destroy$/i.test(arguments[0]))
                // Attach event to the input which will prevent Enter submission as
                // explained above.
                this.keypress(cancelAutocompleteSumbission);                
            // We need to restore the input to it's initial state,
            // detach the keypress callback.    
            else
                this.off('keypress', cancelAutocompleteSumbission);
    
            // Call the cached function with the give "this" scope and paramteres.
            return oldAutocomplete.apply(this, arguments);
        };
    })();
    

    Live DEMO


    Notes:

    • To change all the autocomplete widgets you need to use jQuery's prototype, $.fn is an alias to $.prototype.
    • Also you need to change $.fn.autocomplete before you use it it or the changes you made won't apply to those widget.
    • this inside the autocomplete function is actually a jQuery object so you don't need to wrap it with $(this)
    • You might say, Hey you keep register the very same callback for the keypress event. Well, that's exactly what I'm doing and why I wrote the callback as a named function. If you pass the same callback to addEventListener it will register it only once. MDN, Specifications
    • Adding code to a javascript function programmatically

提交回复
热议问题