Пример Ajax приложения - Телефонная книга (клиент)


AJAX - клиентская  часть программы

Доброго всем времени суток, здравствуйте.
Продолжаю тему начатую в статье "Пример Ajax приложения Телефонная книга (сервер)".
Нам осталось рассмотреть самое интересное - клиентскую часть, то есть то что происходит на клиенте в браузере.

Для начала визуально напомню вам что мы делаем:

Имеется форма с текстовым полем в которое можно вводить данные.
Поиск можно осуществлять как по номерам(цифрам), так и по именам(буквам).

По мере того как текстовое поле заполняется автоматически подгружаются найденные соответствия цифрам или буквам значения, и все это происходит динамически, без перезагрузки HTML страницы.


Пример телефонной книги на AJAX


Введите номер


    И сразу код клиентской части на JavaScript:


    Свернуть код:
    <script type='text/javascript'> 
        //Функция возвращает объект XMLHttpRequest
    function getXmlHttpRequest(){
        if (window.XMLHttpRequest){
            try {
                return new XMLHttpRequest();
            } 
            catch (e){}
        } 
        else if (window.ActiveXObject){
            try {
                return new ActiveXObject('Msxml2.XMLHTTP');
            } catch (e){}
            try {
                return new ActiveXObject('Microsoft.XMLHTTP');
            } 
            catch (e){}
        }
        return null;
    }
        // Очистка списка
    function clearList()
    {
        var ulResult = document.getElementById("ulResult");
        while (ulResult.hasChildNodes())
            ulResult.removeChild(ulResult.lastChild);
    }
        // Добавление нового элемента списка
    function addListItem(text){
        if (text.length == 0) return;
        var ulResult = document.getElementById("ulResult");
        var li = document.createElement("li");   
        ulResult.appendChild(li);
        var liText = document.createTextNode(text);  
        li.appendChild(liText);
    }
        //Поиск совпадения
    function searchNum(){
        // Параметры поиска
        var title = document.getElementById("txtTitle").value;
        // Формирование строки поиска
        var searchString = "search=" + encodeURIComponent(title);
        // Запрос к серверу
        var req = getXmlHttpRequest();
        req.onreadystatechange = function(){
            if (req.readyState != 4) return;
            var responseText = new String(req.responseText);
            var num = responseText.split('\n');
            clearList();
            for (var i = 0; i < num.length; i++)
                addListItem(num[i]);
        }           
        // Метод POST
        req.open("POST", "./find.php", true);
        // Установка заголовков
        req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
        req.setRequestHeader("Content-Length", searchString.length);           
        // Отправка данных
        req.send(searchString);                    
    }
    </script>

    И код HTML:


    Свернуть код:
    <h2 style="text-align:center;">Пример телефонной книги на AJAX</h2><br /> <div style="border:2px solid blue; padding: 50px 0;"> <form onsubmit="return false"> <fieldset style="width: 300px; margin: 0 auto; "> <legend>Введите номер</legend> <div> <label for="txtTitle">Номер</label> <input onkeyup="searchNum()" id="txtTitle" type="text" name="title"/> </div> <button onclick="searchNum()">Поиск</button> </fieldset> </form> <ul id="ulResult" style = "list-style: none; text-align: center"></ul> </div>

    Не пугайтесь кажущемуся большому объему кода на JavaScript. На самом деле все не так страшно. Давайте разбираться.


    Обратимся сначала к функции getXmlHttpRequest():


    Свернуть код:
    //Функция возвращает объект XMLHttpRequest function getXmlHttpRequest(){ if (window.XMLHttpRequest){ try { return new XMLHttpRequest(); } catch (e){} } else if (window.ActiveXObject){ try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch (e){} try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch (e){} } return null; }

    В ней то, собственно, происходит самое главное, а именно фомируется объект ХMLHttpRequest, который выполняет AJAX запрос, и в случае удачного создания сам этот объект и возвращается оператором return . А в противном случае в блоках try catch генерируются исключения которые "гасят" возникающие ошибки.

    Замечу, что тема исключений очень интересная и я непременно к ней вернусь.

    А проверки на наличие объектов window.XMLHttpRequest и window.ActiveXObject в операторах if нужны для для обеспечения кросс-браузерности кода, так как механизм создания объекта отличается для разных браузеров.

    В IE 5—6 она реализована через ActiveXObject, а в остальных браузерах (IE 7 и выше, Mozilla, Opera, Chrome, Netscape и Safari) — как встроенный объект типа XMLHttpRequest.

    Хотя по моему глубокому убеждению на IE 5-6 давно пора "забить", и тогда фактически от всей функции останется только одна строчка кода:

    return new XMLHttpRequest()


    Едем дальше! А дальше унас функция searchNum():


    Свернуть код:
        //Поиск совпадения
    function searchNum(){
        // Параметры поиска
        var title = document.getElementById("txtTitle").value;
        // Формирование строки поиска
        //var searchString = "search=" + title ;
        var searchString = "search=" + encodeURIComponent(title);
        // Запрос к серверу
        var req = getXmlHttpRequest();
        req.onreadystatechange = function(){
            if (req.readyState != 4) return;
            var responseText = new String(req.responseText);
            var num = responseText.split('\n');
            clearList();
            for (var i = 0; i < num.length; i++)
                addListItem(num[i]);
        }           
        // Метод POST
        req.open("POST", "./find.php", true);
        // Установка заголовков
        req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
        req.setRequestHeader("Content-Length", searchString.length);           
        // Отправка данных
        req.send(searchString);                    
    }
    

    которая и занимается поиском совпадений введенного поискового запроса.


    Сначала получаем значение поискового запроса:
    // Параметры поиска
       var title = document.getElementById("txtTitle").value;

    Затем формируем строку запроса (REQUEST_URI):
      // Формирование строки поиска
     var searchString = "search=" + encodeURIComponent(title);

    Обращаю ваше внимание на функцию encodeURIComponent(title), которая кодирует компоненты строки запроса (URI), заменяя некоторые символы escape-последовательностями, представляющими эти символы в кодировке UTF-8.

    Дальше создаем экземпляр класса XMLHttpRequest:
    var req = getXmlHttpRequest();

    И через свойство класса - onreadystatechange (пишем все маленькими бкувами ), которое отслеживает смену состояния объекта, навешиваем на это событие -

    исполняемую функцию:
     req.onreadystatechange = function(){
            if (req.readyState != 4) return;
            var responseText = new String(req.responseText);
            var num = responseText.split('\n');
            clearList();
            for (var i = 0; i < num.length; i++)
                addListItem(num[i]);
        }

    Суть которой предельно проста. Если свойство объекта readyState не равно 4 , то есть данные не загружены (0 — не инициализирован, 1 — открыт, 2 — отправка данных, 3 — получение данных и 4 — данные загружены), ничего не делаем и возвращаемся из функции.

    В противном же случае, если у нас все получилось, создаем объект responseText - экземпляр класса String, в который помещаем полученный через свойство responseText объекта req - (req.responseText) текст.

    Дальше используя метод split, который возвращает массив, разбивая полученную строку текста по разделителю '/n'. Помните я говорил вам в первой части статьи, что он нам еще понадобится?

    Тем самым мы отделяем одно полученное значение от другого. Ведь от сервера то мы получили одну большую строку!

    Затем вызываем функцию clearList(), которая очищает выведенную ранее информацию, удаляя в цикле whille элементы вложенные в элемент ul с идентификатором id="ulResult". Подробно разобраться как она работает предлагаю вам самостоятельно.

    После того как мы очистили выведенную ранее информацию, уже в цикле for вызываем функцию addListItem(), которая построчно выводит в браузер эдементы li, содержащие текстовые значения сформированного split - ом массива.

    Я надеюсь, для вас не новость, что в JavaScript мы можем динамически формировать некоторые элементы?

    Похожий пример был продемонстрирован в статье Обработка формы на JavaScript (часть2) в подрубрике: Списки вариантов (объекты Select и Option).

    Ну а далее сама отправка данных на сервер:
    // Метод POST
        req.open("POST", "./find.php", true);
        // Установка заголовков
        req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        req.setRequestHeader("Content-Length", searchString.length);           
        // Отправка данных
        req.send(searchString);

    Быстро пробежимся по коду:
    Метод open определяет метод POST , URL по которму мы обращаемся с запросом (адрес нашего обработчика на php) и другие опциональные параметры запроса.
    Метод setRequestHeader добавляет HTTP-заголовок к запросу, а отправляет данные метод send.

    На этом с JavaScript все! А код HTML, в котором ничего особо сложного нет, я оставляю вам для самостоятельного разбора.

    Ну вот и закончили! Как вам? Есть вопросы - задавайте. А на этом сегодня все. До свидания.

    Автор: Сергей Зарубин

    Дата: 2012-03-16

    Колличество просмотров: 6656

    Нравится

    Комментарии к заметке:

    Комментарий добавил(а): Rottenwood
    Дата: 2013-02-11

    Спасибо за статью!



    Добавить новый комментарий


    Введите число с картинки:

    captcha