入力フィールドに基づく <option> の自動選択 (いくつかの注意事項あり)
-
21-08-2019 - |
質問
テキストフィールドに入力された郵便番号の前半に基づいて適切なオプションを自動選択する必要がある 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>
以下のコードは現在、値がちょうど 2 文字の場合に正しい要素を選択します。ただし、1 文字のコード (バーミンガム) と郵便番号の範囲 (ダンディー) を包含するように拡張する必要があります。注記:特別な値を保証する解決策がある場合は、オプションの値を変更できます。DD1/DD8 の代わりに DD1/DD2。
要するに:
- B2 --> バーミンガム
- BA3 --> お風呂
- DD5 --> 最初のダンディー [DD1]
- DD11 --> 2 番目のダンディー [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;
}
}
}
解決
あなたが値を引き出すために、正規表現を使用することができます...
/^([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
ことがDD8
を返します。 B2
またはBA3
のようなものは、単純に、それぞれ、B
とBA
を返します。
あなたはif
にswitch
を変更することができます。その後、ちょうど現在の選択として、その値を用いてリスト項目を設定します。
他のヒント
交換する:
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;
}
}
- まず、ループから変数割り当てアクションを削除しました。なぜ同じ操作を繰り返す無駄なサイクルなのでしょうか?
- 2 番目に、入力の先頭の文字を除くすべてをフィルターで除外します。
- これは、数字の接尾辞などを含めるように拡張できます。
あなたは、オプションの値で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;
}
}
これが JavaScript でどのように機能するかはわかりませんが、次のようなことを行うと思います。
- 探しているものと一致する正規表現になるように値を設定します。
したがって、「B」は「^B[0-9]」になります(その後に数字が続く必要があると想定しています)
BA は「^BA[0-9]」になります。
DD1 は「^DD([1-7] )」になります。
DD8 は、DD8、DD9、DD10、DD11 と一致するように「^DD([8-9] |[1][01] )」になります。
次に、文字列に対して正規表現を実行し (^ によりこの一致が文字列の先頭で発生するようにするため、部分文字列にする必要はありません)、一致が成功したかどうかを確認します。