【问题标题】:jQuery Autocomplete verify selected valuejQuery Autocomplete 验证选择的值
【发布时间】:2010-10-22 07:54:10
【问题描述】:

我们正在使用 Jörn Zaefferer 编写的自动完成 jQuery 插件,并正在尝试验证输入的选项是否有效。

插件有结果()事件在选择选择时触发。这没关系,但是当用户也单击时,我需要检查文本框中的值。所以我们尝试了 .change() 和 .blur() 事件,但它们都带来了一个问题:当您单击结果 div(“建议”列表)中的条目时,.change() 和 .blur()事件触发,这是在插件向文本框写入值之前,因此此时无需验证。

有人可以帮我配置事件,以便每当有人点击离开但不在结果框中,我可以检查框中的有效值。如果这是错误的方法,请告诉我正确的方法。我们最初使用这个插件是因为它的“mustMatch”选项。此选项似乎不适用于所有情况。很多时候,一个有效的条目会被写入文本框,然后被插件清除为无效,我无法确定原因。

基本代码示例:

<html>
<head>
<title>Choose Favorite</title>
<script language="JavaScript" src="jquery-1.3.2.min.js" ></script>
<script language="JavaScript" src="jquery.autocomplete.min.js" ></script>
<script>
    $(".suggest").autocomplete("fetchNames.asp", {
        matchContains:false,
        minChars:1, 
        autoFill:false,
        mustMatch:false,
        cacheLength:20,
        max:20
    });

    $(".suggest").result(function(event, data, formatted) {
        var u = this;
        // Check value here

    });

    /* OR */

    $(".suggest").change(function(me) {
        //check value here
    });

</script>
</head>
<body>
    <label for="tbxName">Select name (I show 10):</label><br />
    <INPUT type="text" id="tbxName" name="tbxName" class="suggest"><br />
</body>
</html>

【问题讨论】:

标签: jquery autocomplete event-handling


【解决方案1】:

更新:这应该可以。我正在将名称列表加载到一个名为 ListOfNames 的数组中,这在 onBlur() 事件中用于验证根据数据输入的名称。您可能需要进行一些调整,但我认为它应该可以满足您的需求。

var listOfNames = [];
$(document).ready(function(){
   $.get("fetchNames.asp", function(data){
     listOfNames = data.split("\r\n");    
   });
   $(".suggest").autocomplete("fetchNames.asp", {
        matchContains:false,
        minChars:1, 
        autoFill:false,
        mustMatch:false,
        cacheLength:20,
        max:20
    });
    $("#tbxName").blur(function(){
        if(!listOfNames.containsCaseInsensitive(this.value)){
          alert("Invalid name entered");
        }
    });        
});

Array.prototype.containsCaseInsensitive = function(obj) {
  var i = this.length;
  while (i--) {
    if (this[i].toUpperCase() === obj.toUpperCase()) {
      return true;
    }
  }
  return false;
}

【讨论】:

  • 感谢您的回复。这不完全是这样做的。如果我选择一个值,它会正确填写,一旦我点击它错误,无效。如果我输入几个字符然后点击离开,不会引发错误,但我确实需要添加我的数据库检查。
  • 先触发什么,.blur() 还是 .change()?
  • 再次感谢您的回复。可能从 fetchnames.asp 返回的可能名称是 32,000,不确定我是否要将所有这些数据存储在一个数组中。我喜欢这种方法
  • 在这种情况下,正确的方法是让您的 fetchNames.asp 接受一个等于要验证的名称的查询字符串参数。例如:searchNames.asp?name=John .... 如果找到则返回名称,否则返回空字符串。这可以添加到 onBlur() 事件中。这有意义吗?
  • .blur() 事件的this.value 将只包含我在框中键入的项目,而不是我试图选择的项目。所以它永远不会匹配。我在文本框中输入并接收我的建议,只要我单击选择一个,.blur() 就会触发,但是将值写入文本框的单击事件尚未发生。这有意义吗?
【解决方案2】:

我认为与其编写自己的函数来验证数据是否匹配,不如调用search()。如果result() 是用一个空的data 参数调用的,那么你知道自动完成没有被使用,并且通过在模糊上调用search(),你可以保证至少调用一次result()

我已经为a similar question 发布了这段代码,在这里也可能有所帮助。

autocompleteField.result(function(event, data, formatted) {
    if (data) {
        //auto-complete matched
        //NB: this might get called twice, but that's okay
    }
    else {
        //must have been triggered by search() below
        //there was no match
    }
});

autocompleteField.blur(function(){
    autocompleteField.search(); //trigger result() on blur, even if autocomplete wasn't used
});

【讨论】:

  • 好答案!你知道如何防止结果事件触发两次吗?这就是问题所在,如果此事件执行一些复杂的逻辑,例如通过 ajax 请求验证服务器上的输入。
  • 如果您在.result() 中进行了大量处理,您可以尝试维护一个标志以查看您的if (data) 分支是否已被调用。不过,我可以警告您,这将是非常重要的:您可以轻松地在 if (data) 的末尾设置标志,但在用户编辑自动完成建议的情况下,您需要清除它。我会尝试使用.change()。祝你好运!
【解决方案3】:

我使用全局数据结构来跟踪找到的值

var ac_sent = {};

.result() 事件处理程序在 .change() 事件处理程序之前调用,因此在 .result(event, data, formatted) 中我将数据添加到结构中:

ac_sent[ data ] = true;

然后在 .change( event ) 事件处理程序中,我检查 ac_sent[ data ] 处是否有项目,如果没有,我知道该词没有找到:

$( "#textbox" ).change( function( event ) {

  var data = event.target.value;

  if ( !ac_sent[ data ] ) {
    // result was not found in autocomplete, do something...
    ac_sent[ data ] = true;  // remember that we processed it
  }

  return false;
});

【讨论】:

  • 在 change() 事件之前触发的 result() 事件并非 100% 准确。如果使用 Enter 键从列表中选择一个项目,则会按此顺序发生。但是,如果使用鼠标,则事件顺序是相反的——首先发生 change(),然后是 result()。
【解决方案4】:

这是我过去使用的代码。非常干净和简单。

var availableTags = [
  "ActionScript",
  "AppleScript",
  "Asp",
  "BASIC",
  "C",
  "C++",
  "Clojure",
  "COBOL",
  "ColdFusion",
  "Erlang",
  "Fortran",
  "Groovy",
  "Haskell",
  "Java",
  "JavaScript",
  "Lisp",
  "Perl",
  "PHP",
  "Python",
  "Ruby",
  "Scala",
  "Scheme"
];
$( "#currentSelectedLevel" ).autocomplete({
  source: availableTags,
  change: function( event, ui ) {
        val = $(this).val();
        exists = $.inArray(val,availableTags);
        if (exists<0) {
          $(this).val("");
          return false;
        }
      }
});

【讨论】:

  • 迄今为止最干净的解决方案。请注意,您需要确保 val 大写以符合您的数据源,否则将不匹配。例如。 actionscriptActionScript 不同。
猜你喜欢
  • 1970-01-01
  • 2014-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-17
相关资源
最近更新 更多