Использование JavaScript в проектах IntraWeb.
Николай Ренжиглов ®
Использование JavaScript-кода в проектах IntraWeb не обязательно. Все
программирование может быть сведено к заданию бизнес-объектов и описанию
обработчиков событий в среде IDE Delphi. Такой путь позволяет создавать WEB-проекты любой
степени сложности. Тем не менее, поддержка работы с Java-скриптами в IW-проектах
осуществляется в достаточном объеме.
Основная цель такой поддержки общеизвестна - разгрузить сервер и перенести
обработку некоторой части логики программы на компьютер клиента.
Код серверный и код
клиентский.
Какая же часть
бизнес-кода IW-проекта выполняется на сервере, а какая на
клиентском компьютере? Для уяснения этого создадим Stand Alone - приложение с
формой, содержащей кнопку. Для обработчика нажатия кнопки запишем такой код:
procedure
TformMain.IWButton1Click(Sender: TObject);
var
f : textfile;
begin
assignfile(f,'c:\t.txt'); rewrite(f);
writeln(f,'Мама мыла раму');
closefile(f);
end;
Очевидно, что запись
файла будет выполняться на серверном компьютере: после нажатия кнопки клиентом,
администратор сервера обнаружит "неожиданно" появившийся на его
компьютере файл t.txt.
Заставим обработчик выполнять более
"безобидный" код, например:
procedure
TformMain.IWButton1Click(Sender: TObject);
begin
IWButton1.Caption:='кнопка нажата';
end;
Запустим проект и нажмем на кнопку. Текст на
кнопке изменится и, при этом мы заметим, что происходит какая-то задержка, в
течение которой WEB-страница перерисовывается. Остановим Stand Alone IW-сервер перед
нажатием кнопки (например, если проект работает в режиме отладки в Delphi, нажмем Ctrl+F2). Далее нажмем
кнопку на нашей WEB-странице и получим сообщение о том, что HTTP-сервер не найден.
Поразительно! Для того, чтоб изменить
заголовок кнопки, система использует работу IW Stand Alone-сервера c получением запроса
и возвратом новой страницы. Это представляется довольно тяжеловесным и именно
по этой причине в подобных случаях удобнее применять программирование на JavaScript.
Если вы не использовали ранее приемы WEBSnap-программирования,
то привыкание к совместному использованию Delphi и языка скриптов может
потребовать определенного времени. Однако потраченные усилия стоят того - в IW такое совместное
использование позволит вам создавать
гибкие и мощные WEB-приложения.
Запись обработчика
на JavaScript[1].
В тексте HTML-страницы мы обнаружим
следующий Java-код, имеющий отношение к нашей кнопке:
function
IWBUTTON1_OnClick(ASender) {
return
SubmitClickConfirm('IWBUTTON1','', true, '');
}
Здесь SubmitClickConfirm является некой внутренней
JScript-функцией IW
Stand Alone-сервера. Она часто используется в серверной обработке, но что
и как она делает, мы обсудим позднее. Здесь важно лишь то, что посредством
результата, возвращаемого этой функцией, в обработку события вовлекается
сервер.
Устраним из Delphi-проекта код,
обрабатывающий нажатие кнопки для того, чтоб в дальнейшем перенести его в JavaScript-часть. Для этого:
·
Полностью устраним текст обработчика TformMain.IWButton1Click в Delphi (то есть не просто закроем
комментариями или еще каким-либо образом). Важно, чтоб кода обработчика вообще
не существовало, иначе система ведет себя несколько иначе, чем ожидается.
·
В инспекторе объектов для кнопки выберем свойство ScriptEvents и для обработчика события OnClick запишем JavaScript-код:

Запустим проект на выполнение и обнаружим,
что при нажатии на кнопку программа выполняется без вовлечения в процесс
сервера. Текст HTML-страницы, имеющий отношение к нашей кнопке, теперь
выглядит так:
function
IWBUTTON1_onClick(ASender) {
ASender.value='кнопка
нажата'}
Возвращаемое значение JScript-функции не
определено, а значит система трактует его как false. Заставим функцию
возвращать значение true, для чего проделаем два исправления в коде:
·
Delphi. Восстановим обработчик TformMain.IWButton1Click и
запишем какой-либо код, требующий перезагрузки HTML-документа,
например:
procedure
TformMain.IWButton1Click(Sender: TObject);
begin
IWButton1.Caption:='кнопка нажата';
end;
·
JScript. Явно укажем, какое значение должна возвращать JScript-функция:
function
IWBUTTON1_onClick(ASender) {
ASender.value='кнопка нажата';
return true;
}
Управление будет передано сначала JScript-коду, а затем, поскольку он
вернул значение true, Delphi-обработчику события. В результате и
клиентский и серверный код будет выполнен.
Подводя итог, можно сказать, что JScript-код IW-компонента может
выполнять любой бизнес-код проекта, но если мы хотим после выполнения этого
кода на клиентском компьютере решать вопрос о вовлечении в процесс сервера,
необходимо возвращать из JScript-части значение функции true (Delphi-обработчик
выполняется, документ передается на сервер) или false (соответственно не
выполняется и не передается).
Свойство
ScriptEvents.
События ScriptEvents генерируют следующие
IW-классы:
Эти классы, в итоге, реализуют визуальные
компоненты (элементы) WEB-форм, события которых могут быть обработаны с
использованием JavaScript прямо на клиентском компьютере. Как мы видели выше,
в JavaScript-обработчике нет необходимости записывать объявления function. Эта часть кода
добавляется IW автоматически. Тем не менее, необходимость помнить
о формате передаваемых параметров, существует. Параметр ASender хранит элемент WEB-формы, событие
которого подлежит обработке. Вы можете обработать следующие общие свойства:
|
Свойство элемента |
Тип |
Описание |
|
Name |
Строковая константа |
Содержит имя элемента на WEB-форме. |
|
Value |
Строковая константа |
Содержит значение элемента |
|
default[2] |
Строковая константа |
Содержит начальное значение поля |
Множество членов (методов, событий и свойств) ASender зависит от того,
какой объект страницы вызывает обработчик. Как правило, фактическим параметром
вызова является объект this - аналог объявления self в Оbject-Pascal:
function IWBUTTON1_onClick(ASender) {
ASender.value='кнопка нажата'
}
….
Вызов из HTML-кода:
<input value="IWButton1"
name="IWBUTTON1" type="button"
onclick="return IWBUTTON1_onClick(this);"
id="IWBUTTON1"
class="IWBUTTON1CSS">
….
Таким образом, выяснить, обладает ли ASender конкретным свойством или нет, можно только запросив
перечень его свойств.
Список событий, перечисленных в свойстве JavaScript, не требует
пояснений. Все они стандартны и подробно описаны в многочисленных источниках по
JavaScript (например, [[3]]).
Вопрос возникает, например, в таком случае: что произойдет, если задать
обработчик для события, не вырабатываемого компонентом? Например, кнопка не
вырабатывает событие onChange. Это событие характерно для INPUT-компонентов формы и
вырабатывается, когда INPUT-поле теряет фокус ввода, и при этом
пользователь изменил текст, содержащийся в этом поле (такое событие в
подавляющем большинстве случаев используется для проверки данных в поле). Тем
не менее, Delphi позволяет вписать код обработчика onChange для кнопки.
Ответ в этом случае прост: ничего не
произойдет. WEB-форма просто будет содержать
функционально-избыточный код, который никогда не будет выполняться.
Свойство JavaScript для IW-формы.
JavaScript-функции могут быть
описаны в отдельном месте - свойстве формы JavaScript. Выберем это
свойство и заполним его следующим кодом, например:
function
CheckLength(ASender) {
if (ASender.value.length < 6)
{
alert("Слишком
короткое имя");
}
}
Поместим на форму строку ввода IWEdit и в его свойстве ScriptEvents зададим код для
события onChange:
CheckLength(this)
Запустим проект на выполнение и в строке ввода наберем текстовое
значение длиной менее 6 символов. При попытке переместить фокус на другой
элемент формы или вообще закрыть ее будет вырабатываться сообщение
"Слишком короткое имя". Обработка сообщения осуществляется в
модальном окне. После обработки фокус ввода сохраняется за элементом ввода,
пославшим сообщение.
Свойство JavaScript и ExtraHeader для IW-формы.
Поскольку JScript-код можно поместить в любом
месте внутри тега <Header>, свойство ExtraHeader также может быть
использовано для записи функций на языке JavaScript. В этом случае код
функций требует описания языка программирования и его версии, например:
<script
language="Javascript1.2">
function CheckLength(ASender)
{
if
(ASender.value.length < 6)
{
alert("Слишком
короткое имя");
}
}
</script>
Вызов функции посредством обработки события onChange для строки ввода
остается без изменений.
Объекты HTML-формы.
Компоненты формы в JScript- процедурах могут
быть доступны посредством их имен, определяемых в IntraWeb как ИМЯ_КОМПОНЕНТА{IWCL}. Например, строка
ввода IWEdit1 будет доступна посредством имени IWEDIT1IWCL, кнопка IWButton1 посредством IWBUTTON1IWCL и т.д. Очевидно, что эти компоненты будут иметь совершенно другие
имена для их свойств и методов, определенных в JavaScript.
Работа со свойствами
может выглядеть, например для кнопки, следующим образом:
IWBUTTON1IWCL.style.color='brown';
Подобный код может быть записан как в самом обработчике ScriptEvents для компонента, так
и в тексте JavaScript или ExtraHeader для IW-формы.
Пример работы с объектами HTML-формы и IW-компонентами.
Давайте реализуем пример передачи параметров
клиентского дисплея на IW-сервер. Эти параметры хранятся в клиентском объекте
screen, управлять которым можно используя JScript. Далее, получив эти данные
на сервере, можно определять внешний вид страниц, формируемых для отправки на клиентский компьютер.
Вообще-то эта задача более эффективно
решается с использованием hidden-полей, но для целей
демонстрации, мы изберем самый простой метод, использующий поля, видимые на
форме.
Разместим на форме Stand Alone-проекта компонент IWEdit и кнопку для
отправки формы. Раскроем список JScript-событий для кнопки и для
события onClick запишем обработчик:
IWEDIT1IWCL.value =
screen.Height;
return true;
Обработчик присваивает текстовому полю IWEdit1.Text значение высоты экрана
клиентского компьютера в пикселах. Определим public-поле для формы с
именем UserHeight, которое будет содержать переданное значение. Статус public позволит
использовать содержимое этого поля в серверном коде как этой формы, так и
других форм проекта.
type
TIWForm1 = class(TIWAppForm)
IWEdit1:
TIWEdit;
IWButton1:
TIWButton;
procedure
IWButton1Click(Sender: TObject);
public
UserHeight : string;
end;
Кроме того, зададим Delphi-обработчик для
кнопки:
procedure TIWForm1.IWButton1Click(Sender:
TObject);
begin
UserHeight:=IWEdit1.Text;
end;
Дальнейшая работа программы не требует
подробных объяснений. При нажатии на кнопку управление получает JScript-обработчик события.
Строка ввода получает значение высоты экрана в пикселах, например,
"600". Поскольку обработчик возвращает значение true, управление
передается серверу и выполняется присвоение переменной UserHeight, равное
"600" в процедуре IWButton1Click.
Таковы общие принципы взаимодействия компонентов HTML-формы и IW, а также серверного
и клиентского JScript-кода в IntraWeb-приложении.
Предопределенные
функции.
В IntraWeb разработано большое
количество JScript-функций, используемых при работе сайта. Для того,
чтоб ознакомиться с ними, вы можете использовать файлы IWCL.js_*, IWExplorer.js_*, IWCommon.js_* (здесь значок
"*" означает номер используемой IW-версии), расположенные в
папках временного хранения файлов, загруженных из интрасети. Эти функци можно
вызывать напрямую из JScript-обработчиков событий. Приведем несколько примеров.
Status(Stat). Функция отображает
текст Stat в строке статуса WEB-браузера, например,
Status("Не все поля заполнены");
FindElem(EName). Функция возвращает
объект по его имени EName. Пример использования:
var
df=FindElem("IWEDIT1");
if (df.value ==
"On")
{
df.value = "Off"
};
SubmitClickConfirm. Используется для подтверждения введенных в компоненты формы значений. Параметры вызова
следующие:
function
SubmitClickConfirm(AObjectName, AParam, ADoValidation, AConfirmation)
AObjectName - текстовое имя объекта, для которого осуществляется проверка.
AParam - параметр действия на
форме.
ADoValidation- указывает признак
того, нужна ли проверка.
AСonfirmation- строка,
отображаемая при проверке.
Эта функция вызывается автоматически, когда
вы задаёте строку Confirmation для компонента. Например, нажатие на кнопку
с определенным таким образом свойством, вызовет появление диалогового окна с
предложением подтвердить нажатие или отменить его. Любой JScript- код, записанный в
обработчике onClick не будет вызываться в случае отказа. И,
соответственно, любой код будет вызываться и форма будет отправлена на сервер в
случае подтверждения нажатия.
Можно вызвать эту функцию "вручную"
с тем же самым эффектом, вставив ее в Jscript-обработчик onClick, например:
SubmitClickConfirm("IWBUTTON1", "", true,
"Переслать форму?");
В этом случае вы получаете возможность
анализировать возвращаемый код и строить соответствующим образом JScript-часть
бизнес-логики.
Обратите внимание, что имя объекта IWBUTTON1, а также IWEDIT1 (пример для FindElem) записано в другом
формате, нежели это заданно разработчиками IW и рассмотрено в
разделе " Объекты HTML-формы ".
[1] VBScript в качестве языка скриптов в рассматриваемых версиях IW не поддерживается.
[2] Только для полей типа Input
[3] Джерри Бранденбау. "JavaScript: сборник рецептов". Издательство "Питер" 2000 год.