Auto-seleção de
-
21-08-2019 - |
Pergunta
Eu tenho um elemento SELECT em que eu preciso para auto-selecionar a opção adequada com base no primeiro semestre de um código postal inserido em um campo de texto. postcodes britânicos são da forma AB12 3CD , onde a primeira seção consiste de 1-2 letras que representam o município e um número que representa a área dentro do município. Os últimos 3 caracteres são irrelevantes para esta questão.
Para a maioria dos campos é baseado em apenas a primeira letra (s), mas para algumas opções é uma faixa de código postal. O HTML deve explicá-lo melhor:
<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>
Meu código abaixo atualmente selecione o elemento correto quando o valor é exatamente duas cartas. Mas eu preciso expandi-la para abranger os códigos de uma única letra (Birmingham) e os intervalos de código postal (Dundee). Nota: eu posso mudar os valores de opção se houver uma solução que garante especiais valores, por exemplo, DD1 / DD2 em vez de DD1 / DD8.
Em resumo:
- B2 -> Birmingham
- BA3 -> Bath
- DD5 -> primeira Dundee [DD1]
- DD11 -> segundo Dundee [DD8]
Aqui está o Javascript tenho até agora ...
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;
}
}
}
Solução
Você pode usar uma expressão regular para retirar os valores ...
/^([a-z]{1,2})(\d*)\s/i
Então, por um código com uma gama como DD, talvez algo como isto (pseudo-código) ...
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;
Assim, para DD5
, este retornará DD1
e para DD11
ele irá retornar DD8
. Algo como B2
ou BA3
simplesmente retornará B
e BA
, respectivamente.
Você poderia mudar o if
a um switch
se você tiver vários outros códigos com diferentes intervalos. Em seguida, basta definir o item da lista com esse valor como a seleção atual.
Outras dicas
Substituir:
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;
}
}
Com:
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;
}
}
- Primeiro de tudo, nós removeed a ação atribuir variável do loop. Por ciclos de resíduos repetindo a mesma operação?
- O número dois, agora filtrar tudo, exceto as letras no início da entrada.
- Este por sua vez pode ser expandido para incluir os sufixos número, etc.
Você pode comparar o início da zipValue com os valores de opções. Não há necessidade de expressões regulares. Basta usar 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;
}
}
Eu não sei como isso funcionaria em javascript, mas eu faria algo como o seguinte:
- Configure os valores para ser expressões regulares para combinar com o que você está procurando
Então, "B", se torna "^ B [0-9]" (eu estou supondo que deve ser seguido de um número)
BA torna-se "^ BA [0-9]"
DD1 torna-se "^ DD ([7/1])"
DD8 torna-se "^ DD ([8-9] | [1] [01])" para corresponder DD8, DD9, DD10, DD11
Em seguida, basta executar o regex contra sua seqüência (sem necessidade de substring-lo como o ^ garante que este jogo ocorre no início da string) e verificar se houve um casamento bem-sucedido.