ФорумПрограммированиеПыхнуть хотите?F.A.Q. → Интерактивный select без перезагрузки страницы

Интерактивный select без перезагрузки страницы

  • zaxar

    Сообщения: 33 Репутация: N Группа: Кто попало

    Spritz 7 августа 2007 г. 12:24

    В последнее время часто спрашивают, как сделать «интерактивный select». Это когда есть два списка, и набор вариантов во втором списке зависит от того, что выбрано в первом. При этом, разумеется, все это должно происходить без перезагрузки страницы.

    Все это можно реализовать на чистом JavaScript, перечислив необходимые параметры в скрипте. Но что делать, если данные хранятся где-нибудь в базе или в другом месте? Тогда без дополнительного запроса на сервер не обойтись. Тогда нужно написать отдельный скрипт на PHP, который будет возвращать нужные данные, и делать к нему отдельный запрос без перезагрузки страницы.

    Делается это при помощи технологии AJAX.

    А мы рассмотрим «утилиту» для создания AJAX приложений — JsHttpRequest.

    Подробную информацию, а также исходные коды можно найти на странице http://dklab.ru/lib/JsHttpRequest/

    Жмите «Скачать исходные коды». Из скачанного архива нам понадобятся два файла: JsHttpRequest.js и JsHttpRequest.php. Как нетрудно догадаться, первый подключается к странице, откуда будет производиться запрос, а второй — к PHP-скрипту.

    Прежде чем начать, рассмотрим принцип действия. В странице, с которой идет запрос, нужно написать функцию на Javascript (предварительно подключив скачанную билиотеку). Эта функция как раз и будет посылать запрос на сервер и получать результат.

    Эта функция будет вызываться при помощи события onchange тега select.

    Схема такая: при изменении варианта в select срабатывает функция, посылает запрос на сервер, при этом в запросе передается то, что выбрано в select`e. PHP-скрипт на сервере, в зависимости от того, что было выбрано, подготавливает необходимый HTML-код другого select`a (да и не только select`a, а вообще, всего, что угодно), возвращает подготовленный HTML-код, и наша функция выведет этот код в нужное место.

    Что за «нужное место»? Все просто. На своей странице мы вставляем тег <div> с идентификатором, например, "result", в то место, где должен появиться второй select, а в функции указываем этот самый идентификатор.

    Теперь перейдем от слов к делу. Напишем пример сценария выбора сотового оператора в зависимости от страны.

    Пишем страницу select.php

    <script src="JsHttpRequest.js"></script>

    <!– Здесь мы подключили библиотеку. А теперь пишем функцию, которую назовем doload() –>

    <script>
    function doload(value){
    var req=new JsHttpRequest();
    req.onreadystatechange=function(){
    if(req.readyState==4) document.getElementById("result").innerHTML=req.responseText;}
    req.open(null,"select2.php",true);
    req.send({country:value});}
    </script>

    <!– Нетрудно догадаться, что мы сделали. Смотрите: ниже мы объявим тег select, в котором пропишем вызов функции doload с параметром this.value, то есть с выбранным в select`e значением. А вышенаписанная функция посылает запрос в скрипт select2.php и передаст ему значение country=value. Затем результат выведет в элемент с id=result. Итак, поехали… –>

    <!– Создаем форму –>

    <form action="sript.php" method="POST">

    <!– Теперь пихаем в нее первый select –>

    <select name="country" onchange="doload(this.value);">
    <option value="no" selected>Выберите страну…</option>
    <option value="russia">Россия</option>
    <option value="ukraine">Украина</option>
    </select>

    <br><br>

    <!– Вставляем тэг с нашим идентификатором, вместо которого у нас будет появляться второй select –>

    <div id="result"></div>

    <br><br>

    <!– Теперь вставляем кнопку и закрываем форму. –>

    <input type="submit" value="Отправить">

    </form>


    Все. Готово. Теперь, если открыть эту страницу и повыбирать разные значения в select`e, то… конечно же, получим ошибку, потому что у нас нет скрипта select2.php, в который мы передаем данные. Чтож, займемся его созданием.

    <?
    require("JsHttpRequest.php"); //Подключаем библиотеку
    $JsHttpRequest=new JsHttpRequest("windows-1251"); //Создаем экземпляр класса, указываю рабочую кодировку.

    //Далее все просто. В зависимости от выбранного параметра в первом select`e, заполняем переменную $html необходимым кодом.

    switch($_REQUEST["country"]):

    //Поехали…

    case "russia":
    $html="<select name=\"provider\">
    <option>МТС</option>
    <option>Билайн</option>
    <option>Мегафон</option>
    </select>";
    break;

    // С Россией разобрались. Переходим к Украине

    case "ukraine":
    $html="<select name=\"provider\">
    <option>KievGSM</option>
    <option>UKRGSM</option>
    </select>";
    break;

    //С Украиной тоже разобрались. Далее можно понапихать еще чего-нибудь (не забывая редактировать первый select в первом файле). Но мы пока закончим на этом.

    default: $html=null;
    endswitch;

    //В общем-то, все. Теперь просто выводим переменную $html, которую успешно "поймает" наша функция doload().

    echo $html;
    ?>


    Вот теперь готово.

    Как видите, HTMl-код второго select`a мы забиваем непосредственно в программу. Естественно, такое поведение не является обязательным. Ничего не мешает брать данные, например, из базы и подставлять их в нужное место. Я не буду расписывать, как это делается, так как эта тема выходит за рамки данной статьи.

    Так же я не буду расписывать, как навести «марафет». Например, как грамотно расположить элементы, чтобы ничего не разъезжалось и т.д. (по той же причине).

    Надеюсь, что статью писал не зря и она Вам поможет.

    Успехов!

    Автор статьи: Байдюк Захар
    Автор библиотеки JsHttpRequest: Котеров Дмитрий
  • dimitr

    Сообщения: 1 Репутация: N Группа: Кто попало

    Spritz 13 октября 2007 г. 7:26, спустя 66 дней 19 часов 2 минуты

    А каким образом выдрать переменной provider, в файле script.php?
  • zaxar

    Сообщения: 33 Репутация: N Группа: Кто попало

    Spritz 16 октября 2007 г. 15:21, спустя 3 дня 7 часов 54 минуты

    echo $_POST["provider"];
  • FOBOS

    Сообщения: 1 Репутация: N Группа: Кто попало

    Spritz 12 апреля 2008 г. 15:57, спустя 179 дней 36 минут

    zaxar, хорошая статья!
    Сделал в такой стилистике, только с базой. Только возникла такая ситуация: в моей задаче от значения в селекте зависят несколько (3,4) значения на форме в виде лейбл-ов, которые динамически меняються при смене опшена у селекта. Связь один селект + один лейбл я сделал, как лучше сделать связь к примеру один селект с 3-мя лейбл-ами к примеру?… или как лучше передать эти значения?

    Пока сделал несколько функций долоад , которые обрабатывают разные запросы с файлов и при ончейнже селекта вызывается несколько функций аякса…. но это как то не очень красиво, т.к. избыточный код появляется. Ещё вопрос: возможна ли заместь req.open(null,"select2.php",true);
    вызов функции которая осуществляет обработку, т.е. к примеру в select.php находятся функции запросы к базе, и я вызываю в каждой функции аякса doload отдельную функцию из файла select.php… ?
    Зарание спасибо.
  • adw0rd

    Сообщения: 22959 Репутация: N Группа: в ухо

    Spritz 12 апреля 2008 г. 22:42, спустя 6 часов 45 минут 5 секунд

    Ещё вопрос: возможна ли заместь req.open(null,"select2.php",true);
    конечно поменять можно
    req.open(null,"tra-ta-ta.php",true);
    почитай http://dklab.ru/lib/JsHttpRequest/, там все доступно для понимания :)
    https://smappi.org/ - платформа по созданию API на все случаи жизни
  • Alco

    Сообщения: 19 Репутация: N Группа: Кто попало

    Spritz 17 декабря 2008 г. 12:51, спустя 248 дней 15 часов 8 минут

    <form action="sript.php" method="POST"> что нужна написать в ентом файле?
  • adw0rd

    Сообщения: 22959 Репутация: N Группа: в ухо

    Spritz 17 декабря 2008 г. 12:57, спустя 5 минут 59 секунд

    Alco, это тебе решать, сюда придут данные из формы по сабмиту…
    https://smappi.org/ - платформа по созданию API на все случаи жизни
  • DmityrV

    Сообщения: 9 Репутация: N Группа: Кто попало

    Spritz 3 апреля 2009 г. 19:00, спустя 107 дней 5 часов 3 минуты

    Хорошая статья но вот непойму как сделать если нужно чтоб было 3 и более зависимых селекта на странице.. если не трудно можно привести пример, и ещё допустим на сервере идёт большая выборка с таблицы как сообщить об этом пользователю - типа : подождите идёт загрузка..
  • NRG

    Сообщения: 4761 Репутация: N Группа: в ухо

    Spritz 3 апреля 2009 г. 19:06, спустя 5 минут 26 секунд

    как сообщить об этом пользователю - типа : подждите идёт загрузка

    можно по разному.
    можно точечки рисовать, можно рисунок отдавать аля spinner.gif …..
    все зависит от диза
  • DmityrV

    Сообщения: 9 Репутация: N Группа: Кто попало

    Spritz 3 апреля 2009 г. 19:10, спустя 4 минуты 22 секунды

    можно по разному.


    Можно пример с кодом если не трудно, я понимаю что можно надпись можно точки… расмотрим вариант с надписью например..
  • NRG

    Сообщения: 4761 Репутация: N Группа: в ухо

    Spritz 3 апреля 2009 г. 19:23, спустя 12 минут 41 секунду

    $.ajax({type: "GET", url:'/dir/ajax.file.php?param_1='+param_1+'&param_2='+param_2,
    beforeSend: function(){
    /* здесь ставиш картинку(точечки) */
    },
    complete: function(){

    },
    success:function(data) {
    /* здесь убираешь картинку(точечки) */
    },
    error:function(){
    console.log('Some error happened');
    }
    });


    подробнее на http://docs.jquery.com/Ajax
  • NRG

    Сообщения: 4761 Репутация: N Группа: в ухо

    Spritz 3 апреля 2009 г. 19:24, спустя 53 секунды

    удачи
  • Juicy

    Сообщения: 14 Репутация: N Группа: Кто попало

    Spritz 13 апреля 2009 г. 14:36, спустя 9 дней 19 часов 12 минут

    Здравствуйте! Статья отличная, как раз то,что нужно!
    Я еще совсем новичок в этом деле, так что не ругайтесь, если что-то элементарное спрошу)))
    Вытащить данные в первом select-е из 1 таблицы удалось. У меня такой вопрос: теперь нужно чтобы во втором select-е вышли данные из 2 таблицы (отсортированные по ID первого списка).
  • adw0rd

    Сообщения: 22959 Репутация: N Группа: в ухо

    Spritz 13 апреля 2009 г. 14:56, спустя 19 минут 40 секунд

    Juicy, код в студию, посмотрим - подскажем
    https://smappi.org/ - платформа по созданию API на все случаи жизни
  • Juicy

    Сообщения: 14 Репутация: N Группа: Кто попало

    Spritz 13 апреля 2009 г. 15:04, спустя 8 минут 1 секунду

    Это то что в select2.php:

    $db = mysql_connect ("localhost", "root", "qazxcvb");
    mysql_query ("set character_set_client='cp1251'");
    mysql_query ("set character_set_results='cp1251'");
    mysql_query ("set collation_connection='cp1251_general_ci'");
    mysql_select_db("ales_tech",$db);


    require("JsHttpRequest.php");
    $JsHttpRequest=new JsHttpRequest("windows-1251");
    switch($_REQUEST["country"]):

    case "0":
    $html="<label name=\"provider\">
    $result1 = mysql_query("Gr1_Name FROM sub_grlev1 WHERE Gr1_ID like '0%'");
    $myrow1 = mysql_fetch_array($result1);
    do
    {
    printf ("ID: %s %s<br>",$myrow1['Gr1_ID'],$myrow1['Gr1_Name']);
    }
    while ($myrow1 = mysql_fetch_array($result1));
    </label>"
    break;

    case "1":
    $html="<label name=\"provider\">
    $result1 = mysql_query("Gr1_Name FROM sub_grlev1 WHERE Gr1_ID like '1%'");
    $myrow1 = mysql_fetch_array($result1);
    do
    {
    printf ("ID: %s %s<br>",$myrow1['Gr1_ID'],$myrow1['Gr1_Name']);
    }
    while ($myrow1 = mysql_fetch_array($result1));
    </label>"
    break;

    default: $html=null;
    endswitch;

Пожалуйста, авторизуйтесь, чтобы написать комментарий!