Связанные списки select с получением данных по ajax

В прошлый раз я показывал как можно «на лету» создавать списки html select, данные которых содержались в специальном javascript массиве.

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

База данных

Начнем с создания структуры данных.

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

Для этого я создал две таблички — tree и items.

Таблица tree будет содержать иерархию связанных пунктов для выпадающий списков.

tree-table

treeID — ключ, pID — указатель на родительский пункт, label — текстовая метка для выпадающего списка, а objID — указатель в таблицу items, для конечных элементов дерева.

В таблице items мы разместим описания видов вооружений.

items-table

Описание весьма условное. Кроме ключа в таблице есть title — название вооружения и какие то два параметра, которые мы вообще никак не характеризуем. :)

HTML код

Практически идентичен прошлому примеру.

Мы подключаем библиотеку jQuery и класс — TSEL, создающий связанные списки. TSEL работает с двумя HTML контейнерами, идентификаторы которых мы передадим при инициализации TSEL. Третьим параметром будет url к файлу сервера для обработки ajax запросов.

Javascript создающий списки

Файл tsel.js, подключаемый в секции head содержит класс-функцию объекта, который запрашивает данные на сервере и создаёт в нашем документе связанные выпадающие списки.

Давайте рассмотрим его, не вникая в подробности реализации.

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

Мы имеем дело всего с пятью функциями. Две из них грузят и показывают очередной уровень select-а, ещё две — делают тоже самое для карточки вооружений. А оставшаяся функция реализует логику : какую пару задействовать при выборе пункта списка.

PHP код, реализующий работу сервера

В PHP у нас производится отработка команд клиента, запросы к базе данных. Запросов всего два:

  • вернуть список опций ветки дерева, по указанному айди родителя (команда load-brunch),
  • вернуть данные об единице вооружения (команда load-object).

Надеюсь, загрузка данных пояснений не требует. :)

Результат

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

Мне не хотелось создавать лишние таблицы в базе сайта. Потому я ограничусь комментариями к скринам.

Сразу после инициализации появится первый из выпадающих списков. Как видите, он состоит из названий видов вооружений.

first-level-select-dynamic

Выбирая варианты, вы будете открывать следующий уровень. Я выбрал guns (надо было назвать его cannons или artillery :)) и получил следующий набор вариантов — это уже конечные элементы в моем примере.

guns-select

Потому при выборе одного из пунктов загрузились данные объекта.

cannon-2c5

Если с пунктом не связан объект, а также не удалось найти дочерние элементы списка — выскочит alert с надписью — «Ветка пуста!».

Вложенность ничем не ограничена. Кроме того, ветки и листочки могут располагаться на одном уровне.

Архив файлов и скрипт базы данных.

Скачать без регистрации и СМС :)

Архив содержит 5 файлов:

files

Настройки подключения к вашей базе данных введите в файле db.php. Скрипт для создания таблиц и дамп данных — в test_base.sql. Остальные файлы вы уже знаете.

Написать комментарий

Мало букафф? Читайте есчо !

Анимация смены картинок с помощью jquery

Декабрь 26, 2012 г.

Ещё одна типовая задача, для которой найдено приличное решение. Типично суть задачи состоит в следующем. Есть набор изображений, которые демонстрируются поочередно в некотором контейнере. Ставится задача по анимации периодической смены этих картинок средствами ...

Читать

Fancybox прокручивает основное окно к верху

Июль 13, 2016 г.

Сталкивался с таким поведением плагина fancybox. При открытии модального окна, происходит прокрутка в основном окне к самому верху. Как с этим бороться? Это происходит не всегда, а при некоторых случаях верстки. Верстку уже менять проблематично, ...

Читать

 

Комментарии к «Связанные списки select с получением данных по ajax»

Понравилась статья? Есть вопросы? - пишите в комментариях.



Комментарий:

Много комментариев в “Связанные списки select с получением данных по ajax”

  1. Graf_vorontsov:

    Классную штуку вы написали, но всётаки я не пойму, а если у меня не 2, а 3 или 5 таблиц в БД, то как мне поступить? Вы говорите что скрипт ваш сам ищет вложенность… но это получается не вложенность, а просто разные таблицы. Та куда вписывать запрос обращения к другим таблицам?
    case ‘load-brunch’:
    тут выбираем из одной таблицы
    case ‘load-object’:
    выводит данные на экран

    а как выбирать из остальных таблиц, если они есть?
    Спасибо заранее за ответ.

    • Можно не разделять таблицы items и tree, такое разделение предпочтительно в плане нормализации данных. Потому речь идет не о 2х таблицах, а по сути об одной — tree.

      Таблица tree нужна для хранения иерархии объектов (в данном случае в виде дерева). В ней мы связываем дочерние и родительские элементы. Каждому элементу дерева сопоставляем pID — parent ID или родительский ID. Т.е. нам не нужно 100500 таблиц для хранения иерархии дерева — нужна всего одна.

      Если нужно иметь несколько «объектных» таблиц (items), связанных в одном дереве, то простейшее решение — добавить в tree еще один столбец — entity_type, который будет указывать тип сущности для ObjID.

      • Graf_vorontsov:

        ну всеравно я не пойму как оно подтянет данные из третьей таблицы
        вот у меня есть 3 таблицы
        brands (id, brand_name)
        models (id = brands.id, model_name)
        autos(id = brands.id, auto_name)

        т.е. у меня все три таблицы имеют связь по id, но всеравно чтоб получить данные из каждой, я даю запрос к каждой, и выпадающий список строю сначала из первой, потом из второй на основании первой, а потом третья на основании второй.
        Вот я и не пойму как это реализовать. Или мне надо создать ещё таблицу в которой будут указаны все id и ссылки на дочерние таблицы?

      • :)
        Можно начать с добавления столбца типа объектов в таблицу tree. Второй шаг — адаптировать к работе скрипт, т.к. нужно передавать на сервер дополнительно параметр типа объекта, чтобы программа знала из какой таблицы брать данные. Но надо подумать нужно ли это в вашем случае?

        Можно ведь обойтись таблицей autos, объекты которой является конечной целью выбора.

        Например, у нас есть два бренда — Audi, BMW, по одной модели в каждом и 2 машины, вот как примерно выглядит дерево (tree):

        treeID|pID|label|objID
        1|0|Audi|NULL
        2|0|BMW|NULL
        3|1|A3 Sedan|NULL
        4|2|BMW X4|NULL
        5|3|A3 Sedan 2015 б/у|1
        6|3|A3 Sedan 2017 новая|2

        А это таблица autos:
        ID|title|descr
        1|A3 Sedan 2015 б/у|эта машинка уже с пробегом
        2|A3 Sedan 2017 новая|а эта новьё

        Вам не надо связывать нижние уровни дерева с какими либо объектами — они служат как бы для навигации.

  2. Graf_vorontsov:

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

    • Дерево хранит данные не о сущностях, а о об их иерархии. Сущности — отдельно, структура связей между ними — отдельно. Ценность словаря брендов не меняется.

      Если у вас есть уже какая то сложная база данных с взаимосвязами объектов, и иерархию можно рассчитать используя эти связи, то таблица tree заполняется (рассчитывается) благодаря этим данным.

      • Graf_vorontsov:

        собрал дерево…
        проблема в следующем, не могу запустить даже ваш пример
        вылетает ошибка «Shit happens! error»

      • Попробуйте запустить проект, разместив его в рамках какого то веб-сервера. Можно взять Denver или OpenServer. А то, мне кажется, вы просто распаковали файлы в случайную папку и жмете на index.html ;)

        А еще нужно создать базу данных и настроить к ней подключение…

      • Graf_vorontsov:

        #Попробуйте запустить проект, разместив его в рамках какого то веб-сервера. Можно взять Denver или OpenServer. А то, мне кажется, вы просто распаковали файлы в случайную папку и жмете на index.html ;)

        А еще нужно создать базу данных и настроить к ней подключение…#

        ахаха ))) вы думаете я совсем чтоли? )))
        Denwer c MySQL всё установлено, базу вашу залил. но не работает. Сейчас появилась возможность попробовать на другом компе, счас отпишусь что получилось.

      • Graf_vorontsov:

        вот скрин посмотрите, это уже на абсолютно другом компе
        http://picua.org/?v=2017-06-03_zk2b0h5xtf452j02yobzb2en7.png
        ошибка та же

      • На вкладке браузера network посмотрите, что с сервера приходит при ajax запросе. Ошибаться там в php, по сути негде, возможно, в php выключена поддержка коротких тегов (допишите вместо < ? - < ?php).

      • Graf_vorontsov:

        ошибка у вас в коде была, наверное случайно слэш поставили
        ajaxUrl: «ajax.php»});
        а было так
        ajaxUrl: «/ajax.php»});

        и оно не находило этот файл
        сейчас заработало когда слэш убрал

      • Ну, отлично, не зря столько писанины :)