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

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

  • zaxar

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

    Spritz 7 августа 2007 г. 4: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=&quot;JsHttpRequest.js&quot;></script>

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

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

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

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

    <form action=&quot;sript.php&quot; method=&quot;POST&quot;>

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

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

    <br><br>

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

    <div id=&quot;result&quot;></div>

    <br><br>

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

    <input type=&quot;submit&quot; value=&quot;Отправить&quot;>

    </form>


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

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

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

    switch($_REQUEST[&quot;country&quot;]):

    //Поехали…

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

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

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

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

    default: $html=null;
    endswitch;

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

    echo $html;
    ?>


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

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

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

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

    Успехов!

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

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

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

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

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

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

    echo $_POST[&quot;provider&quot;];
  • FOBOS

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

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

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

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

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

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

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

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

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

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

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

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

    Alco, это тебе решать, сюда придут данные из формы по сабмиту…
    adw/0
  • DmityrV

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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


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

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

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

    удачи
  • Juicy

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

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

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

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

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

    Juicy, код в студию, посмотрим - подскажем
    adw/0
  • Juicy

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

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

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

    $db = mysql_connect (&quot;localhost&quot;, &quot;root&quot;, &quot;qazxcvb&quot;);
    mysql_query (&quot;set character_set_client=&#39;cp1251&#39;&quot;);
    mysql_query (&quot;set character_set_results=&#39;cp1251&#39;&quot;);
    mysql_query (&quot;set collation_connection=&#39;cp1251_general_ci&#39;&quot;);
    mysql_select_db(&quot;ales_tech&quot;,$db);


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

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

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

    default: $html=null;
    endswitch;

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