Не ослабевает интерес к вопросу о динамическом создании связанных выпадающих HTML списков. Для двух зависимых списков (я публиковал пример более 5 лет назад!) ситуация простая и понятная, но люди задают вопрос — а как развить пример для вложения 3х списков?
Ответ — никак. :) Придется менять практически все, потому слово — менять тут не подходит. Я решил написать универсальный пример, который будет работать с любой вложенностью списков.
Так как вложенность у нас не ограничена, то в произвольном случае мы имеем не многомерную таблицу — а дерево вариантов. Т.е. где то мы углубимся на три уровня, а где — то только на один.
Входной массив данных потребуется сильно изменить. Теперь это не плоский массив, многоуровневая матрешка из объектов и массивов. Структура матрешки весьма условна, может быть изменена, но для примера нужно было сформулировать то, как мы описываем данные. Иначе как написать программу?
Описание задачи
Мы имеем дело с гипотетическим прайсом на услуги заправки картриджей, где сначала надо выбрать марку принтера, потом модель принтера, далее — срочность заправки; и тогда вы получите справку о стоимости услуг. Но в некоторых случаях может оказаться, что модель принтера или срочность оказания услуг — не важны, то есть мы сразу должны показать цены.
Структура данных
Начнем с описания структуры данных. Самый нижний уровень матрешки описывает первый уровень, первый из выпадающих списков.
Это заголовок и массив опций-объектов.
1 2 3 4 5 6 |
{ //заголовок перед списком title: "Марка принтера", //массив опций options : [{}, {}, ...] } |
Опций могут быть двух типов по тому, как они ведут себя при их выборе:
- показывается следующий уровень выпадающего списка (добавляется еще один html select),
- показывается информация о ценах.
Для первого случая мы должны задавать объект в списке options в виде:
1 2 3 4 5 6 7 8 9 |
{ //текстовая метка опции label: 'Brother', //описание следующего уровня SELECT select: { title: "Модель", options : [{}, {}, ...] } } |
Описание следующего уровня устроено точно также как и предыдущий уровень.
Второй случай — это конечный «листок» на дереве прайса. Все поля очень условны. К примеру, без поля data — вообще можно обойтись. Но мы же делаем какую то универсальную процедуру :), потому я предусмотрел задание произвольного набора данных для конечного пункта выбора.
1 2 3 4 5 6 7 8 9 |
{ //значение - у нас это название картриджа value: 'HL7600', //текстовая метка опции label: 'Brother HL-5040', //произвольные данные data: [{'label': 'Цена за картридж, менее 5 шт ', 'value': 500}, {'label': 'Цена заправки, начиная с 5-го картриджа', 'value': 470}] }, |
Верстка (требования к макету)
Скрипт выполнен в виде js-класса. Он работает с двумя HTML контейнерами (у меня это — DIV), ID которых нужно указать при инициализации. Ещё на вход нужно передать данные в виде описанной выше структуры прайса.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<div id="selector"> <!-- Здесь будут выпадающие списки --> </div> <div id="result"> <!-- Здесь будет карточка прайса по выбранной услуге --> </div> //класс-функция, которая выполняет работу со связанными списками function TSEL(ids, idr, data) { this.data = data; ... } //создание и инициализация объекта var TS = new TSEL("selector", "result", priceData); |
Кроме того, класс использует библиотеку jQuery. Если у вас она не подключена, то добавьте следующий html код (до инициализации TSEL):
1 |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> |
Версия библиотеки особого значения не имеет.
Полный код скрипта можно взять тут. Скачайте его методом — сохранить как — это файл с расширением html.
Действующий пример динамических селектов произвольной вложенности
Поиграйте с прайсом, чтобы понять как он работает. Наверное, самое сложное теперь -подготовить данные прайса :).
Логическим продолжением темы является реализация с использованием запроса данных по ajax.
Здравствуйте! А как в скрипте ограничить выпадающий список?
А что значит «ограничить»?