简体   繁体   English

自动选择 <option>根据输入字段,有一些警告

[英]Auto-selection of <option> based on input field, with some caveats

I have a SELECT element in which I need to auto-select the appropriate option based on the first half of a postcode entered in a text field. 我有一个SELECT元素,其中需要根据在文本字段中输入的邮政编码的前半部分自动选择适当的选项。 British postcodes are of the form AB12 3CD , where the first section consists of 1-2 letters representing the county and a number representing the area within the county. 英国邮政编码的格式为AB12 3CD ,其中第一部分由1-2个字母组成,代表县,而一个数字则代表县内的地区。 The last 3 characters are irrelevant for this question. 后3个字符与该问题无关。

For most of the fields it is based on only the first letter(s), but for some options it is a postcode range. 对于大多数字段,它仅基于首字母,但是对于某些选项,它是邮政编码范围。 The HTML should explain it best: 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>

My code below will currently select the correct element when the value is exactly two letters. 当值正好是两个字母时,下面的代码当前将选择正确的元素。 But I need to expand it to encompass the single-letter codes (Birmingham) and the postcode ranges (Dundee). 但是我需要扩展它以包含单字母代码(伯明翰)和邮政编码范围(邓迪)。 Note: I can change the option values if there is a solution that warrants special values, eg DD1/DD2 instead of DD1/DD8. 注意:如果有一个可以保证特殊值的解决方案,例如DD1 / DD2而不是DD1 / DD8,我可以更改选项值。

In short: 简而言之:

  • B2 --> Birmingham B2->伯明翰
  • BA3 --> Bath BA3->浴
  • DD5 --> first Dundee [DD1] DD5->第一个邓迪[DD1]
  • DD11 --> second Dundee [DD8] DD11->第二个邓迪[DD8]

Here's the Javascript I have so far... 这是我到目前为止拥有的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;
    }
  }
}

You can use a regular expression to pull out the values... 您可以使用正则表达式提取值...

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

Then, for a code with a range like DD, perhaps something like this (pseudo-code)... 然后,对于范围为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;

So, for DD5 , this will return DD1 and for DD11 it will return DD8 . 因此,对于DD5 ,这将返回DD1 ,对于DD11 ,它将返回DD8 Something like B2 or BA3 will simply return B and BA , respectively. 诸如B2BA3类的东西将分别简单地返回BBA

You could change the if to a switch if you have multiple other codes with different ranges. 如果您有多个其他具有不同范围的代码,则可以将if更改为一个switch Then, just set the list item with that value as the current selection. 然后,仅将具有该值的列表项设置为当前选择。

Replace: 更换:

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;
    }
  }

With: 带有:

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. First of all, we removeed the variable assign action from the loop. 首先,我们从循环中删除了变量assign动作。 Why waste cycles repeating the same operation? 为什么浪费循环重复相同的操作?
  2. Number two, we now filter out everything except the letters in the beginning of the input. 第二,我们现在过滤掉输入开头的字母以外的所有内容。
  3. This can in turn be expanded to include the number suffixes, etc. 依次可以将其扩展为包括数字后缀等。

You can compare the begining of the zipValue with the options values. 您可以将zipValue的开头与选项值进行比较。 No need for regular expressions. 无需正则表达式。 Just use indexOf. 只需使用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;
    }
  }

I'm not sure how this would work in javascript but I'd do something like the following: 我不确定这在javascript中如何工作,但是我会做如下的事情:

  • Set up your values to be regular expressions to match what you're looking for 将您的值设置为正则表达式以匹配您要查找的内容

So then, "B", becomes "^B[0-9]" (I'm assuming it must be followed by a number) 因此,“ B”变成“ ^ B [0-9]”(我假设它后面必须有一个数字)

BA becomes "^BA[0-9]" BA变成“ ^ BA [0-9]”

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

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

Then just run the regex against your string (no need to substring it as the ^ makes sure this match occurs at the start of the string) and check if there was a successful match. 然后只需对您的字符串运行正则表达式(无需对它进行子字符串化,因为^可确保此匹配项发生在字符串的开头)并检查是否存在成功的匹配项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM