0

我试图在ASP.NET MVC3中使用带有下拉列表的JQuery UI Autocomplete (Combobox)JQuery自动完成组合框:MVC3验证不起作用

这里的代码在我看来,相关部分:(有4-10下拉列表中的任意位置)

<div class="editor-label"> 
     @Html.LabelFor(model => model.MerchantID, "Merchant") 
    </div> 
    <div class="editor-field"> 
     @Html.DropDownList("MerchantID", null, String.Empty, new { @class = "combobox" }) 
     @Html.ValidationMessageFor(model => model.MerchantID) 
    </div> 

    <div class="editor-label"> 
     @Html.LabelFor(model => model.FinancialAccountID, "FinancialAccount") 
    </div> 
    <div class="editor-field"> 
     @Html.DropDownList("FinancialAccountID", null, String.Empty, new { @class = "combobox" }) 
     @Html.ValidationMessageFor(model => model.FinancialAccountID) 
    </div> 

这里是JavaScript文件的内容,从基本上复制jquery-ui website

(function ($) { 
    $.widget("ui.combobox", { 
     _create: function() { 
      var input, 
        self = this, 
        select = this.element.hide(), 
        selected = select.children(":selected"), 
        value = selected.val() ? selected.text() : "", 
        wrapper = this.wrapper = $("<span>") 
         .addClass("ui-combobox") 
         .insertAfter(select); 

      input = $("<input>") 
        .appendTo(wrapper) 
        .val(value) 
        .addClass("ui-state-default ui-combobox-input") 
        .autocomplete({ 
         delay: 0, 
         minLength: 0, 
         source: function (request, response) { 
          var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i"); 
          response(select.children("option").map(function() { 
           var text = $(this).text(); 
           if (this.value && (!request.term || matcher.test(text))) 
            return { 
             label: text.replace(
              new RegExp(
               "(?![^&;]+;)(?!<[^<>]*)(" + 
               $.ui.autocomplete.escapeRegex(request.term) + 
               ")(?![^<>]*>)(?![^&;]+;)", "gi" 
              ), "<strong>$1</strong>"), 
             value: text, 
             option: this 
            }; 
          })); 
         }, 
         select: function (event, ui) { 
          ui.item.option.selected = true; 
          self._trigger("selected", event, { 
           item: ui.item.option 
          }); 
         }, 
         change: function (event, ui) { 
          if (!ui.item) { 
           var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex($(this).val()) + "$", "i"), 
            valid = false; 
           select.children("option").each(function() { 
            if ($(this).text().match(matcher)) { 
             this.selected = valid = true; 
             return false; 
            } 
           }); 
           if (!valid) { 
            // remove invalid value, as it didn't match anything 
            $(this).val(""); 
            select.val(""); 
            input.data("autocomplete").term = ""; 
            return false; 
           } 
          } 
         } 
        }) 
        .addClass("ui-widget ui-widget-content ui-corner-left"); 

      input.data("autocomplete")._renderItem = function (ul, item) { 
       return $("<li></li>") 
         .data("item.autocomplete", item) 
         .append("<a>" + item.label + "</a>") 
         .appendTo(ul); 
      }; 

      $("<a>") 
        .attr("tabIndex", -1) 
        .attr("title", "Show All Items") 
        .appendTo(wrapper) 
        .button({ 
         icons: { 
          primary: "ui-icon-triangle-1-s" 
         }, 
         text: false 
        }) 
        .removeClass("ui-corner-all") 
        .addClass("ui-corner-right ui-combobox-toggle") 
        .click(function() { 
         // close if already visible 
         if (input.autocomplete("widget").is(":visible")) { 
          input.autocomplete("close"); 
          return; 
         } 

         // work around a bug (likely same cause as #5265) 
         $(this).blur(); 

         // pass empty string as value to search for, displaying all results 
         input.autocomplete("search", ""); 
         input.focus(); 
        }); 
     }, 

     destroy: function() { 
      this.wrapper.remove(); 
      this.element.show(); 
      $.Widget.prototype.destroy.call(this); 
     } 
    }); 
})(jQuery); 

$(function() { 
    $(".combobox").combobox(); 
}); 

我遇到的问题是,似乎没有要上输入的值进行任何验证。例如,如果我将其留空并提交,那么没有错误表明输入了无效信息。但是,如果我注释掉combobox()调用来禁用组合框功能,则验证将正常工作。

我已经做了一些关于此问题的stackoverflow搜索,但我似乎无法找到任何匹配此特定情况的东西。

编辑:我发现验证实际上确实发生,但只有当我提交之前点击另一个字段,这是奇怪的。因此,如果我将空白文本输入到组合框中,然后单击到文本字段中,然后提交,它将正常工作(显示验证错误。)但是,如果我将空白文本输入到组合框并提交,它不会显示验证错误。有任何想法吗?

+1

我在你的代码和jquery例子之间唯一的区别就是你正在使用类的组合框函数,而不是ID。你有没有尝试过先用ID将它应用到单个元素上? – Shawn 2012-08-09 19:11:51

+0

@Shawn感谢您的回复。我尝试了你的建议,但不幸的是行为没有改变。但是,我确实观察了有关该问题的更多详细信息,并将其添加到了我的帖子中。我发现验证确实发生了,但只有在提交之前点击另一个字段,这很奇怪。因此,如果我将空白文本输入到组合框中,然后单击到文本字段中,然后提交,它将正常工作(显示验证错误。)但是,如果我将空白文本输入到组合框并提交,它不会显示验证错误。有任何想法吗? – Danation 2012-08-09 22:31:58

回答

1

好吧,我想出了问题。

当按下提交按钮时,在验证错误输入时清除所选项目的自动完成JQuery的之前,JavaScript验证被称为。这是我的意思是部分:

if (!valid) { 
    // remove invalid value, as it didn't match anything 
    $(this).val(""); 
    select.val(""); 
    input.data("autocomplete").term = ""; 
    return false; 
} 

用户开始打字,只有当选择一个有效的项目重新选择所以我尽快做出明确选择的项目。

source: function (request, response) { 
    select.val(""); //as soon as typing is started, the select input is cleared. This makes sure validation always occurs 
    var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i"); 
    response(select.children("option").map(function() { 
     var text = $(this).text(); 
     if (this.value && (!request.term || matcher.test(text))) 
      return { 
       label: text.replace(
        new RegExp(
         "(?![^&;]+;)(?!<[^<>]*)(" + 
         $.ui.autocomplete.escapeRegex(request.term) + 
         ")(?![^<>]*>)(?![^&;]+;)", "gi" 
        ), "<strong>$1</strong>"), 
       value: text, 
       option: this 
      }; 
    })); 
}, 
+0

这很有帮助,你在哪里包含这两个功能? – learning 2014-07-08 06:57:20

+0

@learning我的原始问题显示了完整的JavaScript代码,它需要以某种方式包含在页面中(可能通过一个包)。我的答案只是改变了部分代码(自动完成的源参数)。另外,作为警告,我还没有在新版本的jQuery,jQuery UI或ASP.NET MVC上测试过。 – Danation 2014-07-09 15:11:02

+1

我使用的解决方案在下面的链接中。我喜欢立即输入清除,我把它添加到我的组合框+1 http://stackoverflow.com/questions/13516841/how-to-get-unobtrusive-validation-on-my-jqueryui-element-combobox – joetinger 2015-06-11 18:00:33