jQuery 组合框显示 select 值而非文本

jQuery combobox displays select value not text

我正在使用(稍微修改过的)jQuery 自动完成组合框将 <select> 转换为实时搜索 <input>。问题是底层 <select> 看起来像:

<select department>
<option value="12345">Computer Engineering</option>
<option value="01234">Computer Science</option>
  :
</select>

所以当用户选择他们的选择时,部门编号被放在 <input> 中,这看起来很乱而且令人困惑(但这是提交的正确值)。

除了进一步修改组合框小部件以添加 <input type='hidden'> 并(以某种方式?)阻止提交 <input type=text> 之外,我是否有任何其他可能性?

编辑: 如@Pierre 的 link 所示,组合框的 <input type='text'> 没有名称,因此未提交,所以所有这些都需要发生是将所选选项的标签而不是它的值放入文本输入中。

默认jquery ui 自动完成行为似乎显示值数据。 您可以更改它,请参阅此线程 jQuery autocomplete shows value instead of label

否则,您还有其他开箱即用的解决方案:

它将通过包含 id...

<input> 标签解决您的问题

这是我最终得到的代码,也许对其他人有帮助。 它是来自 jQuery UI 自动完成页面的组合框和类别示例的组合。注意:因为我没有动态修改底层 select,所以我只扫描了一次 select -- 在组合框 _create 函数中 -- 如果可以修改,则应该将其移到 _source 函数中.

$(document).ready(function() {
  jQuery.widget("custom.autooptgroup", jQuery.ui.autocomplete, {
    _create: function() {
      this._super();
      this.widget().menu(
        "option",
        "items",
        "> :not(.ui-autocomplete-category)"
      );
    },
    _renderMenu: function(ul, items) {
      var self = this;
      var prevCat = "";
      var li;
      jQuery.each(items, function(index, item) {
        li = "<li class='ui-autocomplete-category'>";
        if (item.category != prevCat) {
          ul.append(li + item.category + "</li>");
          prevCat = item.category;
        }
        li = self._renderItemData(ul, item);
        if (item.category) {
          li.attr(
            "aria-label",
            item.category + " : " + item.label
          );
        }
      });
    }
  });
  jQuery.widget("custom.combobox", {
    _create: function() {
      this.wrapper = $("<span>")
        .addClass("custom-combobox")
        .insertAfter(this.element);
      this.olvc = [];
      var ogroups = this.element[0].children;
      for (var i = 0; i < ogroups.length; ++i) {
        var ogroup = ogroups[i];
        if (ogroup.nodeName == "OPTION") {
          var opt = ogroup
          var txt = opt.text;
          var val = opt.value;
          this.olvc.push({
            option: opt,
            label: txt,
            value: val,
            category: ""
          });
        } else {
          var cat = ogroup.label;
          var opts = ogroup.children;
          for (var j = 0; j < opts.length; ++j) {
            var opt = opts[j];
            var txt = opt.text;
            var val = opt.value;
            this.olvc.push({
              option: opt,
              label: txt,
              value: val,
              category: cat
            });
          }
        }
      }

      this.element.hide();
      this._createAutocomplete()
    },

    /* :selected will return the first option if none are explicitly selected */
    /* we don't want this so we look at the selected attribute to see if the */
    /* option returned by :selected is really selected */
    _createAutocomplete: function() {
      var self = this;
      var selected = this.element.find(":selected");
      var really = (selected.attr('selected') != null);
      var value = really ? (selected.val() ? selected.text() : "") : "";

      this.input = $("<input>")
        .appendTo(this.wrapper)
        .val(value)
        .attr("title", "")
        .attr("size", "32")
        .attr("placeholder", self.element.attr('placeholder'))
        .addClass(
          "custom-combobox-input " +
          "ui-widget ui-widget-content " +
          "ui-state-default ui-corner-left"
        )
        .autooptgroup({
          delay: 0,
          minLength: 0,
          source: jQuery.proxy(this, "_source"),
          select: function(event, ui) {
            ui.item.option.selected = true;
            self._trigger("select", event, {
              item: ui.item.option
            });
            $(this).val(ui.item.label);  /* label, not value for us! */
            event.preventDefault();
          },
          change: function(event, ui) {
            var value = self.input.val();
            var valueLowerCase = value.toLowerCase();
            var valid = false;

            if (ui.item) return;

            self.element.children("option").each(function() {
              if ($(this).label().toLowerCase() === valueLowerCase) {
                this.selected = valid = true;
                return false;
              }
            });

            if (valid) return;

            self.input
              .val("")
              .attr("title", value + " didn't match any item")
              .tooltip("open");
            self.element.val("");
            self._delay(function() {
              this.input.tooltip("close").attr("title", "");
            }, 2500);
          }
        })
        .tooltip({
          classes: {
            "ui-tooltip": "ui-state-highlight"
          }
        });
    },

    _source: function(request, response) {
      response(jQuery.ui.autocomplete.filter(
        this.olvc, request.term
      ));
    },

    _destroy: function() {
      this.wrapper.remove();
      this.element.show();
    }
  });


  $('.example').combobox({
    delay: 0,
    minLength: 0
  });

});
.ui-autocomplete {
  text-align: left;
  max-height: 500px;
  overflow-y: auto;
  overflow-x: hidden;
  padding-right: 20px;
}

.ui-autocomplete-category {
  font-weight: bold;
}

.ui-widget {
  font-family: Nimbus Sans, arial, helvetica, verdana, sans-serif;
  font-size: 1em;
}
<link href="https://code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<script src="https://code.jquery.com/ui/1.11.1/jquery-ui.min.js"></script>

<span style='font-weight: bold'>States and Such</span><br>
<select name='locations' class='example' placeholder='Select Location'>
  <option value='MP'>Northern Mariana Islands</option>
  <option value='PR'>Puerto Rico</option>
  <option value='VI'>US Virgin Islands</option>
  <optgroup label='East'>
    <option value='NH'>New Hampshire</option>
    <option value='NJ'>New Jersey</option>
    <option value='NY'>New York</option>
    <option value='VT'>Vermont</option>
  </optgroup>
  <optgroup label='Midwest'>
    <option value='IA'>Iowa</option>
    <option value='MN'>Minnesota</option>
    <option value='ND'>North Dakota</option>
    <option value='SD'>South Dakota</option>
    <option value='WS'>Wisconsin</option>
  </optgroup>
  <optgroup label='South'>
    <option value='FL'>Florida</option>
    <option value='NC'>North Carolina</option>
    <option value='NM'>New Mexico</option>
    <option value='SC'>South Carolina</option>
    <option value='TX'>Texas</option>
  </optgroup>
  <optgroup label='West'>
    <option value='CA'>California</option>
    <option value='OR'>Oregon</option>
    <option value='WA'>Washington</option>
  </optgroup>
</select>