|
тег option <<многоуровневый>>
Добрый день!
Возможно кто то подскажет.... Задача: Нужно реализовать такое... при загрузке страницы высвечивается два поля <option></option>, поумолчанию второе неактивно к примеру в первом поле название страны во стором название городов, нужно при выборе страны в первом списке чтобы второй становился активным и в нем вываливались города из этой страны. Проблемы: все данные динамичны находятся в базе mysql код страницы генерируется в php соответственно данные из базы выводятся в цикле, примеров в сети оч много но с ними проблема именно из за цикла php подскажите пожалуйста вариант решения вопроса, сам неосилю :((( |
Цитата:
Или я неправилно понял. Другое дело, что это не самое оптимальное решение. ИМХО, наилучший вариант(в случае большого количества стран и городов), это на событие изменения первого optiona повесить Ajax-функцию, которая подгружает список городов во второй option, и делает его доступным. также, для ускорения стоит настроить кэширование этих запросов, с помощью ХТТП-заголовков. Если список городов постоянно изменяется, тогда делаем кеширование как описано в статье Умное Кеширование и Версионность в Javascript/CSS |
Традиционно ваша задача решается так.
Есть два списка select: <!-- Вызываем при изменении нашу функцию --> <select name="contry" onChange="loadList(this)"> <option value="" selected="selected"></option> <option value="rus">Россия</option> <option value="usa">США</option> </select> <select disabled="disabled" name="city" id="cityList"> <option></option> </select> Пишется код, работающий по концепции AJAX:
// Создаём объект асинхронной загрузки с сервера.
var HTTPReq = XMLHttpRequest ?
new XMLHttpRequest() :
new ActiveXObject("Microsoft.XMLHTTP");
// Устанавливаем обработчик ответа от сервера:
HTTPReq.onreadystatechange = function()
{
// Если загружено полностью:
if(HTTPReq.readyState == 4)
{
// Обрабатываем ответ:
var Cities = eval("("+HTTPReq.responseText+")");
// Заполняем список:
fillCityList(Cities);
}
}
// Запоминаем выбранную страну, чтоб не
// дублировать запросы в будущем.
var selectedContry = null;
// Функция, вызываемая при изменении списка
// (при выборе страны)
function loadList(contryList)
{
// Если выбран "пустой" вариант - очищаем список:
if(contryList.value === "")
{
clearCityList();
return;
}
// Проверяем выбрана ли уже какая-то страна:
if(selectedContry !== null)
{
// Если выбрана, проверяем не текущая ли выбрана:
if(selectedContry == contryList.value)
{
// Если текущая уже выбрана - делать нечего.
return;
}
}
// Если никакая не выбрана, или выбрана не текущая, ставим текущую.
selectedContry = contryList.value;
// Далее запрашиваем сервер на предмет списка городов выбранной страны.
// Тут должна быть ваша страница php, её работа будет описана далее:
HTTPReq.open("GET", "page.php?country="+contryList.value);
HTTPReq.send(null);
// После этого будет вызван обработчик (который мы писали ранее, так что выходим)
return true;
}
// Фукнция, которая добавляет элементы в список городов:
function fillCityList(elements)
{
// elements передан в формате JSON, так что щас он - объект
// для начала очистим текущий список городов
clearCityList();
// Уберём статус неактивен с элемента:
var cityList = document.getElementById("cityList");
cityList.disabled = false;
// Скидываем счётчик option'ов (1 - потому что первый элемент пуст)
var i = 1;
// Рассмотрим elements, в котором ключи это values, а значения - имена.
for(var key in elements)
{
// Создаём и добавляем элемент в список:
var City = new Option(elements[key], key, false, false);
cityList.options[i++] = City;
}
// Всё.
return true;
}
// Функция, которая очищает все элементы из второго списка:
function clearCityList()
{
var cityList = document.getElementById("cityList");
// Такое очищение, походу, работает во всех браузерах нормально.
while (cityList.length > 0) cityList.options[0] = null;
cityList.options[0] = new Option('', 0, false, false);
// Установим его в неактивный
cityList.disabled = "disabled";
}
PHP скрипт должен найти в базе данных городов, города из данной страны, и возвратить их назад в воспринимаемом для JavaScript виде. Лучше всего, если это будет JSON. Т.е ответ должен выглядить так:
{"new_york": "New York", "dallas": "Dallas", "city": "city"}
Допустим база данных у вас такая: | identy | name | contry | ------------- | spb | Санкт-Петербург | rus | | spb | Санкт-Петербург | rus | | ny | Нью-Йорк | usa | Тогда PHP скрипт должен быть примерно такой:
<?php
// Если не получен параметр - выходим
if(!array_key_exists('contry', $_GET)) die();
// Подключаемся к БД
mysql_connect('localhost', 'login', 'passwd');
mysql_select_db('database');
// Составляем безопасный запрос:
$query = sprintf("SELECT identy, name FROM cities_list WHERE country='%s'",
mysql_real_escape_string($_GET['country']));
// Выполняем запрос:
$result = mysql_query($query);
$output = array();
// Проходим циклом по результату
while($row = mysql_fetch_assoc($result))
{
$output[] = '"'.addslashes($row['identy'].'": "'.
'"'.addslashes($row['title']).'"';
}
// Выводим, если есть что выводить:
if(sizeof($output) > 0)
{
echo '{'. implode(',', $output) .'}';
}
|
Спасибо огромное за детальный ответ, в самом скрипте пару мелких ошибочек исправил, но к сожалению он не работает :(((
хотя если обращаюсь напрямую к старнице по типу: HTTPReq.open("GET", "page.php?country="+contryList.value); тоесть обращаюсь: page.php?country=1 то просто в тексте страницы просто высвечивается информация в таком виде: {"new_york": "New York", "dallas": "Dallas", "city": "city"} а список второй селект как был неактивным так и остался :((( |
DieseL,
Что-то я не понял. По адресу "page.php?country=1" и должен высвечиваться JSON ответ - это данные для JavaScript скрипта. Селект должен изменятся только на html странице, без перезагрузки страницы. А код должен быть рабочим, я вроде тестил. В общем, щас гляну еще раз, из-за чего может не работать. |
Цитата:
|
Ужасная новость :(((( Скрипт корректно работает только в Opera. В IE6, IE7, Mozilla скрипт неработает:(((
Что нетак? |
DieseL,
Попробуйте заменить:
// Создаём объект асинхронной загрузки с сервера.
var HTTPReq = XMLHttpRequest ?
new XMLHttpRequest() :
new ActiveXObject("Microsoft.XMLHTTP");
На это:
try {
var HTTPReq = new XMLHttpRequest();
} catch(e) {
var HTTPReq = new ActiveXObject("Microsoft.XMLHTTP");
}
|
Цитата:
<meta http-equiv="cache-control" content="no-cache"> а может заголовок документа влиять на корректность работы скрипта в ИЕ??? заголовок у меня такой: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> |
DieseL,
Только что проверил код в Opera, Firefox, Ie 5, Ie5.5, Ie6. Везде работало (после замены из предыдущего сообщения). Какие именно вы изменения сделали в скрипте, и выводится ли ошибка в Ie (слева снизу восклицательный знак). Не работает частично или полностью? |
| Часовой пояс GMT +3, время: 10:53. |
|