Javascript.RU

Интеграция AJAX в интерфейс

При создании компонент интерфейса часто нужен AJAX. Например - SELECT с подгружающимся списком, поле с автозаполнением, дерево с подгружающимися узлами и т.п.

Эта статья посвящена конкретному примеру удобной и универсальной реализации AJAX для компонента интерфейса. Она дает общие рамки, можно даже сказать "фреймворк" для создания таких виджетов.

Например, рассмотрим селект, загружающий данные с сервера. С точки зрения AJAX он почти ничем не отличается от подгружающегося дерева или таблицы.

Общий поток выполнения при AJAX-подгрузке данных, начиная от пустого селекта:

Список телодвижений при загрузке:

  1. Подготовить компонент для загрузки. Для нас - очистить селект
  2. Включить индикацию AJAX (loading...)
  3. Отправить асинхронный вызов
  4. Получить ответ сервера. Обработать ошибку, если она произошла.
  5. Загрузить данные в компонент
  6. Отключить индикацию AJAX

Для создания компоненты интерфейса используем функцию, которая принимает id узла SELECT и возвращает построенный компонент.

Код настолько простой, что я привожу его сразу целиком, а чуть ниже - разбираю каждый метод по отдельности.

function ajaxSelect(id) {
    var element = document.getElementById(id)

    var onLoaded = function(data) {
        var i=0
        for(var key in data) {
            var label = data[key]
            element.options[i++] = new Option(label, key)
        }
    }
    
    var onLoadError = function(error) {
        var msg = "Ошибка "+error.errcode
        if (error.message) msg = msg + ' :'+error.message
        alert(msg)
    }
    
    var showLoading = function(on) {
        element.disabled = on
    }

    var onSuccess = function(data) {
        if (!data.errcode) {
            onLoaded(data)
            showLoading(false)        
        } else {
            showLoading(false)
            onLoadError(data)            
        }
    }
    
    
    var onAjaxError = function(xhr, status){
        showLoading(false)
        var errinfo = { errcode: status }
        if (xhr.status != 200) {
            // может быть статус 200, а ошибка
            // из-за некорректного JSON
            errinfo.message = xhr.statusText
        } else {
            errinfo.message = 'Некорректные данные с сервера'
        }
        onLoadError(errinfo)
    }

    
    return {
        load: function(url) {
            showLoading(true)

            while (element.firstChild) {
                element.removeChild(element.firstChild)
            }

            $.ajax({ // для краткости - jQuery
                url: url,
                dataType: "json",
                success: onSuccess,
                error: onAjaxError,
                cache: false
            })
        }
    }
}

Как это использовать:

  1. Создать в DOM/HTML элемент SELECT:
    <select id="ajax-select"></select>
    
  2. В javascript-коде инициализовать компонент:
    select = ajaxSelect('ajax-select')
    
  3. Например, по нажатию кнопки(onclick), вызвать загрузку:
    select.load('/ajax/ui/options.php')
    

А теперь - разберем все по порядку.

Использованный стиль описания яваскрипт-объекта описан, например, в учебнике по ООП и называется "фабрика объектов".

При стиле ООП "фабрика объектов" - приватные переменные обозначаются var, а доступные извне описываются как свойства возвращаемого return объекта.

Инициализация осуществляется непосредственно вызовом функции, без new:

select = ajaxSelect('...ID узла DOM...')

Так что функции onSuccess, onAjaxError, showLoading - приватные, а функция load - публичная.

Два первых метода onLoaded и onLoadError - основные. Любая AJAX-загрузка приводит к одному из них.

onLoaded(data)
Обрабатывает пришедшие данные. В нашем случае - заполняет ими опции селекта. Например, объект

{1:"Яблоко",2:"Дыня"}

превращается в опции селекта:

<option val="1">Яблоко</option>
<option val="2">Дыня</option>

Использованы стандартные методы работы с DOM (new Option).

onLoadError(error)
Обрабатывает любые ошибки. Объект error должен содержать свойство errcode - код ошибки, например "timeout" или "15541" и, дополнительно, может предоставлять более подробное описание ошибки в свойстве message.

В нашем примере - выдает форматированное сообщение об ошибке.

Метод индикации загрузки в примере просто включает-выключает селект.

Ничто не мешает добавить красивый анимированный значок загрузки. Желательно делать это через добавление CSS-класса к родительскому элемента select'а.

Получится что-то типа:

HTML-код для такой индикации:

<style>
.loading { 
    padding-left:20px;
    background: url(/ajax/ui/blue-loading.gif) left no-repeat;
}
</style>
<span class="loading">
<select disabled="disabled"></select>
</span>
showLoading(on)
Включает/выключает индикацию загрузки, в зависимости от значения on. Эти действия обычно похожи, поэтому удобно объединить их в один метод.

Как правило, ставит/убирает один CSS-класс.

Следующие два метода являются коллбэками для AJAX-запроса.

onSuccess(data)
Вызывается при успешном выполнении AJAX-запроса, получает прибывшие данные. Функция $.ajax автоматически интерпретирует их как JSON.

Чтобы сообщить о произошедшей ошибке, серверу достаточно передать, например, такой ответ:

{
    errcode: 500, 
    message: "Апдейт базы данных. Повторите запрос через 10 минут"
}

Обратите внимание на последовательность вызовов. Если все в порядке, то сначала вызывается обработка данных onLoaded - и только потом отключается индикация showLoading(false), чтобы посетитель увидел сразу заполненный селект.

Если произошла ошибка - удобнее сделать наоборот: сначала убрать индикацию загрузки, а затем вывести сообщение.

onAjaxError(xhr,status)
Коллбэк для ошибки при AJAX-запросе. Получает проблемный XmlHttpRequest и статус.

Вызов $.ajax автоматически интерпретирует ответ сервера как JSON - и если с этим проблемы, то хотя XmlHttpRequest выполнился успешно, но $.ajax вызывает коллбэк для ошибки и ставит status="parsererror".

Удобно то, что где бы ни произошла ошибка: во время выполнения XmlHttpRequest-запроса, или на сервере, или при разборе JSON - вызовется единый обработчик onLoadError.

Ну и, наконец, единственный публичный метод:

load(url)
Загружает данные в селект. Предварительно включает индикацию загрузки showLoading и удаляет всех детей, т.е очищает элемент.

Работающий селект можно посмотреть в действии:


Кнопки в этом примере инициализуются так:

$(document).ready(function() {
    var select = ajaxSelect('ajax-select');

    // урл, всегда выдающий пару разных фруктов
    document.getElementById('ajax-select-load-options').onclick =
        function() { select.load('/ajax/ui/options.php') }
    
    // урл, всегда выдающий ошибку
    document.getElementById('ajax-select-load-error').onclick =
        function() { select.load('/ajax/ui/error.php') }
    
});

Разумеется, никто не мешает передавать более сложный URL, добавлять туда id и другую полезную информацию.

Вы:

  • Познакомились с потоком выполнения при AJAX-загрузке данных.
  • Посмотрели, как его реализовать с унифицированной обработкой ошибок.
  • Порадовались, как прост и элегантен грамотный javascript-код.

Автор: ShUtnik, дата: 4 мая, 2009 - 01:22
#permalink

спасибо хорошая статья


Автор: Гость (не зарегистрирован), дата: 13 мая, 2009 - 03:37
#permalink

спасибо


Автор: Гость (не зарегистрирован), дата: 25 мая, 2009 - 19:21
#permalink

Сюда бы еще архивчик в конце со всеми исходниками, и было бы вообще просто супер.


Автор: Гость (не зарегистрирован), дата: 1 октября, 2009 - 13:18
#permalink

А как сделать options.php что бы он возвращал массив в стиле js?


Автор: Илья Кантор, дата: 2 октября, 2009 - 14:45
#permalink

Можно использовать кодировщик в JSON. При этом для windows-1251 лучше кодировать самому, а в UTF-8 можно из PECL взять.


Автор: Гость (не зарегистрирован), дата: 19 октября, 2009 - 09:09
#permalink

Данные возвращаются в непонятной кодировке


Автор: Гость (не зарегистрирован), дата: 23 октября, 2009 - 11:00
#permalink

Для работы с аяксом необходимо использовать только UTF, к сожалению. Сам от этого страдаю, все сайты в 1251 сделаны.


Автор: Гость (не зарегистрирован), дата: 28 июня, 2010 - 15:54
#permalink

Ну так iconv есть для этого. Сам им все строки перегоняю между браузером и БД.


Автор: Гость (не зарегистрирован), дата: 9 октября, 2012 - 17:36
#permalink

Мухахахаха


Автор: Гость (не зарегистрирован), дата: 29 ноября, 2009 - 16:28
#permalink

Можно поподробнее насчет добавления CSS-класса к родительскому элементу select'а? Как сделать его неактивным в начале работы, когда кнопка еще не нажата?


Автор: katzo (не зарегистрирован), дата: 3 февраля, 2010 - 02:37
#permalink

Не пойму, почему не работает тогда код:

<script src="http://javascript.ru/ajax/ui/ajaxselect.js"></script><select  style="width:100px" id="ajax-select"></select>
<p><input type="button" id="ajax-select-load-options" value="Загрузить опции"/><br />
<input type="button" id="ajax-select-load-error" value="Загрузить ошибку"/></p>

Как заставить это работать?!


Автор: Гарик (не зарегистрирован), дата: 12 марта, 2010 - 14:31
#permalink

Почему не работает? - очень даже работает. Проверьте в файле ajaxselect.js в строках:

$(document).ready(function() {
    var select = ajaxSelect('ajax-select');
    document.getElementById('ajax-select-load-options').onclick =
        function() { select.load('options.php') }
    
    document.getElementById('ajax-select-load-error').onclick =
        function() { select.load('error.php') }

пути к файлам options.php и error.php


Автор: Гарик (не зарегистрирован), дата: 12 марта, 2010 - 14:37
#permalink

У меня вот другая проблема. Не могу заставить работать этот пример в модальном окне facebox. Илья, подскажите пожалуйста путь решения или в каком направлении копать?


Автор: Яростный Меч, дата: 14 августа, 2010 - 20:41
#permalink

Недавно делал загрузку опшенов с сервера. Одному комбобоксу по воле судьбы полагалось 24000 оных. Вставка через дом происходила немыслимо долго в IE8 (после минуты ждать не стал). В итоге пожертвовал траффиком и идеологическими соображениями, стал грузить готовый html (строку с опшенами) и использовать вставку через innerHTML, это отрабатывает почти мгновенно.


Автор: Гость (не зарегистрирован), дата: 17 августа, 2010 - 09:38
#permalink

А как реализовать подгрузку данных сразу а не по нажатию на кнопку ?


Автор: Яростный Меч, дата: 18 августа, 2010 - 13:48
#permalink

$(function(){
/* здесь запускаем подгрузку */
});

или window.onload/DOMContentLoaded


Автор: Гость (не зарегистрирован), дата: 17 февраля, 2011 - 17:51
#permalink

Вот так работает, правда тока в IE6 =))

options.php :

<?php

$result='{1:"Дыня",2:"Яблоко"}';

header("Content-type: text/html; charset=windows-1251");

echo $result;

?>


Автор: Гость (не зарегистрирован), дата: 17 февраля, 2011 - 18:06
#permalink

под OPERA и FF

нехочет заводиться пишед данные не нравятся с сервера


Автор: Ёрка (не зарегистрирован), дата: 2 марта, 2012 - 13:43
#permalink

Выдаёт ошибку Uncaught ReferenceError: $ is not defined, строка 55 в первом листинге.

Что вообще там обозначает коммент "для краткости - jQuery"?

---
Заранее спасибо!


Автор: Юрий123456 (не зарегистрирован), дата: 10 апреля, 2012 - 15:39
#permalink

библиотеку jQuery подключи!
Да и так почитай о ней, полезно
jQuery.com


Автор: Гость (не зарегистрирован), дата: 12 мая, 2012 - 23:45
#permalink

ребят, у меня проблема. Мне нужно как то установить соединение клиента с сервером что получать текстовые обновления на экран для первого. Первое что пришло в голову это сделать так чтобы клиент каждые 5 сек запрашивал у сервака информацию об обновлении, отсюда трафик лишний. Вопрос, как сделать так чтобы при появлении обновления сервак сам отправил клиенту данные? это вопрос синхронизации(асинхронизации), или какие то широковещательные посылки должны быть, я хз. Кто понял о чём я ,отзовитесь плиз!


Автор: Гость (не зарегистрирован), дата: 26 марта, 2015 - 11:20
#permalink

Доброго времени суток

$("#los_save").click(function ()
{
/*
var data1 = $('#faz1').val();
var data2 = $('#faz2').val();
var data3 = $('#faz3').val();
var data4 = $('#faz4').val();
......
var data15 = $('#faz15').val();
*/

var fl=0;
var fl2=15;
for (var i = fl; i <= fl2; i++)
{
var data[i] = $("#faz[i]").val(); /// ???
var arr = ["data[i]", i, true]
}
$.ajax({type: "POST",url: "proba.php", data:"arr", });

});
'#faz1' - id input. Подскажите как правильно написать $("#faz[i]").val() ?


Автор: DeMItt (не зарегистрирован), дата: 5 апреля, 2015 - 18:31
#permalink
$("#"+faz[i]).val();

Автор: DeMitt (не зарегистрирован), дата: 5 апреля, 2015 - 18:34
#permalink

Тьфу. Туплю.Вот:
$("#faz"+i).val();


Автор: DeMitt (не зарегистрирован), дата: 5 апреля, 2015 - 18:36
#permalink

И у тебя нет идентификатора "faz0", поэтому начинай i не с нуля, а с единицы.


Автор: samuelddarden (не зарегистрирован), дата: 4 июня, 2019 - 13:55
#permalink

Я думаю, что вы должны написать больше на эту тему, это не может быть запретной темой, но обычно людей недостаточно, чтобы говорить на такие темы.
candy crush soda saga


Автор: Гость (не зарегистрирован), дата: 8 июня, 2019 - 12:03
#permalink

Ну так iconv есть для этого. Сам им все строки перегоняю между браузером и БД. порно Онлайн


Автор: minion89 (не зарегистрирован), дата: 14 августа, 2019 - 12:45
#permalink

The way you Integrate AJAX into the interface is simple and effective. Very good way. I appreciate your way of doing this.
word games


Автор: fnaf (не зарегистрирован), дата: 30 сентября, 2019 - 13:09
#permalink

I really like your site and especially this post with lots of good and informative information. Very helpful to me.
fnaf


Автор: pikachu (не зарегистрирован), дата: 9 июня, 2020 - 06:48
#permalink

Your article content is being very much interested, I am very impressed with your post. I hope to receive more great posts. atari breakout


Автор: poli (не зарегистрирован), дата: 14 июля, 2020 - 11:18
#permalink

This is a great thing, I think everyone feels this information is very valuable, thank you 8 ball


Автор: 먹튀검증 (не зарегистрирован), дата: 22 ноября, 2020 - 06:00
#permalink

I need to to thank you for this great read!! I absolutely enjoyed every bit of it. I have you book-marked to look at new things you post… 먹튀검증


Автор: 직장인대출 (не зарегистрирован), дата: 22 ноября, 2020 - 06:00
#permalink

This article is really a fastidious one it assists
new internet people, who are wishing in favor of blogging. 직장인대출


Автор: Jerremy Hamston (не зарегистрирован), дата: 22 января, 2021 - 11:27
#permalink

Most people know methods for getting new klingeltöne kostenlos from their cell phone carrier. Throughout the day . give you a great many of great mobile ringtones to choosefrom, however it really isn't quick cash place to find new ringers. There are a lot of websites that pay attention to mobile phone ringtones. This informationexplores top-of-the-line mobile ringtone sites out there, called Myxer. Really popular and and for good reason: custom made use and has a great selectionof ringtones.


Автор: niedersachsenladies (не зарегистрирован), дата: 22 января, 2021 - 22:31
#permalink

Great sexy chat experience only at niedersachsenladies


Автор: GarrickMaynard (не зарегистрирован), дата: 29 апреля, 2021 - 10:59
#permalink

The ringtones provided by the sound cell are exclusive and they are unique and different from the other sonnerie portable gratuite available in the market. They are modern and unique, which is why they are gaining popularity among the younger generation of mobile users. Phone ringtones are easy to download. People just need to connect their phone to the internet and download it for free and then install a ringtone on their cell phone to enjoy its high quality sound.


Автор: UK Shemale Sex (не зарегистрирован), дата: 3 июня, 2021 - 21:14
#permalink

UK Shemale Sex is the most popular web page in United Kingdom for a free chat with local girls


Автор: WinifredAmity, дата: 30 июня, 2021 - 04:15
#permalink

Download phone ringtones completely free at the website klingelton


Автор: casual sex liverpool (не зарегистрирован), дата: 17 июля, 2021 - 20:52
#permalink

Check out the best hot chat contact in UK right here right now casual sex liverpool


Автор: casual sex liverpool (не зарегистрирован), дата: 17 июля, 2021 - 20:52
#permalink

Check out the best hot chat contact in UK right here right now casual sex liverpool


Автор: Shemale Sex Ads in Belfast (не зарегистрирован), дата: 2 сентября, 2021 - 14:12
#permalink

Shemale Sex Ads in Belfast is the best web place for hot chat with young girls in United Kingdom, so check out right now and enjoy


Автор: Гость (не зарегистрирован), дата: 6 сентября, 2021 - 13:26
#permalink

Thank you very much for sharing such a useful information. I will definitely share this with others.
wuxiaworld


Автор: suiko (не зарегистрирован), дата: 9 сентября, 2021 - 06:58
#permalink

Your article is very useful, the content is great, I have read a lot of articles, but for your article, it left me a deep impression, thank you for sharing. run 3


Автор: kostenlose erotikkontakte (не зарегистрирован), дата: 20 октября, 2021 - 08:40
#permalink

kostenlose erotikkontakte is the best web place for lonley guys to find hot girls in EU check out and enjoy hot chat


Автор: deutsche frauen ficken (не зарегистрирован), дата: 20 октября, 2021 - 14:51
#permalink

deutsche frauen ficken is the best web place for lonley guys to find hot girls in EU check out and enjoy hot chat


Автор: Mia11 (не зарегистрирован), дата: 28 октября, 2021 - 13:06
#permalink

One day, fireboy and watergirl decide to take part in a quest that requires them to visit temples and locate helpful artifacts. They must collaborate to find a safe way to get through each level's challenges. Watergirl can be submerged in water whereas fireboy can touch fire. If they want to get out of these mysterious locations, they'll have to work together.


Автор: Victor Mayer (не зарегистрирован), дата: 11 ноября, 2021 - 11:30
#permalink

Soundcloud To Mp3 Downloader ist ein benutzerfreundliches Web-Tool, mit dem Sie auf Soundcloud veröffentlichte Songs im MP3-Format auf Ihr Gerät herunterladen können. Mit dem Soundcloud To Mp3 Downloader-Tool können Sie exklusive Soundcloud-Tracks schnell und absolut sicher direkt herunterladen. Darüber hinaus wird das Audio des Tracks vollständig in hoher Qualität mit 128 kbps und 320 kbps Ihrer Wahl heruntergeladen


Автор: Rosemarie (не зарегистрирован), дата: 15 ноября, 2021 - 11:57
#permalink

Perfect music, download samsung ringtones completely free at https://klingeltonmobi.de/samsung/


Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
9 + 8 =
Введите результат. Например, для 1+3, введите 4.
 
Текущий раздел
Поиск по сайту
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Последние комментарии
Последние темы на форуме
Forum