4

是的,这确实是我关于 jQuery UI 自动完成的第三个或第四个问题。我最近的烦恼是单击表单中的“提交”按钮似乎不算作 jQuery 的“更改”。当我的输入框发生变化时,jQuery 会运行一些 javascript 来强制匹配可接受的输入列表及其值:

jQuery("#Resource").autocomplete({
   source: function( request, response ) {
    var matcher = new RegExp(jQuery.trim(request.term).replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), "i" );
    var matches = jQuery.grep(resources, function(value) {
     return matcher.test( value.label || value.value || value );
    });
    response(matches.length ? matches : [{ label: "No Result Found", value: "" }]);
   },
   focus: function(event, ui) {
    jQuery('#Resource').val(ui.item.label);
    return false;
   },          
   select: function(event, ui) {
    jQuery('#Resource').val(ui.item.label);
    jQuery('#EmployeeNumber').val(ui.item.value);
    return false;
   },
   change: function(event,ui) {
    for(var i in resources){
     jQuery('#EmployeeNumber').val("");
     if(resources[i].label.toLowerCase()==jQuery('#Resource').val().toLowerCase()) {
      jQuery('#EmployeeNumber').val(resources[i].value);
      break;
     }
    }
   }

  });

如果 EmployeeNumber (hidden) 输入已经有一个值,输入一个无效的名称,然后按 Tab 键或单击输入框会清除该值,但是如果您立即点击表单Submit按钮,它似乎不算作“更改” ' 并且POST数据包括以前的 EmployeeNumber 值 - 使应该是不正确的输入“有点”正确!

是否有某种方法可以让 jQuery 认识到单击“提交”也是一种更改,或者我可以通过某种方法让Submit按钮通知 jQueryResource输入已被单击?

更新

最后,我通过使用我认为相当老套的方法解决了这个问题——我放弃了自动完成框的“更改”事件,并在用户单击提交时手动匹配自己。它现在的工作方式是,如果用户通过单击自动完成下拉菜单选择名称,则 EmployeeNumber 值将由自动完成 jQuery 代码填充。如果用户只是键入名称并点击提交,则匹配由 forceCheck() 函数完成。当然,无论是否有第二个相同的名字,这个函数都会自动匹配第一个名字,但不幸的是,在我见过的最奇怪的怪癖中,for循环结束后的任何代码都不会被执行,即使循环中没有'return'语句。循环完成后,提交请求继续......这非常奇怪。

<fieldset class="submit">
    <input id="Submit" name="Submit" type="Submit" class="Submit" value ="Submit" onclick="document.getElementById('Resource').value = jQuery.trim(document.getElementById('Resource').value);forceCheck();"/>
</fieldset>

...


<script type="text/javascript">

    ...

    // Force a resource name check when the user hits the submit button. Necessary because if user changes Resoruce
    // input then hits submit directly (no click or tab off), the jQuery 'change' event (see below) isn't fired
    // until *after* the submit button has begun processing, which is too late.
    function forceCheck() {
        for(var i in resources) {
            document.getElementById("EmployeeNumber").value = "";
            if(resources[i].label.toUpperCase() == document.getElementById("Resource").value.toUpperCase()) {
                document.getElementById("EmployeeNumber").value = resources[i].value;
                return;
            }
        }
    }

    jQuery(function(){
        jQuery("#Resource").autocomplete({
            source: function( request, response ) {
                var matcher = new RegExp(jQuery.trim(request.term).replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), "i" );
                var matches = jQuery.grep(resources, function(value) {
                    return matcher.test( value.label || value.value || value );
                });
                response(matches.length ? matches : [{ label: "No Result Found", value: "" }]);
            },
            focus: function(event, ui) {
                jQuery('#Resource').val(ui.item.label);
                return false;
            },          
            select: function(event, ui) {
                jQuery('#Resource').val(ui.item.label);
                jQuery('#EmployeeNumber').val(ui.item.value);
                return false;
            },  
        });
    }); 
</script>

如果有人知道比这更好的方法,我将非常感谢您的回答 - 或者如果您知道为什么我的 forceCheck 函数的其余部分可能无法运行......否则,我明天将发布这篇文章作为我自己问题的答案,并在可能的情况下接受它(我相信两天后)。

最终更新

好吧,已经超过 24 小时(更多),所以我将我的解决方案发布为“答案”。如果仍然没有其他答案,我会再放几天然后接受它。

4

8 回答 8

4

更改处理程序被延迟调用(在提交之后)的原因是自动完成是异步编码的(有很多 setTimeout(...))。在模糊事件之后 150 毫秒调用更改事件。

我的解决方案也有点老套,但您可以将自动完成代码与提交分开。如果以更同步的方式重写自动完成小部件,这也很容易删除。

$("#mysubmit").click(function (event) {
//Wait for autocomplete to change value
    setTimeout(function() {
        //Do submit
        ...
    }, 250 ); //Make sure delay is greater than 150 ms, as in autocomplete widget.
    event.preventDefault(); //Don't submit now
});
于 2011-10-19T12:47:40.163 回答
2

我知道这是旧的,但这是我试图解决同样问题时最终的结果,我认为我有一个独特的解决方案。这当然不是一个完美的解决方案,因为它涉及访问“私有”功能,但它可以工作(到目前为止)并且看起来更干净。

我在提交之前强制触发更改事件:

$('#yourAutoCompleteForm').submit(function() {
    $('#yourAutoCompleteInput').data("autocomplete")._change();
    //the rest of your submit
}

我的提交继续验证我的更改回调设置的自定义属性。他们可能可以共享一个范围,只使用一个 var ...

于 2012-03-23T22:38:49.507 回答
1

我知道一个问题大约过了一年,但我遇到了同样的问题。我现在使用最后一个 jquery ui 1.8.13。我这样解决问题:

var acinaction = false;  // autocomlete in edit stage flag
var needsubmit = false;  // submit action asked
jQuery("#Resource").keypress(function(event) {
    // if any key pressed then we set autocomplete in edit stage flag
    if (event.which == '13') {
        event.preventDefault();
    }
    acinaction = true;
}).autocomplete({
   select: function(event, ui) {
        // user choose an item from dropdown menu
        // do validation here if necessary
        ...
        // unset autocomplete in edit stage flag
        acinaction = false;
    },
    change: function(event,ui) {
        if( acinaction ) {
            // user input some characters into input field and move focus away
            // without choosing any items from dropdown menu
            // may be clicking submit button
            // do validation here if necessary
            ...
            acinaction = false;
            if( form_is_valid && needsubmit ) {
                // if submit flag is set then try submit again
                JQuery('#Form').submit();
            }
        }
    }
});
JQuery('#Form').submit(function() {
    // if autocomplete in edit stage then cancel form submition
    if( acinaction ) {
        needsubmit = true;
        return false;
    }
    // autocomplete change event is done here
});

代码很丑,但它应该显示这个想法。

于 2011-06-10T14:44:51.950 回答
0

显然,jquery-ui 1.8.4解决了这个问题(见changelog):

  • 固定:组合框/自动完成不会保存价值,除非控制失去焦点

你有能力测试它吗?因为它对我不起作用。

于 2010-09-15T01:40:54.877 回答
0

为了扩展 Tvartom 的答案,这是我在页面加载代码中输入的内容:

$('form').submit(function(event) {
  var form = $(this);
  if (form.find('.ui-autocomplete-input').length &&
      !form.data('already-submitted')) {
    // delay the submit by 250 ms
    form.data('already-submitted', true);
    setTimeout(function() {
      form.submit();
      form.data('already-submitted', false);
    }, 250);
    event.stopImmediatePropagation();
    return false;
  }
});

这会自动应用于所有具有自动完成输入的表单。不过,您需要小心其他表单提交事件回调 - 您需要检查form.data('already-submitted')它是否为假,如果它为假,则什么也不做。

于 2014-01-24T19:07:50.167 回答
0

我有办法解决这个问题,

首先,将此脚本添加到您的脚本中

$('#your_form:input').change(function(){
   $('#your_form').data('changed',true);
});

然后在您提交单击验证脚本中,添加如下脚本,

 if(!$('#your_form').data('changed'))  return false; 

我发现它确实有效,尽管我认为这不是最好的方法。

对不起,这是一个解决方法。

于 2011-11-19T10:24:02.137 回答
-1

可以加吗

submit: function(event,ui) {
// same thing as your change:
}
于 2010-07-27T12:59:04.080 回答
-2

使用blur而不是change. 就我而言,它起作用了!

于 2012-04-18T21:27:27.273 回答