====== Секция описания запросов экранной формы ======
[[start:|lss]] | [[form-definition]]
===== Введение =====
На уровне [[form-definition|экранной формы]] можно описывать [[request|запросы]], отправляемые [[form-definition|экранной формой]] на сервер.
Во первых, можно влиять на внешний вид экранных элементов, нажатие на которые вызывает отправку [[request|запроса]]. Это параметры **caption**, **icon**, **description**. И динамически вычисляемые **js_caption**, **js_icon**, **js_description** соответственно.
Во вторых, можно влиять на доступность выполнения [[request|запроса]], это параметр **enabled** и его динамически вычисляемый вариант **js_enabled**.
Можно перед вызовом [[request|запроса]] требовать подтверждения пользователем, это параметр **confirm** и **js_confirm** соответственно.
Можно связывать выполнение [[request|запроса]] с нажатием комбинации клавиш на клавиатуре, это параметр **key**.
Важный параметр **save="1"** вызывает принудительную отписку не сохраненных изменений перед выполнением [[request|запроса]], если такие изменения есть.
Описанный в этой секции [[request|запрос]] с именем **onshow** автоматически вызывается при открытии [[form-definition|экранной формы]], а **onclose** при закрытии.
Но самая востребованная возможность - описание цепочки последовательно вызываемых с клиента [[request|запросов]]. Элементы цепочки вызываются последовательно. В случае, если очередной [[request|запрос]] возвращает ошибку, выполнение цепочки прерывается.
===== Общий вид секции запросов =====
...
...
===== Имя запроса, rowset =====
* Главный параметр [[request|запроса]] - имя **name**. У некоторых [[request|запросов]] есть дополнительный атрибут - подрежим **mode**.
* Если у [[request|запроса]] задан параметр **rowset**, то по нему определяется, где именно [[request|запрос]] описан и кто его будет выполнять.
* **rowset**=**<имя набора строк формы>** - [[request|запрос]] связан с этим [[rowset-definition|набором строк]]. Из него будет взято описание [[request|запроса]], [[rowset-definition|набор строк]] определит доступность выполнения [[request|запроса]].
* **rowset**="#form" - [[request|запрос]] описан в секции **requests** [[form-definition|экранной формы]]. Если там такого [[request|запроса]] нет, то выполнение [[request|запроса]] недоступно.
* Если **rowset** не задан, обработка идет по мягкому сценарию. Если из контекста можно понять, о каком [[rowset-definition|rowset]] идет речь, и этот **rowset** понимает этот [[request|запрос]], то описание и выполнение [[request|запроса]] перенаправляется туда. Иначе проверяется секция **requests** [[form-definition|экранной формы]]. Если и там описания [[request|запроса]] нет, то [[request|запрос]] считается корректным и отправляется на сервер. При этом предполагается, что [[request|запрос]] будет на сервере обработан контроллером [[form-definition|экранной формы]].
Рассмотрим пример:
* [[request|запрос]] с именем **do-anythig** описан на уровне секции **requests** [[form-definition|экранной формы]]. Его можно вызвать из управляющих экранных элементов формы, сославшись на это имя. Он не связан ни с каким [[rowset-definition|rowset]]. Это [[request|запрос]] - цепочка. Он будет последовательно выполнять вложенные в него [[request|запросы]].
* [[request|запрос]] с именем **exec-rebuild**. Этот [[request|запрос]] нигде не описан, у него не задан [[rowset-definition|rowset]]. LSS клиент ничего об этом [[request|запросе]] не знает, но предполагает, что его на сервере умеет обрабатывать контроллер экранной формы. Прямо внутри этого [[request|запроса]] описаны передаваемые [[request|запросом]] параметры.
* [[request|запросы]] name="refresh" для rowset="table1" и rowset="table2" отсылают к [[rowset-definition|наборам строк]] **table1** и **table2**. Эти [[rowset-definition|наборы строк]] должны быть описаны в разделе **rowsets** описания [[form-definition|экранной формы]]. Особенности выполнения и параметры [[request|запросов]] берутся из них.
Общий смысл этого примера - выполнить на сервере, в контроллере экранной формы, пересчет. А затем, для корректного отображения результатов, перечитать изменившиеся данные.
===== Внешний вид управляющих экранных элементов, доступность, подтверждение =====
Расширим наш пример атрибутами, влияющими на внешний вид управляющих экранных элементов:
[[request|Запрос]] **do-anything** можно вызвать из управляющих экранных элементов. Соответственно, в описании [[request|запроса]] можно прописать отображаемые параметры:
* **caption** - название [[request|запроса]], многие управляющие экранные элементы умеют его отображать.
* **description** - подробное описание [[request|запроса]], обычно оно высвечивается при наведении мышки на управляющий экранный элемент.
* **icon** - иконка, многие управляющие экранные элементы умеют ее отображать.
* **confirm** - если параметр задан, то перед выполнением [[request|запроса]] отображается диалог, требующий подтверждения пользователя.
Эти параметры можно задавать не только статически, но и динамически:
Обычно, динамические выражения вычисляются на основе значений полей [[rowset-definition|rowset]]. Если выражение сложное, и его неудобно описывать в атрибуте XML узла, можно вынести его в раздел **script**, описав внутри функцию на языке JavaScript. В примере так сделано для динамического вычисления значения **icon**. Важный динамический параметр **js_enabled** определяет доступность выполнения [[request|запроса]].
===== Вызов запроса по горячей клавише =====
[[request|Запросом]], объявленным в секции requests, можно назначить комбинацию горячих клавиш, обеспечив вызов [[request|запроса]] с клавиатуры.
Для этого используется атрибут **key**. Его значение - код нажатой клавиши в сочетании с названиями вспомогательных клавиш: **ctrl**, **shift**, **alt**. Разделителем выступает **+**
Вместо кода клавиши можно использовать ключевые слова: **enter**, **escape**, **space**, **ins**, **del**. Другие клавиши надо обозначать их числовым кодом (из события **onKeyDown** JavaScript в браузере).
Можно ограничить область действия горячих клавиш, задав запросу атрибут **rowset**. Тогда сочетание клавиш будет вызывать запрос только в том случае, когда текущая (имеющая фокус ввода) экранная панель относится к этому [[rowset-definition|набору строк]].
Пример:
В данном случае [[request|запрос]] **do-anything** представляет собой цепочку запросов. Она может быть вызвана нажатием комбинации горячих клавиш **Ctrl+Alt+Enter**, если имеющая фокус ввода экранная панель относится к [[rowset-definition|набору строк]] table1.
===== Сохранение накопившихся изменений, перед выполнением запроса =====
Пример:
Параметр save="1" вызывает, перед выполнением [[request|запроса]], сохранение на сервер всех не отписанных изменений, если они есть.
===== Передаваемые запросу параметры =====
В [[request|запросе]] можно описать передаваемые серверу значения параметров. Основные описатели параметра, это имя **name** и значение **value**. Значение может быть константой - тогда используется атрибут **value**, или выражением JavaScript - тогда используется атрибут **js_value**. Для построения выражений можно использовать [[lssfunctions|функции доступа к данным LSS]].
Атрибут **skipempty="1"** указывает, что не следует передавать на сервер параметр, если его значение пусто. По умолчанию skipempty="0" и параметры с пустым значением на сервер передаются.
Атрибут **js_enabled** позволяет задать выражение JavaScript, указывающее следует ли передавать параметр на сервер.
Атрибут **type** позволяет задать тип передаваемого в параметре значения, в соответствии с [[lssformat|форматом данных LSS]].
Пример:
===== Выполнение цепочки запросов =====
Цепочка [[request|запросов]] объявляется в секции requests.
При ее вызове, включенные внутрь цепочки [[request|запросы]] выполняются последовательно, один за другим.
Пришедшая в [[response|ответе]] ошибка прерывает выполнение цепочки запросов.
Параметр [[request|запроса]] sync="0" изменяет это поведение - такой [[request|запрос]] выполняется асинхронно, последующие [[request|запросы]] не ожидают результатов его выполнения. Этот параметр удобно использовать в конце цепочки, для перечитки нескольких [[rowset-definition|rowset]], затронутых [[request|запросом]].
Рассмотрим пример:
===== Запросы на событие onshow и onclose =====
Объявленные в секции **requests** [[request|запросы]] с именем **onshow** и **onclose** вызываются автоматически при открытии и закрытии [[form-definition|экранной формы]].
Пример:
Обратите внимание на значение **get('#data.first')**. Оно 1 при первом вызове [[form-definition|формы]] и 0 при повторном получении [[form-definition|формой]] фокуса ввода.
Часто бывает необходимым организовать перечитку данных [[form-definition|экранной формы]], когда из этой формы переключились в другую, там исправили важные данные, а потом вернулись обратно. Не модальные [[form-definition|экранные формы]] в LSS между собой не взаимодействуют, работают изолированно. Соответственно, для согласования данных приходится организовывать перечитку при возврате [[form-definition|форме]] фокуса ввода.