首页 > 解决方案 > 如何使用 jQuery 搜索 optgroup 标签

问题描述

我有一个选择美国各州的列表,我需要按 optgroup 标签过滤。

例如:如果我搜索 Alabama,我需要返回另一个选择BirminghamHuntsville

我正在使用这个 jQuery 代码,当我按选项搜索时,这个代码可以工作,但我需要按组搜索。

如何更改 jQuery 以仅返回我搜索的州的城市

这是我的工作代码:https ://jsfiddle.net/km7s9er5/

在此先感谢有人帮助我

$(document).ready(function() {

  jQuery.fn.filterByText = function(textbox, selectSingleMatch) {
    return this.each(function() {
      var select = this;
      var options = [];
      $('#myfiltercities_id').hide();
      $(select).find('option').each(function() {
        options.push({
          value: $(this).val(),
          text: $(this).text()
        });
      });
      $(select).data('options', options);
      $(textbox).bind('change keyup', function() {
        $('#myfiltercities_id').hide();
        var options = $(select).empty().data('options');
        var search = $(this).val().trim();
        var regex = new RegExp(search, "gi");

        $.each(options, function(i) {
          var option = options[i];
          if (option.text.match(regex) !== null) {
            $(select).append(
              $('<option>').text(option.text).val(option.value)
            );
          }
        });
        if (selectSingleMatch === true && $(select).children().length === 1) {
          $(select).children().get(0).selected = true;
        }
      });
    });
  };

  $(function() {
    $('#myfiltercities_id').filterByText($('#textbox'), true);
    $("select option").click(function() {
      alert(1);
    });
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<select name="myfiltercities" id="myfiltercities_id">
  <option value=""></option>
  <optgroup label="AL"></optgroup>
  <optgroup label="Alabama">
    <option value="123">Birmingham</option>
    <option value="123">Huntsville</option>
  </optgroup>
  <optgroup label="AK"></optgroup>
  <optgroup label="Alaska">
    <option value="456">Anchorage</option>
    <option value="789">Juneau</option>
    <option value="135">Fairbanks</option>
  </optgroup>
  <optgroup label="AZ"></optgroup>
  <optgroup label="Arizona">
    <option value="198">Phoenix</option>
    <option value="065">Tucson</option>
  </optgroup>
  <optgroup label="AR"></optgroup>
  <optgroup label="Arkansas">
    <option value="835">Little Rock</option>
  </optgroup>
  <optgroup label="CA"></optgroup>
  <optgroup label="California">
    <option value="402">Los Angeles</option>
  </optgroup>
</select>

标签: javascriptjqueryarraysjquery-ui

解决方案


考虑以下代码。

https://jsfiddle.net/Twisty/zvtymk1r/29/

HTML

<form action="/action_page.php">
  <label for="fname">Find City</label>
  <input type="text" id="textbox" name="textbox"><br><br>

  <select name="myfiltercities" id="myfiltercities_id">
    <option value=""></option>
    <optgroup label="Alabama" data-abbr="AL">
      <option value="123">Birmingham</option>
      <option value="123">Huntsville</option>
    </optgroup>
    <optgroup label="Alaska" data-abbr="AK">
      <option value="456">Anchorage</option>
      <option value="789">Juneau</option>
      <option value="135">Fairbanks</option>
    </optgroup>
    <optgroup label="Arizona" data-abbr="AZ">
      <option value="198">Phoenix</option>
      <option value="065">Tucson</option>
    </optgroup>
    <optgroup label="Arkansas" data-abbr="AR">
      <option value="835">Little Rock</option>
    </optgroup>
    <optgroup label="California" data-abbr="CA">
      <option value="402">Los Angeles</option>
    </optgroup>
  </select>
</form>

JavaScript

jQuery.fn.filterByText = function(textbox, selectSingleMatch) {
  return this.each(function() {
    var select = this;
    $('#myfiltercities_id').hide().children().hide();
    $(textbox).on("change keyup", function(e) {
      $('#myfiltercities_id').hide().children().hide();
      var search = $(this).val().trim().toLowerCase();
      if (search.length >= 2) {
        $('#myfiltercities_id').show();
        $("optgroup", select).each(function(i, el) {
          var label = $(el).attr("label").toLowerCase();
          var abbr = $(el).data("abbr").toLowerCase();
          if (search.length == 2) {
            if (abbr == search) {
              console.log(search, label, abbr);
              $(el).show();
            }
          } else {
            if (label.indexOf(search) >= 0) {
              console.log(search, label, abbr);
              $(el).show();
            }
          }
        });
      }
    });
  });
}

$(function() {
  $('#myfiltercities_id').filterByText($('#textbox'), true);
  $("select option").click(function() {
    alert(this.value);
  });
});

首先,您的 HTML 结构不利于正确搜索。缩写与结果无关。我将其移至与城市关联的数据属性。

您的搜索功能最初是为选项元素设计的,不适合组。它还将选项重新添加回选择。它似乎过于复杂。

我发现在过滤时,简单地隐藏所有项目然后显示与过滤器匹配的项目更容易。根据输入中的字符数,我们可能正在搜索缩写词或完整的州名。这是一个容易查看的条件。

因此,如果用户搜索"al",他们将获得阿拉巴马州,但如果他们继续搜索 ,他们将获得阿拉巴马"ala"州和阿拉斯加州。


推荐阅读