Опрос с помощью Ajax

Тема в разделе "Web 2.0, AJAX, Ruby, RSS технологии", создана пользователем admin, 20 мар 2006.

  1. admin

    admin Well-Known Member

    Регистрация:
    8 авг 2003
    Сообщения:
    2.811
    Симпатии:
    0
    Многие сайты проводят на своих страницах всяческие опросы пользователей. Обычно вопрос и варианты ответа на него помещается на заглавную страницу сайта, там, где его может увидеть как можно большее количество людей. Если делать механизм опроса с помощью традиционных средств HTML, то участие в нем пользователя потребует перезагрузки всей страницы. В данной статье я расскажу как можно осуществить опрос пользователей, используя модную нынче технологию AJAX.

    Ты - мне, я - тебе

    Сейчас подробно будет рассмотрен алгоритм проведения опроса и протокол взаимодействия клиента и сервера. Итак, после загрузки основной страницы, средствами JavaScript выполняется GET-запрос без параметров к серверу для получения исходных данных для проведения опроса. Сервер возвращает их в виде XML документа следующей структуры:
    Код (Text):
    <poll>
       <question>Вам сколько лет?</question>
       <choices>
          <choice>
               <text>10</text>
           </choice>
           <choice>
               <text>20</text>
           </choice>
           <choice>
               <text>Не помню</text>
           </choice>
          <choice>
               <text>А вам зачем?</text>
           </choice>
       </choices>
    </poll>
    Легко заметить, что сервер передает на клиентскую часть приложения вопрос и варианты ответа на него.

    На клиенте происходит обработка полученной информации и вывод ее на страницу. После того, как пользователь выберет один из вариантов ответа, выполняется еще один запрос GET к серверу. Но на этот раз, в качестве параметра передается индекс выбранного пользователем варианта ответа. Сервер сохраняет выбор пользователя и возвращает новый XML-документ, который содержит статистику ответов:
    Код (Text):
    <poll>
       <question>Вам сколько лет?</question>
       <choices>
           <choice>
               <text>10</text>
               <percent>38</percent>
           </choice>
           <choice>
               <text>20</text>
               <percent>20</percent>
           </choice>
           <choice>
               <text>Не помню</text>
               <percent>15</percent>
           </choice>
           <choice>
               <text>А вам зачем?</text>
               <percent>27</percent>
           </choice>
       </choices>
       <totalVoted>21760</totalVoted>
    </poll>
    В этом документе появилась информация о том, сколько процентов опрошенных выбрало тот или иной вариант ответа, и сколько всего человек приняло участие в опросе. Клиентской части приложения остается только вывести полученные данные на страницу.

    Реализация

    Сразу приведу ссылку на конечный результат: опрос. Хочу подчеркнуть, что у меня не было задачи сделать универсальный скрипт для проведения опросов. Если вы захотите использовать приведенный ниже код, то вам придется его модифицировать для того, чтобы он соответствовал вашим потребностям. Данный пример имеет минимум функциональности, но этого достаточно для иллюстрации применения AJAX для опроса пользователей сайта.

    Код серверной части рассматриваемого примера я приводить не буду. Да он и не важен. Скажу только, что на самом деле он не сохраняет результаты опроса, а генерирует их случайным образом. Уверен, что вам не составит труда реализовать серверный скрипт, возвращающий простые XML-документы, и сохраняющий результаты опроса в базе данных или в файле на сервере.

    Теперь переходим к клиентской части. Вот исходный код страницы в текстовом формате: poll.txt. Если вас смущают незнакомые теги (которые значимой роли не играют), то можете просто просмотреть HTML код работающего примера.

    Область страницы, на которой будет осуществляться вывод данных в ходе опроса, определяется тегом div, который имеет id="poll". Я не буду останавливаться на служебных функциях, которые возвращают экземпляр класса XMLHttpRequest и осуществляют с помощью него асинхронный запрос GET к серверу. Эти функции были описаны в предыдущей статье. Рассмотрим новый код:
    Код (Text):
        //CallBack-функция.
       function processResponse() {
           if (httpRequester.readyState == READY_STATE_COMPLETE) {
               if (httpRequester.status==200) {
                   processXmlResponse(httpRequester.responseXML)
               } else {
                   var message = "Problem retrieving data. requestStatus="+httpRequester.status+". Message="+httpRequester.statusText;
                   alert (message);
               }
           }
       }

       var isInit = true;

       //выполняет обработку xml-документа, полученного с сервера.
       function processXmlResponse(xmlResponse){
           if (isInit){
               initPoll(xmlResponse);
               isInit = false;
           } else {
               showResults(xmlResponse)
           }
       }
    Если при получении данных с сервера не ошибок не возникло (т.е. httpRequester.status=200), то получить их можно с помощью свойства responseXML объекта класса XMLHttpRequest. При этом они уже трактуются не как текст, а как объект XML DOM. После того, как данные получены, они передаются процедуре processXmlResponse, которая вызывает процедуру подготовки опроса или вывода результата в зависимости от того, первый это был вызов или второй. Рассмотрим процедуру initPoll:
    Код (Text):
        //создание на странице всего необходимого для проведения опроса
       function initPoll(xml){
           var divElement = document.getElementById("poll");
           divElement.appendChild(document.createTextNode(getQuestion(xml))); //добавление вопроса на страницу
           divElement.appendChild(document.createElement("br"));
           var choices = xml.documentElement.getElementsByTagName("choice");  // получение всех вариантов ответа из XML
           for (var i=0; i<choices.length;i++){
               var radioElement = createNamedElement("input", "rdChoice");    //создание radio button
               radioElement.setAttribute("type", "radio");
               divElement.appendChild(radioElement);                          //добавление radio button на страницу
               var choice = choices[i].firstChild.firstChild.data;            //полуение варианта ответа из XML
               divElement.appendChild(document.createTextNode(choice));       //добавление варианта ответа
               divElement.appendChild(document.createElement("br"));
           }
           divElement.appendChild(document.createElement("br"));
           var buttonElement = document.createElement("input");               //создание кнопки
           buttonElement.setAttribute("type", "button");
           buttonElement.setAttribute("value", "Голосовать!");
           buttonElement.onclick = vote;                                      //добавление обработчика onClick кнопки
           divElement.appendChild(buttonElement);                             //добавление кнопки на страницу
       }

       //функция возвращает вопрос извлеченный, из xml-документа с помощью DOM
       function getQuestion(xml){
           return xml.documentElement.getElementsByTagName("question")[0].firstChild.data;
       }
    Здесь все достаточно прозрачно. Сначала на странице ищется элемент div, имеющий идентификатор "poll". Затем в него помещается вопрос, варианты ответа, и кнопка, при нажатии на которую будет выполнена процедура голосования. Новые элементы создаются и добавляются на страницу с помощью HTML DOM. Данные из XML-документа, полученного с сервера, тоже извлекаются средствами DOM. Единственный момент, который требует отдельного рассмотрения, это создание элементов input типа "radio" с помощью функции createNamedElement

    Преодоление особенностей

    Как известно, реализация JavaScript отличается в разных браузерах и не всегда соответствует стандартам W3C. Такое несоответствие принято называть "особенностями" браузера. Одну из таких особенностей и придется преодолеть в ходе реализации поставленной задачи.

    Для выбора одного варианта ответа на вопрос я использовал элемент управления "radio button". Для того чтобы объединить несколько таких элементов в группу, им нужно назначить одинаковое значение атрибута name. Я выбрал значение "rdChoice". Итак, я создавал элемент input и после этого устанавливал у него name, равное "rdChoice". Проблема в том, что Internet Explorer не позволяет устанавливать значение атрибута name после того, как элемент уже был создан. Что же делать? Для того, чтобы обойти этот баг, программисты Microsoft сделали возможным создание элементов, уже имеющих некоторые аттрибуты. Как вы понимаете, таке создание элементов не описано в стандарте и поддерживается только в IE. Функция, которая создает элементы с заданным атрибутом name в любом браузере выглядит так:
    Код (Text):
        //функция возвращает новый элемент с установленным аттрибутом name
       function createNamedElement(type, name) {
           var element = null;
           // Попытка создать элемент в стиле IE. Она будет неудачной в большинстве браузеров
           try {
               element = document.createElement('<'+type+' name="'+name+'">');
           } catch (e) {
           }
           if (!element || element.nodeName != type.toUpperCase()) {
               // Для не IE; использование стандартного метода создания элемента
               element = document.createElement(type);
               element.setAttribute("name", name);
           }
           return element;
       }
    Возвращение к нашим баранам

    Теперь самое время рассмотреть процедуру vote, которая выполняется, когда пользователь выбрал один из вариантов ответа и нажал на кнопку "Голосовать!".
    Код (Text):
        function vote(){
           divElement = document.getElementById("poll");
           var index = 0;
           var selIndex = -1;
           //определение индекса выбранного ответа
           var childs = divElement.childNodes;
           for (var i=0; i<childs.length; i++){
               if (childs[i].nodeType==1){
                   if (childs[i].getAttribute("name")=="rdChoice"){
                       if (childs[i].checked){
                           selIndex=index;
                       }
                       index++;
                   }
               }
           }
           if (selIndex==-1) {
               alert ("Ни один из вариантов не выбран!");
               return;
           }
           makeAJAXCall(sUrl+"?choice="+selIndex);
       }
    Здесь тоже все довольно просто. Процедура определяет индекс выбранного пользователем варианта ответа, и выполняет асинхронный запрос к серверу, передавая параметр "choice". В ответ сервер вернет XML-документ с результатами опроса. Этот документ будет обработан процедурой showResults, которая по своему содержанию очень похожа на процедуру initPoll:
    Код (Text):
        //вывод на страницу результатов опроса
       function showResults(xml){
           var divElement = document.getElementById("poll");
           while (divElement.hasChildNodes()) divElement.removeChild(divElement.lastChild); //очищаем содержимое div'а
           divElement.appendChild(document.createTextNode(getQuestion(xml)));               //добавление вопроса на страницу
           divElement.appendChild(document.createElement("br"));
           var choices = xml.documentElement.getElementsByTagName("choice");                // получение всех вариантов ответа из XML
           for (var i=0; i<choices.length;i++){
               var choice = choices[i].firstChild.firstChild.data;                          //получение варианта ответа из XML
               var percent = choices[i].childNodes[1].firstChild.data;                      //получение процентов проголосовавших из XML
               divElement.appendChild(document.createTextNode(percent+"% - "+choice));      //добавление результата
               divElement.appendChild(document.createElement("br"));
           }
           divElement.appendChild(document.createElement("br"));
           //получение количества проголосовавших
           var totalVoted = xml.documentElement.getElementsByTagName("totalVoted")[0].firstChild.data;
           divElement.appendChild(document.createTextNode("Всего проголосовало: "+totalVoted)); //добавление на страницу
       }
    В этой статье я рассказал, как можно организовать опрос пользователей с использованием технологии AJAX. Надеюсь, этот пример поможет вам при создании опросов на вашем сайте.

    http://intenter.ru/me/articles/poll.jsp
     
Загрузка...

Поделиться этой страницей