Блог разработчика 1С-Битрикс

BX.selectUtils.* — управление списками <select> в 1С-Битрикс

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

Управление DOM-структурой. BX.selectUtils.*

1. Что входит в BX.selectUtils.*

Метод Назначение Ключевые параметры
addNewOption(node, value, name, sort = false, unique = true) Добавляет новую опцию sort — сразу отсортировать?
unique — проверять дубликаты?
deleteOption(node, value) Удаляет опцию с заданным value
deleteSelectedOptions(node) Удаляет все выбранные опции
deleteAllOptions(node) Полностью очищает список
sortSelect(node) Сортирует опции по тексту
selectAllOptions(node) Выделяет каждую опцию
selectOption(node, value) Выделяет опцию по value
moveOptionsUp(node) / moveOptionsDown(node) Поднимает/опускает выбранные элементы

2. Полный рабочий пример

Код ниже работает даже без установленного Битрикса благодаря мини-заглушке BX. Если вы вставляете его в реальный проект Bitrix, просто удалите блок *“BX-stub”* и подключите ядро Битрикса.


<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Демо BX.selectUtils (самодостаточный)</title>
<style>
  .panel{max-width:340px;margin:16px auto;font-family:sans-serif}
  .panel button{width:100%;margin:6px 0;padding:8px;border:1px solid #888;
    background:#f2f2f2;border-radius:4px;cursor:pointer}
  .panel button:hover{background:#e0e0e0}
  .panel select{width:100%;height:130px;margin-bottom:8px}
</style>
</head>
<body>
<div class="panel">
  <select id="demo-select" size="5"></select>
  <button id="btn-add">Добавить «По дате»</button>
  <button id="btn-del-selected">Удалить выбранное</button>
  <button id="btn-del-date">Удалить «По дате»</button>
  <button id="btn-sort">Сортировать ↑</button>
  <button id="btn-move-up">Поднять выбранное ↑</button>
  <button id="btn-move-down">Опустить выбранное ↓</button>
  <button id="btn-select-all">Выделить всё</button>
  <button id="btn-clear">Очистить список</button>
</div>
<script>
/* ----------------- BX-stub: удалить при использовании в Bitrix ---------------- */
(function(w){
  if(w.BX) return;                       // ядро уже подключено
  const $ = id => document.getElementById(id);
  const selectUtils = {
    addNewOption(node,val,text,sort=false,unique=true){
      if(unique && [...node.options].some(o=>o.value===val)) return;
      node.add(new Option(text,val));
      if(sort) this.sortSelect(node);
    },
    deleteOption(node,val){ [...node.options].forEach(o=>o.value===val && o.remove()); },
    deleteSelectedOptions(node){ [...node.selectedOptions].forEach(o=>o.remove()); },
    deleteAllOptions(node){ node.length = 0; },
    sortSelect(node){
      [...node.options]
        .sort((a,b)=>a.text.localeCompare(b.text,'ru'))
        .forEach(o=>node.add(o));
    },
    selectAllOptions(node){ [...node.options].forEach(o=>o.selected = true); },
    selectOption(node,val){ [...node.options].forEach(o=>o.selected = (o.value===val)); },
    moveOptionsUp(node){
      for(let i=1;i<node.options.length;i++){
        const cur=node.options[i], prev=node.options[i-1];
        if(cur.selected && !prev.selected) node.insertBefore(cur,prev);
      }
    },
    moveOptionsDown(node){
      for(let i=node.options.length-2;i>=0;i--){
        const cur=node.options[i], next=node.options[i+1];
        if(cur.selected && !next.selected) node.insertBefore(next,cur);
      }
    }
  };
  w.BX = Object.assign(
    function(id){ return $(id); },
    {
      ready(fn){ document.addEventListener('DOMContentLoaded',fn); },
      bind:(el,ev,fn)=>el.addEventListener(ev,fn),
      selectUtils
    }
  );
})(window);
/* ----------------------------------------------------------------------------- */
BX.ready(()=>{
  const $list = BX('demo-select');
  // начальные опции
  [
    {v:'NAME',  t:'По наименованию'},
    {v:'PRICE', t:'По цене'}
  ].forEach(o=>BX.selectUtils.addNewOption($list,o.v,o.t));
  const a={
    add:() => {
      BX.selectUtils.addNewOption($list,'DATE','По дате',false,true);
      BX.selectUtils.selectOption($list,'DATE');
    },
    delSel: () => BX.selectUtils.deleteSelectedOptions($list),
    delDate:() => BX.selectUtils.deleteOption($list,'DATE'),
    sort:   () => BX.selectUtils.sortSelect($list),
    up:     () => BX.selectUtils.moveOptionsUp($list),
    down:   () => BX.selectUtils.moveOptionsDown($list),
    all:    () => BX.selectUtils.selectAllOptions($list),
    clear:  () => BX.selectUtils.deleteAllOptions($list)
  };
  BX.bind(BX('btn-add'),'click',a.add);
  BX.bind(BX('btn-del-selected'),'click',a.delSel);
  BX.bind(BX('btn-del-date'),'click',a.delDate);
  BX.bind(BX('btn-sort'),'click',a.sort);
  BX.bind(BX('btn-move-up'),'click',a.up);
  BX.bind(BX('btn-move-down'),'click',a.down);
  BX.bind(BX('btn-select-all'),'click',a.all);
  BX.bind(BX('btn-clear'),'click',a.clear);
});
</script>
</body>
</html>
    

Как запустить:

  1. Сохраните файл под любым именем и откройте в браузере — все кнопки будут активны.
  2. Для «боевого» проекта в Битрикс удалите блок BX-stub (обёрнут в комментарии) и убедитесь, что ядро подключено.

3. Практические сценарии

Сценарий Как помогает selectUtils
Динамические фильтры в модуле CRM Создавайте поля сортировки «на лету» без перерендера страницы
Множественный перенос опций moveOptionsUp/Down ускоряет работу с длинными списками (например, настройка отчётов)
Защита от дубликатов Передавайте unique=true и избавьтесь от повторов при добавлении
Предзаполнение через AJAX deleteAllOptions перед новой подгрузкой + последующий цикл addNewOption

4. Частые ошибки и лечение

Проблема Симптом Решение
«BX is not defined» Открыли HTML вне Битрикса Подключите ядро (CJSCore::Init) или используйте stub-версию, показанную выше
Дубликаты опций При каждом клике пункт «По дате» добавляется снова Параметр unique=true или предварительная deleteOption
Ничего не удаляется Кликаете «Удалить выбранное», а список не меняется Убедитесь, что у <select> стоит multiple или используется Ctrl/Shift для выделения

5. Итоги

  • BX.selectUtils.* — это 8 небольших, но очень полезных функций для работы со списками без лишнего кода.
  • В административных разделах они избавляют от громоздких циклов appendChild/removeChild.
  • Пример выше можно копировать напрямую: он обучает, демонстрирует все методы и не требует установленного Битрикса.

Остаётся только интегрировать приёмы в ваши компоненты — и управлять DOM-структурой станет проще и быстрее!

Теги:  BX.selectUtils, управление списками, select, JavaScript, разработка, веб-разработка


Стоимость услуг по разработке и сопровождению сайтов на 1C-Битрикс

Разработка интернет-магазина с готовой версткой

от 4 недель

от 90 000 рублей

* указана минимальная стоимость. Стоимость выбранной лицензии «1С-Битрикс» оплачивается отдельно.

Перенос сайтов на «1С-Битрикс»

сайты на платформе «1С-Битрикс» — это удобство, надежность и высокая посещаемость

от 12 000 рублей
Перенос сайтов с любых CMS и статичных страниц на платформу «1С-Битрикс», с учетом дизайна, верстки и урл-адресов. С сохранением всей информации и структуры сайта.

* зависит от объема выполняемых работ.

Лечение сайтов от вирусов

восстановление сайта и подъем версии PHP

от 25 000 рублей
Лечение сайтов на решениях АСПРО и прочих.

* полный комплекс лечения проекта и закрытия дыр