Автоматический выбор <option> на основе поля ввода, с некоторыми оговорками

StackOverflow https://stackoverflow.com/questions/865009

Вопрос

У меня есть элемент SELECT, в котором мне нужно автоматически выбрать соответствующую опцию на основе первой половины почтового индекса, введенного в текстовое поле.Британские почтовые индексы имеют вид АБ12 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>

Мой код ниже в настоящее время выбирает правильный элемент, если значение составляет ровно две буквы.Но мне нужно расширить его, чтобы охватить однобуквенные коды (Бирмингем) и диапазоны почтовых индексов (Данди).Примечание:Я могу изменить значения параметров, если есть решение, требующее специальных значений, например.DD1/DD2 вместо DD1/DD8.

Суммируя:

  • B2 --> Бирмингем
  • BA3 --> Ванна
  • DD5 --> первый Данди [DD1]
  • DD11 --> второй Данди [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;
    }
  }
  1. Прежде всего, мы удалили из цикла действие присваивания переменной.Зачем тратить время на повторение одной и той же операции?
  2. Во-вторых, теперь мы отфильтровываем все, кроме букв в начале ввода.
  3. Это, в свою очередь, можно расширить, включив в него числовые суффиксы и т. д.

Вы можете сравнить начало 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 становится "^DD([8-9] |[1][01] )" в соответствии с DD8, DD9, DD10, DD11.

Затем просто запустите регулярное выражение для вашей строки (нет необходимости подстраивать ее, поскольку ^ гарантирует, что это совпадение произойдет в начале строки) и проверьте, было ли успешное совпадение.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top