bool jsAjaxUtil.InsertFormDataToNode (
string|object Form obForm,
string|object DOMNode container_id,
bool bShadow)
bool jsAjaxUtil.AppendFormDataToNode (
string|object Form obForm,
string|object DOMNode container_id,
bool bShadow)
Два метода, осуществляющих динамическую отправку формы
obForm с отображением результата в контейнере
container_id . Вместо идентификатора формы или идентификатора элемента допустимо передавать ссылку на объект требуемого узла
DOM-структуры . Первый метод заменяет содержимое элемента новыми данными, второй – добавляет новые данные к имеющемуся содержимому элемента. Флаг
bShadow показывает, вызывать ли затенение элемента. Методы всегда возвращают
true . Подробнее см.
класс CAjaxForm .
Использовать методы стоит следующим образом:
В примере
MyFormCheck() - это собственный метод, осуществляющий валидацию полей формы.
bool jsAjaxUtil.SendForm (
string|object Form obForm,
object Function obHandler)
Метод осуществляет динамическую отправку формы
obForm с передачей результата обработчику
obHandler . Методу можно передавать как идентификатор формы, так и ссылку на объект формы в документе. Никаких визуальных эффектов, сопровождающих запрос, не выводится. Метод всегда возвращает
true . Использование аналогично предыдущему. Подробнее см.
класс CAjaxForm .
jsAjaxUtil . RemoveAllChild (
object DOMNode pNode)
Удаление всех дочерних узлов DOM-узла
pNode .
jsAjaxUtil.EvalGlobal (
string script)
Выполнение строки
script в контексте окна (объекта
window ).
jsAjaxUtil.EvalExternal (
string script_src)
Подключение внешнего файла сценария, расположенного по ссылке
script_src . Проверяется уникальность списка загруженных файлов – один и тот же сценарий повторно грузиться не будет.
string jsAjaxUtil.urlencode (
string str)
Аналог функции
urlencode из PHP.
string jsAjaxUtil.trim (
string str)
Аналог функции
trim из PHP.
object jsAjaxUtil.GetRealPos (
object DOMNode obNode)
Получение координат узла DOM-структуры относительно окна. Результатом является ассоциативный массив (объект), содержащий свойства
top ,
bottom ,
left ,
right .
bool jsAjaxUtil.IsIE ()
Определяет, загружена ли страница в браузере Internet Explorer.
bool jsAjaxUtil.IsOpera ()
Определяет, загружена ли страница в браузере Opera.
string jsAjaxUtil.GetStyleValue (
object DOMNode obElement,
string property)
Получение значения CSS-свойства property элемента
obElement . Учитываются как inline-стили, так и стили, создаваемые CSS-таблицей.
jsAjaxUtil.ShowLocalWaitWindow (
string TID,
string|object DOMNode obContainer,
bool bShadow)
Вывод визуализации аяксового запроса.
TID – уникальный идентификатор,
obContainer – идентификатор целевого узла DOM-структуры или ссылка на него.
bShadow – флаг, обозначающий, показывать ли затенение на целевом узле. Выводится пиктограмма в левом верхнем углу элемента, соответствующего целевому узлу, элемент затеняется (если bShadow = true).
jsAjaxUtil.CloseLocalWaitWindow (
string TID,
string|object DOMNode obContainer)
Убирает визуальные эффекты, созданные
jsAjaxUtil.ShowLocalWaitWindow() . Эффекты также убираются нажатием кнопки Esc. Если в этот момент происходил AJAX-запрос, он также отменяется.
jsAjaxUtil.UpdatePageData (
object arData)
Обновление параметров страницы на основе ассоциативного массива
arData . Элементы массива:
TITLE – новый заголовок страницы. Для того чтобы можно было заменить заголовок на странице, пришлось ввести стандарт: элемент шаблона сайта, содержащий заголовок, должен иметь идентификатор pagetitle . Если элемента с таким идентификатором на странице не найдено, будет обновлен только заголовок окна.
CSS – массив ссылок на файлы стилей, которые требуется загрузить на страницу (см. объект jsStyle )
SCRIPTS – массив ссылок на внешние файлы сценариев, которые нужно загрузить на страницу и выполнить (см. jsAjaxUtil.EvalExternal()).
Класс CAjax.
Класс CAjax – это менеджер AJAX-запросов. По умолчанию, создается экземпляр класса с именем
jsAjax , который и следует использовать. Кроме того, выше описаны методы InsertDataToNode, AppendDataToNode, LoadData, PostData объекта jsAjaxUtil, которые составляют интерфейс, позволяющий решить большинство требуемых задач без прямого обращения к объекту класса.
Внимание! Из результата автоматически вырезаются и выполняются в контексте окна клиентские сценарии. Обработчики получают уже очищенный вывод. Если в сценариях ответа создаются обработчики события window.onload , они также выполняются.
string CAjax.InitThread () – инициализация AJAX-запроса. Метод генерирует и возвращает идентификатор запроса, а также создает экземпляры классов CAjaxThread и XMLHttpRequest.
CAjax.AddAction (
string TID,
object Function obHandler) - добавление обработчика результата AJAX-запроса. Метод назначает обработчик результата запросу с идентификатором TID.
object CAjaxThread CAjax.GetThread (
string TID) – метод возвращает ссылку на экземпляр класса CAjaxThread, соответствующий AJAX-запросу с идентификатором TID.
CAjax.Send (
string TID,
string url,
object arData) – отправка AJAX-запроса методом GET с идентификатором TID на адрес url. Свойства объекта arData прикрепляются к параметрам url в виде параметров GET-запроса.
CAjax.Post (
string TID,
string url,
object arData) – отправка POST-данных AJAX-запросом с идентификатором TID на адрес url. Свойства объекта arData используются в качестве полей POST-данных.
Класс СAjaxForm.
Основная задача класса CAjaxForm – это преобразование формы для динамической отправки. Преобразование заключается в следующем: на странице создается скрытый плавающий фрейм, на него перенаправляется отправка формы. Также, к форме добавляется скрытый параметр
AJAX_CALL=Y . Результат берется из фрейма и передается обработчику. Единственное условие — результат не должен быть пустым. При работе на уровне компонентов, из результата
на сервере вырезаются все клиентские сценарии (чтобы избежать выполнения сценариев в контексте окна фрейма), которые собираются в единый пакет, отправляемый серверу.
Выше описаны методы InsertFormDataToNode, AppendFormDataToNode, SendForm объекта jsAjaxUtil, которые составляют интерфейс, позволяющий решить большинство требуемых задач, минуя непосредственную работу с объектами класса CAjaxForm.
CAjaxForm (
object Form obForm,
object Function obHandler,
bool bFirst) – конструктор класса. Входные параметры:
obForm – объект формы,
obHandler – функция-обработчик результата,
bFirst – флаг, означающий, должно ли преобразование формы быть перманентным, или должно быть отменено после первого вызова.
CAjaxForm.process () – подготовка формы, указанной в конструкторе экземпляра класса, к динамической отправке.
CAjaxForm.setProcessedFlag (
bool flag) – установка для формы флага «обработана».
bool CajaxForm.isFormProcessed (
object Form obForm) – проверка флага «обработана» для формы obForm.
Объект jsStyle
Объект jsStyle представляет собой менеджер стилей документа. Новые стили добавляются с минимальным приоритетом и могут быть перезаписаны стилями, ранее подключенными при помощи менеджера или в коде страницы. Повторно файлы стилей не загружаются, а включаются с тем же приоритетом, что и загруженные в первый раз (см. также jsAjaxUtil.UpdatePageData()).
jsStyle.Load (
string cssurl) – загрузка и подключение к документу внешнего файла стилей, расположенного по адресу cssurl.
jsStyle.Unload (
string cssurl) – отключение файла стилей cssurl.
Внимание! Некоторые браузеры обновляют отображение документа только при динамическом изменении или при добавлении новых стилей.
jsStyle.UnloadAll () – отключение всех динамически подгруженных файлов стилей.
Внимание! Некоторые браузеры обновляют отображение документа только при динамическом изменении или при добавлении новых стилей.
Объект jsEvent
Объект jsEvent представляет собой кроссбраузерный менеджер событий. При назначении событию объекта нового обработчика, все имеющиеся обработчики данного события также включаются в список. Идентификаторы событий указываются без префикса 'on', т.е., для того чтобы добавить свой обработчик MyOnload на событие onload окна, нужно вызвать
jsEvent.addEvent(window, 'load', MyOnload) . В отличие от браузерных методов, attachEvent/addEventListener менеджер выполняет обработчики событий строго в том порядке, в каком они были назначены. Если у объекта уже есть обработчики, назначенные при помощи атрибута или сценария, они будут поставлены в начало списка выполнения и также выполнятся при инициализации события.
jsEvent.addEvent (
object obElement,
string event,
object Function obHandler) – назначение обработчика
obHandler событию
event объекта
obElement .
jsEvent.removeEvent (
object obElement,
string event,
object Function obHandler) – удаление обработчика
obHandler для события
event объекта
obElement .
jsEvent.removeAllHandlers (
object obElement,
string event) – удаление всех обработчиков события
event объекта
obElement .
Внимание! Обработчики удаляются только в том случае, если объекту был назначен хоть один обработчик средствами объекта jsEvent .
jsEvent.removeAllEvents (
object obElement) – удаление всех обработчиков всех событий объекта
obElement .
Внимание! Обработчики удаляются только для тех событий, для которых объекту был назначен хоть один обработчик средствами объекта jsEvent .
jsEvent.clearObject (
object obElement) – удаление всей известной менеджеру информации объекте
obElement . Рекомендуется вызывать перед удалением объекта.
Пример:
API сервера
На сервере доступно несколько дополнительных средств для работы с AJAX:
Константа BX_AJAX_PARAM_ID содержит название REQUEST -параметра, используемого в качестве идентификатора AJAX-запроса.
Стилевое оформление визуальных эффектов AJAX настроено в файле /bitrix/templates/.default/ajax/ajax.css и, соответственно, может быть переопределено для любого шаблона сайта.
CAjax::Init () – подключение клиентской библиотеки и требуемых ей файлов стилей.
bool |string CAjax::GetSession ()– получение значения AJAX-идентификатора сессии. Если такого нет, функция возвращает false.
string CAjax::GetSessionParam ([string |bool $ajax_id = false]) – получение строки вставки идентификатора AJAX-сессии в URL. Если идентификатор не передан в параметрах функции, он берется из параметров запроса к текущей странице. Если идентификатор отсутствует, функция возвращает пустую строку.
string CAjax::AddSessionParam (string $url[, string |bool $ajax_id = false]) – вставка идентификатора AJAX-сессии в URL. Если идентификатор не передан в параметрах функции, он берется из параметров запроса к текущей странице. Если идентификатор отсутствует, функция возвращает $url без изменений. Если в запросе к текущей странице присутствует флаг динамически отправленной формы (AJAX_CALL=Y), он также будет добавлен к $url.
string CAjax::GetLink (string $url, string $text, string $container_id[, string $additional = '', bool $bReplace = true, bool $bShadow = true]) – генерация тэга ссылки, для отправки посредством AJAX. Параметры: $url – URL ссылки; $text – текст ссылки (будет пропущен через htmlspecialchars); $container_id – идентификатор контейнера на странице, куда должны быть вставлены полученные с сервера данные; $additional – дополнительные атрибуты ссылки; $bReplace – флаг, показывающий, должно ли содержимое контейнера замениться новыми данными, или добавиться к ним; $bShadow – флаг, показывающий должен ли контейнер накрываться «затенением».
Пример:
Результат:
Link "TEST"
string CAjax::GetLinkEx (string $real_url, string $public_url, string $text, string $container_id[, string $additional = '', bool $bReplace = true, bool $bShadow = true]) – расширенная версия функции CAjax::GetLink(). Параметры: $real_url – URL, по которому пойдет AJAX-запрос; $public_url – URL, который будет записан в атрибут href ссылки; $text – текст ссылки (будет вставлен непосредственно, без htmlspecialchars); $container_id – идентификатор контейнера на странице, куда должны быть вставлены полученные с сервера данные; $additional – дополнительные атрибуты ссылки; $bReplace – флаг, показывающий, должно ли содержимое контейнера замениться новыми данными, или добавиться к ним; $bShadow – флаг, показывающий, должен ли контейнер накрываться «затенением».
Пример:
TEST"', 'ajax_container');?>
Результат:
Link "
TEST "
string CAjax::GetForm (string $form_params, string $container_id, string $ajax_id[, bool $bReplace = true, bool $bShadow = true]) – получение тега формы, который будет отправлен на сервер без перезагрузки страницы. Параметры: $form_params – строка, содержащая атрибуты тега формы; $container_id – идентификатор контейнера на странице, куда должны быть вставлены полученные с сервера данные; $ajax_id – идентификатор AJAX-сессии; $bReplace – флаг, показывающий, должно ли содержимое контейнера замениться новыми данными, или добавиться к ним; $bShadow – флаг, показывающий, должен ли контейнер накрываться «затенением».
Пример:
Результат:
Если атрибуты формы содержат обработчик события
onsubmit , то это будет учтено:
Результат:
string CAjax::GetFormEvent (string $container_id[, bool $bReplace = true, bool $bShadow = true]) – получение атрибута onsubmit тега формы для динамической отправки. Параметры: $container_id – идентификатор контейнера на странице, куда должны быть вставлены полученные с сервера данные; $bReplace – флаг, показывающий, должно ли содержимое контейнера замениться новыми данными, или добавиться к ним; $bShadow – флаг, показывающий должен ли контейнер накрываться «затенением».
Tips&Tricks. Кастомизируем визуальные эффекты
Как уже было сказано ранее, стили визуальных эффектов AJAX располагаются в каталоге /bitrix/templates/.default/ajax. Соответственно, для простой модификации цветовой схемы достаточно скопировать этот каталог в каталог нужного шаблона и исправить цвета или заменить файлы изображений своими собственными. Мы же рассмотрим менее тривиальный вариант. Реализуем визуальный эффект AJAX-перехода в виде затенения всей страницы с выводом сообщения о загрузке в виде блока, расположенного посередине страницы.
Для этого, скопируем каталог с шаблонами дизайна в шаблон, для которого мы хотим модифицировать вывод. В примере это будет шаблон web20 стандартной поставки. В каталог
ajax/images скопируем картинку
progress . gif . Затем модифицируем файл
ajax / ajax . css следующим образом:
iframe.waitwindowlocal {position:absolute; border:0px; z-index:9999;}
div.waitwindowlocal {position:absolute; width:180px; padding:25px 5px 10px 5px; z-index:10000; background-color:#DADADA; border:1px solid #666666; background-image:url(images/progress.gif); background-position:center 7px; background-repeat:no-repeat; text-align: center; font-weight: bold; color: #666666; font-size: 9px;}
div.waitwindowlocalshadow {position:absolute; top: 0px; left: 0px; height: 100%; width: 100%; z-index:9998; background-color: white;}
div.waitwindowlocalshadow {opacity: 0.5; -moz-opacity: 0.5; -khtml-opacity: 0.5; filter:progid:DXImageTransform.Microsoft.Alpha(opacity=50);}
Теперь очередь за кастомизацией сценария. Создадим каталог
/bitrix/templates/web20/ js и поместим в него файл
customize _ ajax . js со следующим содержимым:
if (window.jsAjaxUtil)
{
// переопределим метод jsAjaxUtil.ShowLocalWaitWindow()
jsAjaxUtil.ShowLocalWaitWindow = function (TID, cont, bShadow)
{
if (typeof cont == 'string' || typeof cont == 'object' && cont.constructor == String)
var obContainerNode = document.getElementById(cont);
else
var obContainerNode = cont;
if (null == bShadow) bShadow = true;
var container_id = obContainerNode.id;
if (bShadow)
{
// если нужно отображать затенение - отобразим
var obWaitShadow = document.body.appendChild(document.createElement('DIV'));
obWaitShadow.id = 'waitshadow_' + container_id + '_' + TID;
obWaitShadow.className = 'waitwindowlocalshadow';
if (jsAjaxUtil.IsIE())
{
// для MSIE – раскроем тень по всей высоте содержимого окна
obWaitShadow.style.height = document.body.scrollHeight + 'px';
}
else
{
// для остального сделаем ее фиксированной
obWaitShadow.style.position = 'fixed';
}
}
// создадим сообщение о загрузке
var obWaitMessage = document.body.appendChild(document.createElement('DIV'));
obWaitMessage.id = 'wait_' + container_id + '_' + TID;
obWaitMessage.className = 'waitwindowlocal';
if (jsAjaxUtil.IsIE())
{
// для MSIE – разместим его посередине текущего отображаемого контента окна
var left = parseInt(document.body.scrollLeft + document.body.clientWidth/2 - obWaitMessage.offsetWidth/2);
var top = parseInt(document.body.scrollTop + document.body.clientHeight/2 - obWaitMessage.offsetHeight/2);
}
else
{
// для остального сделаем ее посередине окна и с фиксированным положением
var left = parseInt(document.body.clientWidth/2 - obWaitMessage.offsetWidth/2);
var top = parseInt(document.body.clientHeight/2 - obWaitMessage.offsetHeight/2);
obWaitMessage.style.position = 'fixed';
}
obWaitMessage.style.top = top;
obWaitMessage.style.left = left;
// добавим текст
obWaitMessage.innerHTML = 'Подождите, идет загрузка...';
if(jsAjaxUtil.IsIE())
{
// для IE6 и ниже создадим под сообщением плавающий фрейм
var frame = document.createElement("IFRAME");
frame.src = "javascript:''";
frame.id = 'waitframe_' + container_id + '_' + TID;
frame.className = "waitwindowlocal";
frame.style.width = obWaitMessage.offsetWidth + "px";
frame.style.height = obWaitMessage.offsetHeight + "px";
frame.style.left = obWaitMessage.style.left;
frame.style.top = obWaitMessage.style.top;
document.body.appendChild(frame);
}
// добавим обработчик нажатия клавиши Esc.
function __Close(e)
{
if (!e) e = window.event
if (!e) return;
if (e.keyCode == 27)
{
jsAjaxUtil.CloseLocalWaitWindow(TID, cont);
jsEvent.removeEvent(document, 'keypress', __Close);
}
}
jsEvent.addEvent(document, 'keypress', __Close);
}
}
Как видно, мы переопределяем метод
jsAjaxUtil.ShowLocalWaitWindow() под свои цели. Поскольку общая структура элементов остается прежней (см. оригинальный jsAjaxUtil.ShowLocalWaitWindow), то переопределять
jsAjaxUtil . CloseLocalWaitWindow нам не требуется. Остается только подключить этот файл сценария в шаблон (файл
/bitrix/templates/web20/header.php ) так, чтобы он шел после подключаемых оригинальный библиотек AJAX, то есть, после строки
ShowHeadScripts()?>
и можно просмотреть результат.
Внимание ! Если нам не нужно полное изменение ShowLocalWaitWindow , то можно поступить проще:
if (window.jsAjaxUtil)
{
jsAjaxUtil._ShowLocalWaitWindow = jsAjaxUtil.ShowLocalWaitWindow;
jsAjaxUtil.ShowLocalWaitWindow = function (TID, cont, bShadow)
{
if (null == bShadow) bShadow = true;
jsAjaxUtil._ShowLocalWaitWindow(TID, cont, bShadow);
/*
И затем производим любые манипуляции с уже созданными объектами
*/
}
}
Например, можно совершить следующие кастомизации:
замена идущей в поставке продукта "тени" на полупрозрачное затенение;
изменение цветов индикатора ajax-загрузки и добавление к нему сообщения;
изменение стиля курсора мыши на время ajax-запроса;
визуализация процесса загрузки в виде «бегающей» за курсором анимированной картинки в стиле некоторых тем Windows.