Automatic selection of <option> based on input field with some caveats

I have a SELECT element in which I need to automatically select the appropriate option based on the first half of the zip code entered in the textbox. British postal codes 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. The last 3 characters are irrelevant to this question.

For most fields, it is based on the first letter (s) only, but for some parameters it is the zip code range. HTML explains best:

<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 is currently selecting the correct item when the value is exactly two letters. But I need to expand it to cover single letter codes (Birmingham) and postal code ranges (Dundee). Note. I can change the parameter values ​​if there is a solution that requires special values, eg. DD1 / DD2 instead of DD1 / DD8.

In short:

  • B2 → Birmingham
  • BA3 → Bath
  • DD5 → first Dundee [DD1]
  • DD11 → second Dundee [DD8]

Here is the Javascript I have so far ...

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

      

0


a source to share


4 answers


You can use regex to pull in values ​​...

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

      

Then, for code with a range like DD, perhaps something like this (pseudocode) ...



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 it will return DD1

, and for DD11

it it will return DD8

. Something like B2

or BA3

just will return B

and BA

accordingly.

You can change if

to switch

if you have multiple other codes with different ranges. Then just set the list item with that value as the current selection.

+1


a source


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

      

FROM



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

      

  • First of all, we removed the variable assignment action from the loop. Why do waste cycles repeat the same operation?
  • Second number, we are now filtering out everything except letters at the beginning of the input.
  • This, in turn, can be expanded to include number suffixes, etc.
0


a source


You can compare the start of zipValue with parameters. No need for regular expressions. Just use 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;
    }
  }

      

0


a source


I'm not sure how this works in javascript, but I would do something like the following:

  • Set up your values ​​as regexps according to what you are looking for.

So then "B" becomes "^ B [0-9]" (I'm guessing it should be followed by a number)

BA becomes "^ BA [0-9]"

DD1 becomes "^ DD ([1-7])"

DD8 becomes "^ DD ([8-9] | [1] [01])" to match DD8, DD9, DD10, DD11

Then just run a regex on your string (no need to tweak it as specified in the ^ file, make sure it matches at the beginning of the line) and check if there was a successful match.

0


a source







All Articles