【问题标题】:Auto-selection of <option> based on input field, with some caveats根据输入字段自动选择 <option>,但有一些注意事项
【发布时间】:2009-05-14 18:40:26
【问题描述】:

我有一个 SELECT 元素,我需要根据在文本字段中输入的邮政编码的前半部分自动选择适当的选项。英国邮政编码的格式为 AB12 3CD,其中第一部分由代表县的 1-2 个字母和代表县内区域的数字组成。最后 3 个字符与此问题无关。

对于大多数字段,它仅基于首字母,但对于某些选项,它是邮政编码范围。 HTML 应该解释得最好:

<select id="country_field">
  <option value="">Select</option>
  <option value="AB">AB (Aberdeen)</option>
  <option value="AL">AL (St. Albans)</option>
  <option value="B">B (Birmingham)</option>
  <option value="BA">BA (Bath)</option>
  ...
  <option value="DD1">DD 1-7 (Dundee)</option>
  <option value="DD8">DD 8-11 (Dundee)</option>
  ...
</select>

当值正好是两个字母时,我下面的代码当前将选择正确的元素。但我需要将其扩展为包含单字母代码(伯明翰)和邮政编码范围(邓迪)。注意:如果有保证特殊值的解决方案,我可以更改选项值,例如DD1/DD2 而不是 DD1/DD8。

简而言之:

  • B2 --> 伯明翰
  • BA3 --> 巴斯
  • DD5 --> 第一个邓迪 [DD1]
  • DD11 --> 第二个邓迪 [DD8]

这是我到目前为止的 Javascript...

window.onload = function()
{
  // postcode INPUT field
  var zipInput = document.getElementById( 'zip_field' );
  // county SELECT field
  var ctySelect = document.getElementById( 'county_field' );

  zipInput.onchange = function()
  {
    var zipValue = zipInput.value;
    var ctyOptions = ctySelect.options;
    for ( i = 0; i < ctyOptions.length; i++ )
    {
      if ( zipValue.substring(0,2) == ctyOptions[i].value )
        ctyOptions[i].selected = true;
    }
  }
}

【问题讨论】:

  • 别忘了把 var 关键字放在 "i = 0" 前面,以免 i 变量污染全局范围。

标签: javascript regex select option postal-code


【解决方案1】:

您可以使用正则表达式来提取值...

/^([a-z]{1,2})(\d*)\s/i

那么,对于像 DD 这样的范围的代码,可能是这样的(伪代码)...

if(match[1].value == "DD") {   // needs special processing
  range = match[2].value;
  range = range < 8 ? 1 : 8;   // if the number is less than 8, set it to 1, otherwise set it to 8
  listValue = match[1].value + range
} else                         // just use the letters to select the list item 
  listValue = match[1].value;

因此,对于DD5,这将返回DD1,对于DD11,它将返回DD8B2BA3 之类的东西只会分别返回 BBA

如果您有多个具有不同范围的其他代码,您可以将if 更改为switch。然后,只需将具有该值的列表项设置为当前选择。

【讨论】:

  • 我认为这非常接近完美。我会尝试并报告。
【解决方案2】:

替换:

zipInput.onchange = function()
  {
    var zipValue = zipInput.value;
    var ctyOptions = ctySelect.options;
    for ( i = 0; i < ctyOptions.length; i++ )
    {
      if ( zipValue.substring(0,2) == ctyOptions[i].value )
        ctyOptions[i].selected = true;
    }
  }

与:

zipInput.onchange = function()
  {
    var zipValue = zipInput.value.match(/^[a-z]+/gi);

    var ctyOptions = ctySelect.options;
    for ( i = 0; i < ctyOptions.length; i++ )
    {
      if (zipValue[0] === ctyOptions[i].value )
        ctyOptions[i].selected = true;
    }
  }
  1. 首先,我们从循环中删除了变量赋值操作。为什么要浪费循环重复相同的操作?
  2. 第二,我们现在过滤掉除输入开头的字母之外的所有内容。
  3. 这又可以扩展为包括数字后缀等。

【讨论】:

    【解决方案3】:

    您可以将 zipValue 的开头与选项值进行比较。不需要正则表达式。只需使用 indexOf。

      zipInput.onchange = function()
      {
        var zipValue = zipInput.value.toUpperCase();
        var ctyOptions = ctySelect.options;
        for ( i = 0; i < ctyOptions.length; i++ )
        {
          if ( zipValue.indexOf(ctyOptions[i].value) == 0 )
            ctyOptions[i].selected = true;
        }
      }
    

    【讨论】:

    • 我想知道我怎么没想到这一点。最直接的解决方案呵呵。
    • 我不明白这如何处理 DD5 的条目将选择值为 DD1 的列表项的情况。
    • 我认为他对一个地区的每个地区都有一个选择。不过我可能错了。
    • 我可能理解错了,但从问题来看:#DD5 --> first Dundee [DD1],# DD11 --> second Dundee [DD8]。
    • 在任何情况下,他都会说“如果有保证特殊值的解决方案,我可以更改选项值,例如 DD1/DD2 而不是 DD1/DD8。”
    【解决方案4】:

    我不确定这在 javascript 中如何工作,但我会执行以下操作:

    • 将您的值设置为正则表达式以匹配您要查找的内容

    那么,“B”就变成了“^B[0-9]”(我假设它后面必须跟一个数字)

    BA 变为“^BA[0-9]”

    DD1 变为“^DD([1-7] )”

    DD8 变为 "^DD([8-9] |[1][01] )" 以匹配 DD8, DD9, DD10, DD11

    然后只需对您的字符串运行正则表达式(无需对其进行子字符串化,因为 ^ 确保此匹配出现在字符串的开头)并检查是否成功匹配。

    【讨论】:

      猜你喜欢
      • 2019-03-03
      • 2016-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-27
      相关资源
      最近更新 更多