【问题标题】:jQuery ui.combobox and asp.net web forms autopostbackjQuery ui.combobox 和 asp.net web 表单自动回发
【发布时间】:2011-09-08 00:52:01
【问题描述】:

我正在使用 jQuery UI 库 (http://jqueryui.com/demos/autocomplete/#combobox) 中的自动组合框。组合框正在替换标准的 asp.net Web 表单下拉列表控件,其 autopostback 属性设置为 true。有没有办法我可以“继承”此控件上的事件处理程序,或者有没有办法我可以确定组合框中发生了“选择”或“更改”事件,以便我自己触发回发?

编辑:

添加我的组合框代码:

    (function($) {
  $.widget("ui.combobox", {

    _create: function() {
      var self = this;
      var width = this.element.width() > 100 ? "style='width:"+this.element.width()+"px'" : "";
        self.select = this.element.hide();
      var v = self.select.children(":selected").text();
      self.span = $("<span>")
      .insertAfter(self.select)
      .addClass(self.select.attr("class"))
      .addClass("ui-combobox");
      self.input = $("<input "+width+">")
      .appendTo(self.span)
      .autocomplete({
        source: function(request, response) {
          var matcher = new RegExp(request.term, "i");
          response(self.select.children("option").map(function() {
            var text = $(this).text();
            if (!request.term || matcher.test(text))
            return {
              id: $(this).val(),
              label: text.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" +
                      request.term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,
                      "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>"),
              value: text
            };
          }));
        },

        delay: 0,
        select: function(e, ui) {
          if (!ui.item) {
            // remove invalid value, as it didn't match anything
            $(this).val("");
            return false;
          }
          $(this).focus();
          self.select.val(ui.item.id);
          self._trigger("selected", null, {
            item: self.select.find("[value='" + ui.item.id + "']")
          });
        },
        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.value.match( matcher ) ) {
                this.selected = valid = true;
                return false;
              }
            });
            if ( !valid ) {
              // remove invalid value, as it didn't match anything
              $( this ).val( "" );
              select.val( "" );
              return false;
            }
          }
        },
        minLength: 0
      })
      .val(v)
      .addClass(self.select.attr("class"))
      .addClass("ui-widget-content ui-corner-left ui-combobox-input")
      .myHover();
      $("<div></div>")
      .appendTo(self.span)
      .button({
        icons: {
          primary: "ui-icon-triangle-1-s"
        },
        text: false
      }).removeClass("ui-corner-all")
      .addClass(self.select.attr("class"))
      .addClass("ui-corner-right ui-button-icon ui-combobox-button")
      .position({
        my: "left center",
        at: "right center",
        of: self.input,
        offset: "-1 0"
      })//.css("top", "")
      .click(function() {
        // close if already visible
        if (self.input.autocomplete("widget").is(":visible")) {
          self.input.autocomplete("close");
          return;
        }
        // pass empty string as value to search for, displaying all results
        self.input.autocomplete("search", "");
        self.input.focus();
        self.input.get(0).select();
      });
    },
    setValue: function(v) {
        this.select.val(v);
        this.input.val(this.select.children(":selected").text());
    }
    //_trigger("change", e, ui);
  });
})(jQuery);

【问题讨论】:

    标签: jquery asp.net jquery-ui


    【解决方案1】:

    在组合框小部件定义的_create 函数中,您会注意到var select 指的是目标选择元素。我们需要在组合框代码中的两个位置对该元素触发更改事件。第一个是在文本字段中选择并填充菜单项时。这将需要对自动完成小部件的关闭事件进行一些测试。第二个是小部件的更改事件(用于手动文本输入),这个更简单。

    首先,在 ui.combobox _create 函数的第 48 行附近编辑发送到自动完成构造函数的选项,在 change 处理程序选项之后添加一个 close 处理程序选项:

    change: function(event, ui) {
        if (!ui.item) {
    
        }
    },
    close: function(event, ui) {
        if (event.originalEvent &&
            event.originalEvent.type == "menuselected") {
            $(select).change();
        }
    }
    

    请注意,每次菜单关闭时,如果是menuselected 事件的结果(即用户选择了一个选项),它将触发原始选择的更改事件。此时,该项目已填充到文本框中,并在源元素中标记为已选中。

    接下来,在上面的 change 处理程序中(在第 36 行或附近)修改 select 的 test 和 set 函数,以在执行成功的测试并设置值时包含对 select 的更改的调用:

    select.children("option").each(function() {
        if ($(this).text().match(matcher)) {
            this.selected = valid = true;
            $(select).change();
            return false;
        }
    });
    

    这是必要的,因为以编程方式将选项标记为选中不会生成所需的更改事件。

    我创建了一个working demo,其中一个更改事件绑定到源选择,它在元素更新时提醒它的新值。我相信 ASP 的自动回发处理程序也会监听相同的事件,所以我怀疑这应该会产生您正在寻找的行为。

    【讨论】:

    • 我已将组合框代码添加到问题中。我“认为”它与 jquery ui 中的相同,不确定我们是否做了一些细微的修改。
    • 实际上这与您必须找到一种方法将此触发器绑定到(我认为)自动完成小部件的菜单元素的模糊事件这一事实有关。我昨晚做了一些研究,但今天晚些时候会进一步研究。这是由于我认为自动完成小部件的事件模式不完整。有一个事件可以拦截元素的选择,并且在输入模糊以“确认”更改之后,但是在使用所选项目中的文本更新输入之后没有事件。
    • 我和你一样好奇,因为我很想在我未来的 ASP 项目中用它来替换 DDL。
    • @lloydphillips 我已经用修改后的代码编辑了我的答案,似乎在适当的时候正确地冒泡了更改事件。
    【解决方案2】:

    对于更改事件:

    $( ".selector" ).bind( "autocompletechange", function(event, ui) {
      // do postback
    });
    

    对于选择,使用“autocompleteselect”而不是“autocompletechange”。

    【讨论】:

    • 我已将组合框代码添加到问题中。我“认为”它与 jquery ui 中的相同,不确定我们是否做了一些细微的修改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-05
    • 1970-01-01
    • 1970-01-01
    • 2011-01-12
    • 2016-03-22
    • 1970-01-01
    • 2014-10-27
    相关资源
    最近更新 更多