Автоматический выбор <option> на основе поля ввода, с некоторыми оговорками
-
21-08-2019 - |
Вопрос
У меня есть элемент 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;
}
}
- Прежде всего, мы удалили из цикла действие присваивания переменной.Зачем тратить время на повторение одной и той же операции?
- Во-вторых, теперь мы отфильтровываем все, кроме букв в начале ввода.
- Это, в свою очередь, можно расширить, включив в него числовые суффиксы и т. д.
Вы можете сравнить начало 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.
Затем просто запустите регулярное выражение для вашей строки (нет необходимости подстраивать ее, поскольку ^ гарантирует, что это совпадение произойдет в начале строки) и проверьте, было ли успешное совпадение.