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;
    }
  }
}
Foi útil?

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;
    }
  }
  1. Primeiro de tudo, nós removeed a ação atribuir variável do loop. Por ciclos de resíduos repetindo a mesma operação?
  2. O número dois, agora filtrar tudo, exceto as letras no início da entrada.
  3. 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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top