В Choices.js управление элементами списка строится вокруг массива
choices, который может заполняться как статически при
инициализации, так и динамически после создания экземпляра. При работе с
локальными файлами основной задачей становится преобразование внешних
данных (JSON, CSV, текстовых файлов) в формат, который библиотека
способна интерпретировать через методы setChoices,
clearChoices, removeActiveItems и
setValue.
Ключевая особенность ручной загрузки заключается в полном контроле над жизненным циклом данных: библиотека не выполняет чтение файлов самостоятельно, а лишь предоставляет интерфейс для отображения уже подготовленного набора значений.
Каждый элемент списка в Choices.js описывается объектом следующего вида:
{
value: "unique_value",
label: "Отображаемый текст",
selected: false,
disabled: false,
customProperties: {}
}
При ручной загрузке файлов важно привести данные к этой структуре. Любой источник — JSON, CSV или текстовый файл — должен быть преобразован в массив таких объектов.
Наиболее распространённый сценарий — загрузка JSON-файла с диска пользователя.
[
{ "value": "1", "label": "Москва" },
{ "value": "2", "label": "Санкт-Петербург" },
{ "value": "3", "label": "Новосибирск" }
]
const fileInput = document.querySelector('#fileInput');
const choicesInstance = new Choices('#sel ect', {
searchEnabled: true,
shouldSort: false
});
fileInput.addEventListener('change', (event) => {
const file = event.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onl oad = (e) => {
try {
const data = JSON.parse(e.target.result);
const formatted = data.map(item => ({
value: item.value,
label: item.label,
selected: false,
disabled: false
}));
choicesInstance.clearChoices();
choicesInstance.setChoices(formatted, 'value', 'label', true);
} catch (err) {
console.error('Ошибка парсинга JSON:', err);
}
};
reader.readAsText(file);
});
Метод setChoices является основным инструментом для
ручного наполнения списка после загрузки файла.
Сигнатура:
setChoices(choicesArray, valueKey, labelKey, replaceChoices)
choicesArray — массив объектовvalueKey — ключ значенияlabelKey — ключ отображаемого текстаreplaceChoices — замена текущих данныхПри значении true текущий список полностью очищается
перед загрузкой нового набора. Это критично при работе с файлами, так
как предотвращает дублирование данных.
CSV требует дополнительного парсинга, так как не является структурированным объектом.
1,Москва
2,Санкт-Петербург
3,Новосибирск
function parseCSV(text) {
return text
.split('\n')
.map(line => line.trim())
.filter(line => line.length > 0)
.map(line => {
const [value, label] = line.split(',');
return {
value: value.trim(),
label: label.trim(),
selected: false,
disabled: false
};
});
}
fileInput.addEventListener('change', (event) => {
const file = event.target.files[0];
const reader = new FileReader();
reader.onl oad = (e) => {
const parsed = parseCSV(e.target.result);
choicesInstance.clearChoices();
choicesInstance.setChoices(parsed, 'value', 'label', true);
};
reader.readAsText(file);
});
При частых загрузках файлов пересоздание экземпляра Choices.js является неэффективным. Вместо этого используется комбинированный подход:
function updateChoices(data) {
choicesInstance.removeActiveItems();
choicesInstance.clearChoices();
choicesInstance.setChoices(data, 'value', 'label', true);
}
Такой подход гарантирует:
В некоторых сценариях требуется не замена, а добавление данных из файла.
function appendChoices(data) {
choicesInstance.setChoices(data, 'value', 'label', false);
}
При replaceChoices = false новые элементы добавляются к
существующим.
Важно учитывать возможные дубликаты значений, так как библиотека не выполняет автоматическую дедупликацию.
При загрузке больших JSON/CSV файлов возникает нагрузка на основной поток. Оптимизация включает:
function chunkArray(arr, size) {
const result = [];
for (let i = 0; i < arr.length; i += size) {
result.push(arr.slice(i, i + size));
}
return result;
}
async function loadInChunks(data) {
const chunks = chunkArray(data, 200);
for (const chunk of chunks) {
choicesInstance.setChoices(chunk, 'value', 'label', false);
await new Promise(resolve => setTimeout(resolve, 50));
}
}
Такой подход снижает блокировку UI при больших объёмах данных.
Перед передачей данных в Choices.js необходимо обеспечить их корректность.
function validateItems(items) {
return items.filter(item =>
item &&
typeof item.value !== 'undefined' &&
typeof item.label === 'string' &&
item.label.length > 0
);
}
const safeData = validateItems(parsedData);
choicesInstance.clearChoices();
choicesInstance.setChoices(safeData, 'value', 'label', true);
При работе с несколькими файлами используется объединение массивов:
function mergeFiles(files) {
const readerPromises = Array.fr om(files).map(file => {
return new Promise(resolve => {
const reader = new FileReader();
reader.onl oad = (e) => {
const parsed = JSON.parse(e.target.result);
resolve(parsed);
};
reader.readAsText(file);
});
});
return Promise.all(readerPromises);
}
После объединения:
mergeFiles(fileInput.files).then(results => {
const flat = results.flat();
choicesInstance.clearChoices();
choicesInstance.setChoices(flat, 'value', 'label', true);
});
Choices.js поддерживает customProperties, что позволяет
сохранять дополнительные данные.
[
{
"value": "1",
"label": "Москва",
"region": "Центральный",
"population": 12000000
}
]
const formatted = data.map(item => ({
value: item.value,
label: item.label,
customProperties: {
region: item.region,
population: item.population
}
}));
При повторной загрузке файла важно полностью сбрасывать состояние:
function resetChoices() {
choicesInstance.removeActiveItems();
choicesInstance.clearChoices();
}
Это предотвращает сохранение старых выбранных значений, которые могут конфликтовать с новыми данными.
При работе с файлами возможны ошибки чтения и парсинга.
function safeLoad(file) {
const reader = new FileReader();
reader.oner ror = () => {
console.error('Ошибка чтения файла');
};
reader.onl oad = (e) => {
try {
const data = JSON.parse(e.target.result);
const safe = validateItems(data);
choicesInstance.setChoices(safe, 'value', 'label', true);
} catch (err) {
console.error('Ошибка обработки данных:', err);
}
};
reader.readAsText(file);
}
После завершения загрузки часто требуется программно установить значение:
choicesInstance.setChoiceByValue('1');
или несколько значений:
choicesInstance.setChoiceByValue(['1', '2']);
Это позволяет синхронизировать интерфейс с загруженными данными без дополнительных действий пользователя.