Загрузка городов через AJAX

страна

регион

город

Как это реализовано
Для начала нам нужна база городов. Скачать базу в формате SQL можно здесь.

Клиентская часть

Посмотреть клиентский код можно здесь.
AJAX у меня реализован через известную библиотеку jQuery. При выборе страны (или региона) отсылаем серверному скрипту 2 параметра методом POST:
id – id объекта (страны или региона)
type – тип списка, который нужно получить (города или регионы)

<script type="text/javascript">
function getList(type, obj) {
    $("#loading_" + type).show(); // запускаем крутящееся колесико
    $.post("/ajax/city.php", {type: type, id: $("#"+obj).val()}, onAjaxSuccess);
    function onAjaxSuccess(data) {
         out = document.getElementById(type);
         for (var i = out.length - 1; i >= 0; i--) {
              out.options[i] = null;
         }
         eval(data);
         $("#loading_" + type).hide(); // скрываем крутящееся колесико
    }
}
</script>

Во время обращения к серверному скрипту следует оповестить пользователя о том, что идет какой-либо обмен данными (показываем крутящееся колесико загрузки). Индикация во время обмена данными в Web 2.0 играет очень важную роль: посетители могли еще не привыкнуть к таким способам обновления страницы.

Серверная часть

Как только на сервер пришел запрос от клиента (параметры id и type), мы формируем либо список регионов, либо список городов и отправляем его клиенту. Список формируется в виде js-объекта Option а затем, когда ответ пришел клиенту, то этот ответ (текстовая строка) выполняется через eval и получается полноценный html-код из option. Изначально я сразу формировал html-код из option, но в одном из браузеров (по-моему, IE6) он не хотел вставляться в select, поэтому пришлось использовать извращение eval().

<?php
include($_SERVER['DOCUMENT_ROOT'].'/include/config.php');
include($_SERVER['DOCUMENT_ROOT'].'/include/db.php');

$id   = (int)$_POST['id']; // id объекта (страна или регион)
$type = $_POST['type']; // тип списка, который нужно получить (города или регионы)

sleep(1); // спешить нам некуда

if ($type == 'city') {
     // выбираем города в данном регионе
     $cities = $DB->select('SELECT *
                                    FROM city
                                    WHERE region_id = ?d
                                    ORDER BY name', $id);
     if (!empty($cities)) {
         echo "out.options[out.options.length] = new Option('выберите город...','none');\n";
         foreach ($cities as $city) {
              echo "out.options[out.options.length] = new Option('".$city['name']."','".$city['city_id']."');\n";
         }
     }
     else {
          echo "out.options[out.options.length] = new Option('нет городов','none');\n";
     }
}
if ($type == 'region') {
     // выбираем регионы в данной стране
     $regions = $DB->select('SELECT *
                                      FROM region
                                      WHERE country_id = ?d
                                      ORDER BY name', $id);
     if (!empty($regions)) {
         echo "out.options[out.options.length] = new Option('выберите регион...','none');\n";
         foreach ($regions as $region) {
              echo "out.options[out.options.length] = new Option('".$region['name']."','".$region['region_id']."');\n";
         }
     }
     else {
          echo "out.options[out.options.length] = new Option('нет регионов','none');\n";
     }
}
?>

Для выборки данных из базы я использую библиотеку DBSimple (в коде объект $DB). Вы можете легко переделать работу с базой данных под свой код. Запросы элементарные, так что разберетесь.

sleep(1) – замораживает выполнение скрипта на 1 секунду. Я это сделал специально, чтобы можно было увидеть крутящееся колесико при загрузке.

Английский язык для начинающих
#1

имели ли опыт с JSON ?
используя json, в этом примере код можно сделать менее избыточным

sikoshi, 25.04.2010 - 18:28
#2

Да, с JSON имел опыт. Но этот код писался в 2008 году, поэтому переделывать его влом:)
Кстати, JSON активно используется в Контакте.

admin, 25.04.2010 - 19:33
#3

Вконтакте не очень :)
на такие запросы они выдают готовый html, как я понимаю, закешированный в nginx

sikoshi, 25.04.2010 - 19:51
#4

Поиск людей, список друзей в Контакте сделан через JSON. По-моему даже API у них выдает списки в виде json.

admin, 25.04.2010 - 22:28
#5

Спасибо, Серёж!

Полезный у тебя сайт.
Последнее время часто натыкаюсь.

Апрель, 6.06.2010 - 21:14
#6

А нельзя выложить готовые скрипты в архиве как это было сделано с sql базой городов?

KuzyaK, 24.06.2010 - 12:50
#7

Да, где конфиг, где db.php

onthebest, 26.06.2010 - 21:38
#8

Что такое out.options[out.options.length] и где функция Option ? В каком виде должен содержаться ответ от city.php ?
в нем должен быть уже html список ?

Евгений, 9.07.2010 - 10:54
#9

Разобрался. Но така как не было библиотеки DB то воспользовался штатными средствами cms для запросов. потом еще были проблемы с кодировкой, т.к. сайт в windows-1251, но помог $id=iconv("UTF-8", "windows-1251", $id); в city.php

Евгений, 9.07.2010 - 11:50
#10

http://blog.wel.org.ua/index.php/2010/08/есть-где-взять-названия-городов-насел/

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

Валера, 30.08.2010 - 14:19