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. 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. The last 3 characters are irrelevant for this question.
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:
<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.
In short:
Here's 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;
}
}
}
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)...
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
. Something like B2
or BA3
will simply return B
and BA
, respectively.
You could change the if
to a switch
if you have multiple other codes with different ranges. 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;
}
}
You can compare the begining of the zipValue with the options values. 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;
}
}
I'm not sure how this would work in javascript but I'd do something like the following:
So then, "B", becomes "^B[0-9]" (I'm assuming it must 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 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.