Иногда приходится создавать очень длинные выпадающие списки, значения которых невоз-можно установить в разметке HTML. Например список городов и стран, дней и месяцев можно задать без особых проблем. А вывести значения из БД и подставить их в выпадаю-щий список, да еще сделать список трех-четырех уровневым, да еще и без перезагрузки страницы, с использованием AJAX – уже тянет на хорошую статью.
Сегодня мы с вами займемся созданием интересного скрипта, который вы сможете в будущем установить на свой интернет-магазин. Причем я разделю статью на отдельные части, которые размещу в соответствующих разделах сайта.
Что же мы будем создавать в этих уроках:
- Создание многоуровневого выпадающего списка посредством jQuery, PHP и MySQL
- Разработка отдельных страниц для выпадающих списков разных категорий(Шины, Диски, Дворники)
- Программирование фильтра товаров для платформы openCart с использованием полученных данных.
Модуль подбора запчастей по марке авто
По порядку что нам предстоит сделать в этой главе.
- Получаем значения в виде массива для первого выпадающего списка.
- Выпадающий список получает зачения из бд, обновляет значения второго списка. Использование jQuery в нашем коде.
- Создадим отдельный файл класcа и добавим методы - функции для удобного использования нашего скрипта в будущем.
Для начала создадим файл подключения к бд.
Да, да, да. Мы будем использовать именно базу данных авто-запчастей. Практически на каж-дом втором крупном сайте программисты используют эту базу данных. В ней собраны все известные и неизвестные марки автомобилей, разбиты по годам, обьему двигателя и соб-ственно марки автомобиля.
База данных очень серьездная и в дальнейшем, для обработки данных, мы с вами будем использовать все доступные php обработчики строк, что бы эти данные использовать для поиска в интернет-магазине.
База данных каталога по подбору автозапчастей
Вот структура таблицы подбора шин и дисков:
1 //id - таблицы Acura CL //car - производитель автомобиля 2003 //year - год выпуска авто 3.2 i //modification - обьем двигателя 5*114,3 //pcd - шины 67,1 мм //diametr - шины Гайка: 14*1,5 //gaika - шины 205/60 R16 // zavod_shini - заводской размер 215/50 R17|225/45 R18|225/45 R19 //zamen_shini - варианты замены 205/60 R17 //tuning_shini - варианты тюнинга шины 6,5 x 16 ET45 //zavod_diskov - заводские размеры дисков 7 x 17 ET48|7,5 x 18 ET48 //zamen_diskov - варианты замены дисков 7 x 17 ET48| // tuning_diski - варианты тюнинга дисков
Как мы видим структура таблиц очень простая. Используются разделители строк | и # в не-которых позициях, то есть задние передние шины к примеру разделяются прямой чертой и решетка для разделения возможных установленных на заводе пар передних и пар задних шин.
Остальные таблицы немного различаются по характеристикам, но основная сортировка идет по трем, четырем критериям. Производитель, марка, год выпуска, модификация. Сделаем пример для подбора шин и дисков.
Создадим форму будущего выпадающего списка. Я выложу код и ниже пояснения. Так же буду стараться комментировать свои разработки.
//если вы заметили я вынес кнопку подтверждения отдельно от формы, если вы будете уста-навливать скрипт на готовый магазин opencart, то это пригодится, если нет. можно оставить submitt в форме.
Обычная форма, ни чего лишнего, за исключением, данной строчки:
echo $opt->ShowCategory(podbor_shini_i_diski);
Это не просто строчка - это наш отправочный пунк. Список всех производителей авто мы инициализируем при открытии нашей странички и автоматически генерируем список всех доступных автомобилей в виде следующем виде:
Выбранное пользователем значение value первого выпадающего списка мы будем сопоставлять со вторым, а второе с третим и так далее, пока не отсеим не нужные нам строки бд.
Вот как это все выглядит:
Создадим php файл, обработки и предзагрузки марки автомобиля.
class SelectList { protected $conn; //конструктор соединения с бд public function __construct() { $this->DbConnect(); } //защищенная функция соединения с бд protected function DbConnect() { //импортируем наши настройки имени пользователя, пароля и имени бд для работы с ней include "db_config.php"; $this->conn = mysql_connect($host,$user,$password) OR die("Unable to connect to the da-tabase"); //ставим кодировку utf-8 mysql_query("SET CHARACTER SET UTF8"); mysql_query("SET NAMES UTF8"); mysql_select_db($db,$this->conn) OR die("can not select the database $db"); return TRUE; } public function ShowCategory($table) { //инициализируем переменную с названием таблицы, к которой пойдет запрос, ниже я обясню где мы обьявляем её название. $this->table = $table; //делаем запрос на выбор всех производителей. Если не казать DISTINCT то выпадет количество производителей = колличеству строк $sql = "SELECT DISTINCT vendor FROM $table "; //выполняем запрос $res = mysql_query($sql,$this->conn); //формируем первое значение выпадающего списка $category = ''; //создаем цикл, который генерирует выпадающий список из списка производителей while($row = mysql_fetch_array($res)) { $category .= ''; } //возвращаем значения return $category; }
Вы наверно попробовали запустить скрипт в действие, но он еще не готов. Так как мы не вставили сгенерированные циклом данные в нашу форму. Для этого давайте подключим файл пхп с нашим написанным кодом перед формой:
include "select.class.php";
Сейчас на мой взгляд будет самая сложная часть скрипта. Я использовал библиотеку jQuery, так как она позволяет экономить кучу времени при обращении к обьектам. Не забывайте подключить её на ваш сайт.
$(document).ready(function(){ //вот и наша переменная $table - что мы использовали в php файле, то есть если запрос будет к другой таблице, мы просто меняем её значение. var table = "podbor_shini_i_diski"; //выбираем второй, третий и четвертый выпадающий список и делаем их заблокированны-ми для пользователя. Обращаемся к обектам по их id $("select#type1").attr("disabled","disabled"); $("select#year1").attr("disabled","disabled"); $("select#modification1").attr("disabled","disabled"); //Выбираем наш первый список с производителями и задаем действие, если пользователь выберет один из вариантов $("select#category1").change(function(){ //меняем выпадающий элемент марки на заблокированный $("select#type1").attr("disabled","disabled"); //меняем содержимое заблокированного элемента марки - на надпись «ждите» пока идет вы-борка из бд $("select#type1").html(""); //создаем переменную vendor и помещаем в нее выбранное пользователем значение из пер-вого списка. var vendor = $("select#category1 option:selected").attr('value'); //отправляем ассинхронный post запрос в файл select_type.php, со значениями table и vendor $.post("select_type.php", {vendor:vendor,table:table}, function(data){ //при получении данных мы убираем блокировку со второго выпадающего списка и под-ставляем значения что пришли нам с бд. $("select#type1").removeAttr("disabled"); $("select#type1").html(data); }); });
Немного сложновато, но не переживайте. Когда вы разберетесь с этим куском кода - перед вами откроется вся картина будущего скрипта. Мы вначале делаем недоступными все элементы выпадающего списка кроме первого а потом постепенно их открываем и подставляем значения что приходят нам с сервера.
Вот код недостоющего файла select_type.php:
//подключаем наш файл обработки данных include "select.class.php"; //инициализируем переменную $table[POST]. Мы приняли её методом post а в файле select.class.php работаем с ней как просто с $table. $table = $_POST["table"]; //вызываем еще не написанную функцию ShowType($table) - в качестве парамертра передаем имя таблицы. echo $opt->ShowType($table);
Всю логику можно сделать иначе и уместить в одном файле, но мне для будущих разработок понадобилось каждый post запрос отправлять в отдельный файл.
В общем дописываем недостающую функцию в наш файл select.class.php
public function ShowType($table) { $this->table = $table; //создадим переменную $vendor и присвоим её значение выбранной марки $vendor = $_POST["vendor"]; //обработаем принятые post данные во избежании иньекции $vendor = htmlspecialchars(stripslashes($vendor)); //выполним запрос к бд, обратите внимание на комманду mysql_escape_string, без нее рабо-тать не будет. $sql = "SELECT DISTINCT car FROM $table WHERE ven-dor='".mysql_escape_string($vendor)."'"; //дальше все по аналогии $res = mysql_query($sql,$this->conn); $type = ''; while($row = mysql_fetch_array($res)) { $type .= ''; } return $type; }
Пишем динамический выпадающий список на php + mysql
$("select#type1").change(function(){ $("select#year1").attr("disabled","disabled"); $("select#year1").html(""); var vendor = $("select#category1 option:selected").attr('value'); //только теперь добавляем к производителю еще и марку автомобиля var car = $("select#type1 option:selected").attr('value'); $.post("select_year.php", {vendor:vendor,car:car,table:table}, function(data){ $("select#year1").removeAttr("disabled"); $("select#year1").html(data); }); }); $("select#year1").change(function(){ $("select#modification1").attr("disabled","disabled"); $("select#modification1").html(""); var vendor = $("select#category1 option:selected").attr('value'); var car = $("select#type1 option:selected").attr('value'); //А тепереь добавим еще и год var year = $("select#year1 option:selected").attr('value'); $.post("show_modification.php", {vendor:vendor,car:car,year:year,table:table}, func-tion(data){ $("select#modification1").removeAttr("disabled"); $("select#modification1").html(data); }); });
Исходный код к обращаемым файлам select_year.php:
include "select.class.php"; echo $opt->ShowYear();
Содержание файла show_modification.php
include "select.class.php"; $table = $_POST["table"]; echo $opt->ShowModification($table);
И выкладываю недостающие куски select.class.php
public function ShowYear() { $vendor = $_POST["vendor"]; $vendor = htmlspecialchars(stripslashes($vendor)); $car = $_POST["car"]; $car = htmlspecialchars(stripslashes($car)); $sql = "SELECT DISTINCT year FROM podbor_shini_i_diski WHERE ven-dor='".mysql_escape_string($vendor)."' AND car='".mysql_escape_string($car)."'"; $res = mysql_query($sql,$this->conn); $type = ''; while($row = mysql_fetch_array($res)) { $type .= ''; } return $type; } public function ShowModification($table) { $vendor = $_POST["vendor"]; $vendor = htmlspecialchars(stripslashes($vendor)); $car = $_POST["car"]; $car = htmlspecialchars(stripslashes($car)); $year = $_POST["year"]; $year = htmlspecialchars(stripslashes($year)); $this->table = $table; //мы видим небольшое отклонение от созданных выше запросов. Дело в том что для вывода аккумуляторов и дворников нам необходимы 3 параметра, а для дисков и шин 4. Из за этого мы меняем запрос. Если имя таблицы подбор шин и дисков то... if ($table == "podbor_shini_i_diski"){ $sql = "SELECT modification FROM $table WHERE ven-dor='".mysql_escape_string($vendor)."' AND car='".mysql_escape_string($car)."' AND year='".mysql_escape_string($year)."'"; } else {$sql = "SELECT modification FROM $table WHERE ven-dor='".mysql_escape_string($vendor)."' AND car='".mysql_escape_string($car)."'";} $res = mysql_query($sql,$this->conn); $type = ''; while($row = mysql_fetch_array($res)) { $type .= ''; } return $type; }
На данном этапе мы закончили написание многоуровневого выпадающего списка посредством ajax php и mysql. Но у нас остался один обработчик нажатия кнопки подтвердить.
Надеюсь теперь вы поняли рабочую структуру скрипта. Что бы вы смогли лицезреть полную картину исходного кода и понять его работу я выкладываю исходные коды рабочего скрипта с базой шин и дисков, дворников и акб в комплекте. База запчастей актуальна на 2012 год, в том году и писался скрипт, так что не суди строго ;-)
Alex
Спасибо большое, в интернете ни кто почему то не выкладывал такой скрипт.. только продают готовые скрипты с базой. Правда дорабатывать очень много и код переписывать но все же смысл ясен. Пишите еще. Ждем 2 часть