Построение выбора временного диапазона в интерфейсах на базе Choices.js требует понимания того, как библиотека управляет списками опций, как динамически изменять содержимое селекта и каким образом интегрировать пользовательские сценарии, связанные с фильтрацией данных по времени.
Choices.js представляет собой надстройку над стандартными
<select> и <input> элементами,
позволяющую создавать расширенные интерфейсы выбора с поиском, тегами,
кастомными шаблонами и управляемым состоянием. При работе с временными
диапазонами библиотека используется не для хранения дат как таковых, а
для предоставления пользователю предопределённых или динамически
формируемых интервалов.
Временной диапазон в пользовательском интерфейсе обычно представлен набором предустановленных значений:
Choices.js позволяет моделировать такой список через массив объектов
choices, где каждый элемент содержит значение и
отображаемый текст.
const timeRanges = [
{ value: 'last_24h', label: 'Последние 24 часа' },
{ value: 'last_7d', label: 'Последние 7 дней' },
{ value: 'last_30d', label: 'Последние 30 дней' },
{ value: 'this_month', label: 'Текущий месяц' },
{ value: 'prev_month', label: 'Предыдущий месяц' },
{ value: 'custom', label: 'Произвольный диапазон' }
];
Инициализация Choices.js на основе этого массива выполняется через стандартный конструктор.
const select = document.querySelector('#timeRange');
const choices = new Choices(select, {
searchEnabled: false,
shouldSort: false,
itemSelectText: '',
choices: timeRanges
});
Временные диапазоны часто используются как фильтр данных в аналитических панелях. В таких сценариях важно фиксировать значения и предотвращать их сортировку или изменение порядка.
Параметр shouldSort: false критичен, поскольку
сортировка по алфавиту нарушает логическую последовательность временных
интервалов.
Также часто отключается поиск:
searchEnabled: false
Это связано с тем, что количество вариантов обычно ограничено и не требует фильтрации.
Ключевой аспект — обработка изменения значения. Choices.js
предоставляет событие change, которое позволяет реагировать
на выбор пользователя.
select.addEventListener('change', (event) => {
const selected = event.detail.value;
applyTimeFilter(selected);
});
Функция фильтрации может интерпретировать значение и преобразовывать его в реальные даты.
function applyTimeFilter(range) {
const now = new Date();
let startDate, endDate = now;
switch (range) {
case 'last_24h':
startDate = new Date(now.getTime() - 24 * 60 * 60 * 1000);
break;
case 'last_7d':
startDate = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
break;
case 'last_30d':
startDate = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);
break;
case 'this_month':
startDate = new Date(now.getFullYear(), now.getMonth(), 1);
break;
case 'prev_month':
startDate = new Date(now.getFullYear(), now.getMonth() - 1, 1);
endDate = new Date(now.getFullYear(), now.getMonth(), 0);
break;
default:
return;
}
fetchData({ startDate, endDate });
}
Вариант custom требует дополнительного интерфейса ввода
дат. Choices.js не предназначен для выбора дат напрямую, поэтому
используется комбинированный подход: селект + отдельные input
type=“date”.
<select id="timeRange"></select>
<div id="customRange" style="display:none;">
<input type="date" id="startDate">
<input type="date" id="endDate">
</div>
Логика отображения:
const customRangeBlock = document.querySelector('#customRange');
select.addEventListener('change', (event) => {
const value = event.detail.value;
if (value === 'custom') {
customRangeBlock.style.display = 'block';
} else {
customRangeBlock.style.display = 'none';
applyTimeFilter(value);
}
});
Дополнительная обработка применяется при изменении дат вручную:
document.querySelector('#endDate').addEventListener('change', () => {
const start = document.querySelector('#startDate').value;
const end = document.querySelector('#endDate').value;
if (start && end) {
fetchData({
startDate: new Date(start),
endDate: new Date(end)
});
}
});
Choices.js позволяет изменять список опций после инициализации. Это важно при сценариях, где временные диапазоны зависят от контекста пользователя или типа данных.
choices.setChoices([
{ value: 'today', label: 'Сегодня' },
{ value: 'yesterday', label: 'Вчера' },
{ value: 'last_7d', label: 'Последние 7 дней' }
], 'value', 'label', true);
Флаг true очищает предыдущие значения, заменяя их новым
набором.
При работе с большими объёмами данных временной диапазон почти всегда связан с серверным API. Значение из Choices.js передаётся как параметр запроса.
async function fetchData({ startDate, endDate }) {
const response = await fetch('/api/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ startDate, endDate })
});
const data = await response.json();
renderChart(data);
}
Такой подход разгружает клиентскую сторону и позволяет обрабатывать данные на сервере с использованием индексов по датам.
Choices.js позволяет изменять внешний вид выпадающего списка через CSS-классы. Для временных диапазонов часто выделяют логические группы, например быстрые пресеты и пользовательский режим.
.choices__item--selectable[data-value="custom"] {
font-weight: 600;
color: #2b6cb0;
}
Это помогает визуально отделить стандартные интервалы от расширенных режимов.
При увеличении количества вариантов используется группировка через
optgroup-подобную структуру.
choices.setChoices([
{
label: 'Короткие интервалы',
choices: [
{ value: 'today', label: 'Сегодня' },
{ value: 'yesterday', label: 'Вчера' }
]
},
{
label: 'Долгие интервалы',
choices: [
{ value: 'last_7d', label: 'Последние 7 дней' },
{ value: 'last_30d', label: 'Последние 30 дней' }
]
}
], 'value', 'label', false);
Такое разделение улучшает восприятие при большом количестве временных фильтров.
Choices.js хранит текущее значение внутри компонента, но для синхронизации с приложением часто требуется принудительная установка значения.
choices.setChoiceByValue('last_7d');
Это полезно при восстановлении состояния фильтров после перезагрузки страницы или при переключении вкладок интерфейса.
При работе с временными диапазонами возникают ситуации, требующие дополнительной логики:
Choices.js не решает эти задачи напрямую, но обеспечивает стабильный слой выбора значения, который затем интерпретируется бизнес-логикой приложения.
function validateRange(start, end) {
const maxRange = 365 * 24 * 60 * 60 * 1000;
if (end - start > maxRange) {
throw new Error('Превышен максимально допустимый диапазон');
}
}
Временной диапазон, выбранный через Choices.js, часто напрямую связан с графиками и аналитическими компонентами. После изменения значения триггерится пересчёт данных и обновление визуализации.
function onRangeChange(range) {
applyTimeFilter(range)
.then(data => updateDashboard(data));
}
Такой механизм делает Choices.js частью реактивного интерфейса, где селект выступает управляющим элементом фильтрации временных данных.