Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 28.05.2008, 20:08
Интересующийся
Отправить личное сообщение для DieseL Посмотреть профиль Найти все сообщения от DieseL
 
Регистрация: 28.05.2008
Сообщений: 12

тег option <<многоуровневый>>
Добрый день!

Возможно кто то подскажет....

Задача:

Нужно реализовать такое... при загрузке страницы высвечивается два поля <option></option>, поумолчанию второе неактивно к примеру в первом поле название страны во стором название городов, нужно при выборе страны в первом списке чтобы второй становился активным и в нем вываливались города из этой страны.

Проблемы:
все данные динамичны находятся в базе mysql код страницы генерируется в php соответственно данные из базы выводятся в цикле, примеров в сети оч много но с ними проблема именно из за цикла php

подскажите пожалуйста вариант решения вопроса, сам неосилю ((
Ответить с цитированием
  #2 (permalink)  
Старый 28.05.2008, 20:35
Аватар для Gvozd
Матрос
Отправить личное сообщение для Gvozd Посмотреть профиль Найти все сообщения от Gvozd
 
Регистрация: 04.04.2008
Сообщений: 6,246

Сообщение от DieseL
примеров в сети оч много но с ними проблема именно из за цикла php
в чем проблема-то? если все правильно сделано, то должно работать.
Или я неправилно понял.
Другое дело, что это не самое оптимальное решение.
ИМХО, наилучший вариант(в случае большого количества стран и городов), это на событие изменения первого optiona повесить Ajax-функцию, которая подгружает список городов во второй option, и делает его доступным.
также, для ускорения стоит настроить кэширование этих запросов, с помощью ХТТП-заголовков. Если список городов постоянно изменяется, тогда делаем кеширование как описано в статье Умное Кеширование и Версионность в Javascript/CSS
Ответить с цитированием
  #3 (permalink)  
Старый 28.05.2008, 21:51
Отправить личное сообщение для Андрей Параничев Посмотреть профиль Найти все сообщения от Андрей Параничев
 
Регистрация: 21.02.2008
Сообщений: 1,250

Традиционно ваша задача решается так.
Есть два списка 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) .'}';
}

Последний раз редактировалось Андрей Параничев, 30.05.2008 в 15:29.
Ответить с цитированием
  #4 (permalink)  
Старый 29.05.2008, 20:41
Интересующийся
Отправить личное сообщение для DieseL Посмотреть профиль Найти все сообщения от DieseL
 
Регистрация: 28.05.2008
Сообщений: 12

Спасибо огромное за детальный ответ, в самом скрипте пару мелких ошибочек исправил, но к сожалению он не работает ((

хотя если обращаюсь напрямую к старнице по типу:

HTTPReq.open("GET", "page.php?country="+contryList.value);

тоесть обращаюсь:

page.php?country=1

то просто в тексте страницы просто высвечивается информация в таком виде:

{"new_york": "New York", "dallas": "Dallas", "city": "city"}

а список второй селект как был неактивным так и остался ((
Ответить с цитированием
  #5 (permalink)  
Старый 30.05.2008, 15:32
Отправить личное сообщение для Андрей Параничев Посмотреть профиль Найти все сообщения от Андрей Параничев
 
Регистрация: 21.02.2008
Сообщений: 1,250

DieseL,
Что-то я не понял. По адресу "page.php?country=1" и должен высвечиваться JSON ответ - это данные для JavaScript скрипта. Селект должен изменятся только на html странице, без перезагрузки страницы. А код должен быть рабочим, я вроде тестил.

В общем, щас гляну еще раз, из-за чего может не работать.
Ответить с цитированием
  #6 (permalink)  
Старый 01.06.2008, 21:42
Интересующийся
Отправить личное сообщение для DieseL Посмотреть профиль Найти все сообщения от DieseL
 
Регистрация: 28.05.2008
Сообщений: 12

Сообщение от Андрей Параничев Посмотреть сообщение
DieseL,
Что-то я не понял. По адресу "page.php?country=1" и должен высвечиваться JSON ответ - это данные для JavaScript скрипта. Селект должен изменятся только на html странице, без перезагрузки страницы. А код должен быть рабочим, я вроде тестил.

В общем, щас гляну еще раз, из-за чего может не работать.
Спасибо большое!Подкрутил чуть чуть и Все работает! ))
Ответить с цитированием
  #7 (permalink)  
Старый 02.06.2008, 11:41
Интересующийся
Отправить личное сообщение для DieseL Посмотреть профиль Найти все сообщения от DieseL
 
Регистрация: 28.05.2008
Сообщений: 12

Ужасная новость ((( Скрипт корректно работает только в Opera. В IE6, IE7, Mozilla скрипт неработает((

Что нетак?
Ответить с цитированием
  #8 (permalink)  
Старый 02.06.2008, 19:44
Отправить личное сообщение для Андрей Параничев Посмотреть профиль Найти все сообщения от Андрей Параничев
 
Регистрация: 21.02.2008
Сообщений: 1,250

DieseL,
Попробуйте заменить:
// Создаём объект асинхронной загрузки с сервера.
var HTTPReq = XMLHttpRequest ? 
          new XMLHttpRequest() : 
          new ActiveXObject("Microsoft.XMLHTTP");

На это:
try {
	var HTTPReq = new XMLHttpRequest();
} catch(e) {
	var HTTPReq = new ActiveXObject("Microsoft.XMLHTTP");
}
Ответить с цитированием
  #9 (permalink)  
Старый 03.06.2008, 10:27
Интересующийся
Отправить личное сообщение для DieseL Посмотреть профиль Найти все сообщения от DieseL
 
Регистрация: 28.05.2008
Сообщений: 12

Сообщение от Андрей Параничев Посмотреть сообщение
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">
Ответить с цитированием
  #10 (permalink)  
Старый 03.06.2008, 16:30
Отправить личное сообщение для Андрей Параничев Посмотреть профиль Найти все сообщения от Андрей Параничев
 
Регистрация: 21.02.2008
Сообщений: 1,250

DieseL,
Только что проверил код в Opera, Firefox, Ie 5, Ie5.5, Ie6. Везде работало (после замены из предыдущего сообщения). Какие именно вы изменения сделали в скрипте, и выводится ли ошибка в Ie (слева снизу восклицательный знак). Не работает частично или полностью?
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск