Ограничения на ввод

Базовая модель контроля вводимых данных

В библиотеке Choices.js механизм ограничения ввода строится вокруг нескольких уровней контроля: параметров инициализации, фильтрации вводимых значений, перехвата событий добавления и управления состоянием выбранных элементов. В совокупности это позволяет формировать строгие правила формирования списка значений в поле выбора.

Основная идея заключается в том, что ввод пользователя не принимается напрямую, а проходит цепочку проверок:

  • допустимость добавления нового элемента
  • соответствие ограничениям по длине и количеству
  • проверка уникальности
  • фильтрация по кастомным правилам
  • финальное подтверждение добавления

Ограничение количества выбранных элементов

Одним из ключевых параметров является maxItemCount, который задаёт верхнюю границу количества выбранных значений.

const choices = new Choices('#example', {
  maxItemCount: 5
});

При достижении лимита:

  • новые элементы не добавляются
  • ввод визуально может оставаться активным, но добавление блокируется
  • события добавления не вызываются

Типичный сценарий применения — формы с фиксированным числом тегов, категорий или участников.

Дополнительное поведение часто комбинируется с:

removeItemButton: true

что позволяет пользователю освобождать место для новых значений, не нарушая ограничение.


Ограничение длины вводимого значения

Для контроля длины текста используется параметр maxItemTextLength. Он ограничивает количество символов в каждом элементе.

const choices = new Choices('#example', {
  maxItemTextLength: 20
});

Поведение при превышении:

  • значение не добавляется в список
  • пользователь может продолжать ввод, но финализация блокируется
  • можно дополнительно визуализировать ошибку через внешнюю логику

Для более гибкого контроля иногда используется кастомная фильтрация:

const choices = new Choices('#example', {
  addItemFilter: function (value) {
    return value.length <= 20;
  }
});

Кастомная фильтрация ввода через addItemFilter

Параметр addItemFilter является одним из наиболее мощных инструментов ограничения ввода. Он позволяет полностью переопределить логику допустимости нового элемента.

const choices = new Choices('#example', {
  addItemFilter: function (value) {
    const regex = /^[a-zA-Z0-9_-]+$/;
    return regex.test(value);
  }
});

Возможности фильтра:

  • запрет символов
  • проверка формата (email, username, код)
  • ограничение по длине
  • условная логика на основе внешнего состояния

Пример комбинированной логики:

addItemFilter: function (value) {
  if (value.length < 3) return false;
  if (value.length > 15) return false;

  return /^[a-z0-9]+$/i.test(value);
}

Такой подход полностью заменяет стандартные ограничения и позволяет строить доменную валидацию прямо в компоненте.


Запрет дубликатов

Контроль уникальности реализуется через параметр duplicateItemsAllowed.

const choices = new Choices('#example', {
  duplicateItemsAllowed: false
});

При отключённой возможности дублирования:

  • повторное добавление существующего значения игнорируется
  • сравнение обычно происходит по значению строки
  • не учитываются различия в регистре (в зависимости от конфигурации и данных)

Дополнительно можно усиливать контроль через addItemFilter:

const existing = new Set();

const choices = new Choices('#example', {
  addItemFilter: function (value) {
    if (existing.has(value.toLowerCase())) {
      return false;
    }
    existing.add(value.toLowerCase());
    return true;
  }
});

Ограничение количества результатов поиска

Хотя это не прямое ограничение ввода, параметр searchResultLimit влияет на то, сколько вариантов пользователь может выбрать из доступного списка.

const choices = new Choices('#example', {
  searchResultLimit: 10
});

Это ограничение снижает когнитивную нагрузку и косвенно влияет на ввод, особенно в сценариях автодополнения.


Контроль добавления новых элементов

Параметр addItems определяет, можно ли пользователю создавать новые значения.

const choices = new Choices('#example', {
  addItems: true
});

При false:

  • разрешены только предустановленные значения
  • любой ввод вне списка игнорируется
  • поле фактически становится строго ограниченным селектором

Это один из самых жёстких способов ограничения ввода.


Перехват и валидация через события

Choices.js предоставляет событийную модель, которая позволяет реализовать внешнюю валидацию перед добавлением значения.

Основное событие:

document.querySelector('#example').addEventListener('addItem', function (event) {
  const value = event.detail.value;
});

На практике чаще используется событие addItem совместно с удалением некорректных значений:

const element = document.querySelector('#example');
const choices = new Choices(element);

element.addEventListener('addItem', function (event) {
  if (event.detail.value.includes('bad')) {
    choices.removeActiveItemsByValue(event.detail.value);
  }
});

Это позволяет реализовать пост-валидацию, когда ограничение не блокирует ввод, но корректирует состояние.


Ограничение ввода через шаблон и формат

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

Примеры типичных ограничений:

Email

addItemFilter: function (value) {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
}

Числовые значения

addItemFilter: function (value) {
  return /^\d+$/.test(value);
}

Теги без пробелов

addItemFilter: function (value) {
  return !/\s/.test(value);
}

Ограничение через максимальное число символов во вводе

Хотя Choices.js не всегда напрямую ограничивает ввод в текстовом поле на уровне DOM, можно контролировать ввод через обработку событий клавиатуры.

const input = document.querySelector('.choices__input');

input.addEventListener('input', function () {
  if (this.value.length > 10) {
    this.value = this.value.slice(0, 10);
  }
});

Такой подход используется для жёсткого контроля UX, когда визуальная часть должна соответствовать бизнес-логике без ожидания подтверждения добавления элемента.


Блокировка вставки (paste) и контроль буфера обмена

Ограничения могут распространяться и на вставку текста:

const input = document.querySelector('.choices__input');

input.addEventListener('paste', function (e) {
  const text = (e.clipboardData || window.clipboardData).getData('text');

  if (text.length > 20) {
    e.preventDefault();
  }
});

В связке с addItemFilter это формирует двойной слой защиты:

  • на уровне ввода
  • на уровне финальной проверки

Комбинированные ограничения

В реальных сценариях ограничения редко используются изолированно. Чаще формируется набор правил:

const choices = new Choices('#example', {
  maxItemCount: 5,
  maxItemTextLength: 12,
  duplicateItemsAllowed: false,
  addItems: true,
  addItemFilter: function (value) {
    return /^[a-z0-9_-]+$/i.test(value);
  }
});

Логика такого набора:

  • максимум 5 элементов
  • каждый элемент ограничен по длине
  • запрещены дубликаты
  • разрешено создание новых значений
  • допускается только строго заданный формат

Приоритеты ограничений

При одновременном использовании нескольких механизмов важно учитывать порядок срабатывания:

  1. Проверка возможности добавления (addItems)
  2. Ограничение количества (maxItemCount)
  3. Проверка дубликатов (duplicateItemsAllowed)
  4. Фильтрация addItemFilter
  5. Финальное добавление элемента
  6. Пост-обработка через события

Любое из ограничений может остановить процесс на своём уровне, не доходя до следующего шага.


Поведение интерфейса при нарушении ограничений

При срабатывании ограничений Choices.js не выбрасывает критические ошибки, а изменяет поведение интерфейса:

  • скрывает возможность добавления
  • очищает некорректный ввод
  • игнорирует события создания элемента
  • блокирует подтверждение выбора

Это делает систему устойчивой к пользовательским ошибкам и позволяет управлять логикой без разрушения UI-состояния.