修改jQuery自动完成,不要急于提交Enter [英] Modify jQuery autocomplete not to submit eagerly on Enter

查看:130
本文介绍了修改jQuery自动完成,不要急于提交Enter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的用户抱怨说,当他们在粘贴或在jQuery自动填充小部件中输入值之后按Enter键时,表单被提交。

当他们复制粘贴存在于自动填充选项中的值时,他们非常讨厌他们自动填充小部件打开以显示单个值,他们按Enter接受该值,但那么在完成填充所有字段之前,表单会被提交,因为(默认情况下和我们

 < form>类型C并按Enter键:
< input id =autocomplete/>
< input type =submitvalue =submit/>
< / form>
$ b $('form')。submit(function(){
alert('You submitted the form');
return false;
});
$ b $('#autocomplete')。autocomplete({
source:[c#,c,c ++,java,php,coldfusion]
});

问题的演示



如何更改该点击回车只会关闭自动填充建议?

解决方案

好像jQuery UI没有留下后门来自定义widget,所以你可以重写 autocomplete 函数为 onkeypress 事件注册一个回调函数,捕获 Enter >并停止传播,所以它不会提交表单,如果widget打开=可见。



这里是怎么回事:

 函数cancelAutocompleteSumbission(e){
//确保这是一个nodeElement,并且按下的按钮是Enter-Return
if(!this。 nodeType || e.which!= 13)
return;

//如果小部件可见,我们只想关闭小部件。
if($(this).autocomplete('widget')。is(':visible')){
$(this).autocomplete('close');
返回false;
}
}
//制作私人范围以避免命名冲突。
$ .fn.autocomplete =(function(){
//缓存旧的自动填充函数
var oldAutocomplete = $ .fn.autocomplete;

//这将是新的自动完成函数
return function(){
//如果第一个参数不是销毁哪个
//应该将输入恢复到初始状态
if(!/ ^ destroy $ / i.test(arguments [0]))
//将事件添加到输入,以防止输入提交为
//上面解释
this.keypress(cancelAutocompleteSumbission);
//我们需要将输入恢复到初始状态,
//分离按键回调
else
this.off(' keypress',cancelAutocompleteSumbission);

//用给定的this作用域和paramteres调用缓存函数。
返回oldAutocomplete.apply(this,arguments);
};
})();

直播DEMO









  • 要更改所有自动填充小部件,您需要使用jQuery的原型 $。fn $的别名。prototype

  • 您还需要在使用它之前更改 $。fn.autocomplete 或您所做的更改不适用于这些小部件。 autocomplete 函数中的
  • 这个是实际上是一个jQuery对象,所以你不需要用 $(this)

  • 来包装它。你可能会说,与按键事件的回调相同。那么,这正是我正在做的,为什么我将回调函数写成了一个命名函数。如果您将相同的回调传递给 addEventListener ,它只会注册一次。 MDN 规格

  • 以编程方式将代码添加到javascript函数


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 annoying them when they copy-paste a value that exists in the autocomplete options the autocomplete widget opens to show that single value, they press Enter to accept that value but then the form is submitted before they finished filling all the fields because (by default and we don't want to change it) the widget won't select the first option in the menu.

<form>Type C and press Enter:
    <input id="autocomplete" />
    <input type="submit" value="submit" />
</form>

$('form').submit(function () {
    alert('You submitted the form');
    return false;
});

$('#autocomplete').autocomplete({
    source: ["c#", "c", "c++", "java", "php", "coldfusion"]
});    

DEMO of the problem

How can we change that clicking Enter will only close the autocomplete suggestions?

解决方案

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

这篇关于修改jQuery自动完成,不要急于提交Enter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆