Довольно часто на сайтах встречаются данные, которые можно визуально представить в виде структуры дерева. Дерево по своей структуре предусматривает зависимость одних подчиненных элементов, от других, корневых. Иногда на формах требуется сделать зависимые списки, говоря простым языком, это когда значения одного списка зависят от выбранного значения другого. Для наглядности давайте рассмотрим пример, как можно сделать подобные списки выбора.
Задача такова, на форме должны присутствовать два выпадающих списка. Первый из них будет содержать марки автомобилей, второй будет меняться динамически посредством Ajax запросов, тем самым получая данные по конкретной модели.
Создадим три файла: cars.php, form.php, ajax.php.
В файле cars.php будут храниться данные в виде массива, этот файл нам пригодится для подключения к двум другим файлам. Файл form.php содержит форму со списками, a ajax.php будет обрабатывать Ajax-запросы отправляемые из формы.
Файл cars.php:
<?php $arModels = array( 'BMW' => array( 0 => '1-series', 1 => '2-series', 2 => '3-series', // ... ), 'Mercedes-Benz' => array( 0 => 'A-класс', 1 => 'B-класс', 2 => 'C-класс', // ... ), // и т.д. ); ?>
Ключи массива – это модели автомобилей в нашем представлении, вложенные массивы – серии для конкретных моделей.
Файл form.php:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script> <select name="model" onchange="loadCar(this)"> <option>Модель</option> <?php require_once('cars.php'); // подключаем файл с данными foreach ($arModels as $model => $series){ echo '<option value="' . $model . '">' . $model . '</option>' . "\n"; } ?> </select> <select name="series"> <option>Выберите модель</option> </select> <script> function loadCar(select){ var carSelect = $('select[name="series"]'); $.getJSON('ajax.php', { action:'getModels', model:select.value }, function(seriesList){ carSelect.html(''); $.each(seriesList, function(i){ carSelect.append('<option value="' + i + '">' + this + '</option>'); }); }); } </script>
Для работы с формой мы будем использовать JQuery фреймворк, который следует подключать перед самой формой. Первый список содержит обработчик события OnChange, он инициализирует код для запроса данных для второго списка.
Файл ajax.php:
<?php require_once('cars.php'); // подключаем файл с данными if (isset($_GET['action']) && $_GET['action'] == 'getModels'){ // проверка параметров if (isset($arModels[$_GET['model']])) // если ключ найден echo json_encode($arModels[$_GET['model']]); // возвращаем массив с данными else // иначе echo json_encode(array('Выберите марку')); die; } ?>
Файл, как ранее уже говорилось, будет отвечать на Ajax-запросы, и возвращать результат в формате Json.
Пример и исходники
UPD: В продолжение темы: как реализовать 3 зависимых списка?
Добрый день! Подскажите, как реализовать 3 зависимых списка. Третий от второго, второй от первого: 1.Марка 2.Модель 3.Модификация модели.
Спасибо!
Добрый день. Добавил ссылку на второй пост в конце статьи.
Для файла form.php я приделал форму, метод post. Для приема создал файл b.php. Вместо моделей я сделал области и связал их с городами. В результате файл b.php получает область и номер города, а не сам город. Я не знаю яваскрипт, поэтому подскажите как получать город, а не его номер.
к примеру у нас переменные:
$_POST['model'] в ней значение 'BMW';
$_POST['series'] в ней значение 2;
// подключаем файл с данными
require_once('cars.php');
// а значение элемента массива получаем так
echo $arModels[$_POST['model']][$_POST['series']]; // результат '3-series'
Здравствуйте. Тоже интересует вопрос который выше.. Никак не могу делать так, чтобы вместо вместо номера получить название серии в option value=" ". Код взял у Вас, подскажите пожалуйста где дописать ту строчку которая поможет?
Здравствуйте, для этого в js функции loadCar() нужно подправить
carSelect.append('<option value="' + this + '">' + this + '</option>');
Добрый день!
Спасибо за статью, очень помогло реализовать.
Все работает, все классно, кроме одного маленького нюанса.
Списки темизированы с помощью плагина core-ui-select
Плагин загружается с загрузкой страницы, списки красивые. Но после выбора в первом списке, второй перегружается по аяксу, и красивый дизайн сбрасывается, а поскольку страница не перегружается, то плагин и не подключается снова, и список получается уродливым.
Подскажите, что и где нужно прописать, чтобы плагин снова подгружался после аякс-перезагрузки?
Пример здесь: zaphub.ru (фильтр по моделям авто).
Добрый день. Можно попробовать вызвать
после того как список создан посредством Ajax.
Добрый день. Подскажите как сделать, чтобы эти данные извлекались из бд. В моем случае есть 2 таблицы с товаром (одежда) и размеры_цвета. Необходимо, чтобы при выборе цвета, также извлекались размеры (от выбора цвета). Спасибо!
Добрый день. Не могли бы вы описать структуру таблиц в базе
таблица tovar:
id
title
price
brand
datetime
type_tovara //здесь записывается, например футболка из type (category)
таблица category:
cat_id
type
brand
таблица colosize:
cs_id
cs_product_id //здесь записывается id тавара
cs_size
cs_color
пример заполнения для последней таблицы 3 последних столбцов
3
M
Красный
3
S
Зеленый
3
S
Синий
4
1
S
Оранжевый
1
S
Коричневый
1
M
Коричневый
1
xxl
Коричневый
1
l
Желтый
А добавляются размеры и цвета - через товар (выбираем товар, id передается методом get, через 2 inputa пишем вручную размер и цвет)
Итак, полагаю нужна таблица colosize, а конкретнее следующие поля:
cs_product_id // id товара
cs_size // размер
cs_color // цвет
Для товара нам предстоит первично узнать список доступных цветов.
1. Выбор списка доступных цветов товара. В качестве переменной изначально у нас есть ID_товара. Делаем выборку цветов из таблицы:
SELECT DISTINCT cs_color FROM colosize WHERE cs_product_id = 'ID_товара'
Команда DISTINCT - фильтрует повторяющиеся в выборке записи, таким образом, список записей будет уникальным.
2. Второй запрос подразумевает что у нас есть уже 2 переменные это: 'ID_товара' и 'значение_цвета', которые передаются посредством ajax-запроса. Выбираем доступные размеры товара согласно выбранному цвету:
SELECT cs_size FROM colosize WHERE cs_product_id = 'ID_товара' AND cs_color = 'значение_цвета'
Как в первом так и во втором случае результат передаете в json формате.
Меня также интересует как извлечь эти данные и записать их в массив?
Как вы работаете с базой данных в своем проекте? Опишите ваши методы работы с базой.
$result1 = mysql_query("SELECT * FROM tovar WHERE id='$id' ", $link);
if (mysql_num_rows($result1) > 0)
{
$row1 = mysql_fetch_array($result1);
do
{
// выводится вся информация о товаре c картинками
echo "Выберите цвет и размер";
echo "";
$result7 = mysql_query("SELECT * FROM colosize WHERE cs_product_id='$id' ORDER BY cs_color", $link);
if (mysql_num_rows($result7) > 0)
{
$row = mysql_fetch_array($result7);
do
{
echo '
'.$row["cs_color"].' - '.$row["cs_size"].'
';
}
while ($row = mysql_fetch_array($result7));
}
echo "";
}
}
while ($row1 = mysql_fetch_array($result1));
Все понял. И такой еще вопрос (немного не по теме): У меня после выбора товара передаются данные (а именно только один id корзину, которая также добавляется в бд: ее структура - cart_id, cart_id_product,cart_price,cart_count,cart_datetime,cart_ip ). Обращение идет через ссылку с классом add-cart и дополнительным аттрибутом -
tid="'.$row1["product_id"].'
Никаких форм нет, потом появится select для цвета/размера. Необходимо, чтобы в эту таблицу добавлялся cs_id через ссылку. Два javascripta :$('.add-cart').click(function(){
alert('Товар добавлен в корзину.');
var tid = $(this).attr("tid");
$.ajax({
type: "POST",
url: "include/addtocart.php",
data: "id="+tid,
dataType: "html",
cache: false,
success: function(data) {
loadcart();
}
});
});
function loadcart(){
$.ajax({
type: "POST",
url: "include/loadcart.php",
dataType: "html",
cache: false,
success: function(data) {
if (data == "0")
{
$("#block-basket > a").html("Корзина пуста");
}
else
{
$("#block-basket > a").html(data);
}
}
});
}
addtocart:
$id = $_POST["id"];
$result = mysql_query("SELECT * FROM cart WHERE cart_ip = '{$_SERVER['REMOTE_ADDR']}' AND cart_id_product = '$id'", $link);
if (mysql_num_rows($result) > 0)
{
$row = mysql_fetch_array($result);
$new_count = $row["cart_count"] + 1;
$update = mysql_query ("UPDATE cart SET cart_count='$new_count' WHERE cart_ip = '{$_SERVER['REMOTE_ADDR']}' AND cart_id_products ='$id'", $link);
}
else
{
$result = mysql_query("SELECT * FROM tovarWHERE product_id = '$id'", $link);
$row = mysql_fetch_array($result);
mysql_query("INSERT INTO cart(cart_id_products,cart_price,cart_datetime,cart_ip)
VALUES(
'".$row['product_id']."',
'".$row['price']."',
NOW(),
'".$_SERVER['REMOTE_ADDR']."'
)", $link);
}
}
Необходимо, чтобы передалось cs_id в корзину
а в этой строке
(data: "id="+tid,)
что пишется?Добавьте при выборке размеров из таблицы colosize, ещё одно поле cs_id.
Т.е. вы выбрали цвет, по ajax к вам будет возвращаться массив с cs_id и cs_size.
Формируете из этих данных такой список:
<select id="size">
<option value="cs_id">cs_size</option>
...
</size>
При добавлении в корзину так же как и параметр tid, отправляете cs_id
var cs_id = $("#size").val();
Вместо
Следует указать
Я, конечно Вас замучал), но немного не получается(. Посмотрите если я загружу листинги? Можно через обратную связь?
Ребята подскажите пожалуйста как эти файлы добавить в обычный html ничего не получается...