Скриптинг в формах
------------------

Основные требования и некоторые детали задачи описаны в
соответствующей постановке: `«Скриптинг в формах» <http://tdd.lan.arta.kz/docs/additional/statements/3/html/forms63.html>`_

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

Примеры использования скриптинга см. `здесь <http://tdd.lan.arta.kz/docs/synergy/tags/wilkes/sdk-doc/html/extfp-usecases/extfp-usecases.html>`_

**Используемые технологии и библиотеки:**

*   `jQuery`
*   `Underscore` - утилиты
*   `Backbone` - UI компоненты
*   `Marionette` - UI компоненты
*   `jQuery ui` - UI компоненты
*   `math.js` - поддержка математики больших чисел
*   `base64.js` - добавляет методы btoa, atob для браузеров,
    в которых их нет (в частности IE 9, 10)
*   `XregExp.js` - поддержка более сложных регулярных
    выражений

Схемы работы проигрывателя
~~~~~~~~~~~~~~~~~~~~~~~~~~

.. figure:: _static/img/schema_1.png

    Общая схема работы проигрывателя

.. figure:: _static/img/schema_2.png

    Процесс изменения модели

.. figure:: _static/img/schema_3.png

    Процесс изменения значения компонента

.. figure:: _static/img/schema_4.png

    Взаимодействие со средой

Общедоступные объекты
~~~~~~~~~~~~~~~~~~~~~

*   ``AS`` - общее пространство имен
*   ``AS.FORMS`` - формы
*   ``AS.COMPONENTS`` - компоненты, которые могут быть использованы отдельно от проигрывателя форм
*   ``AS.SERVICES`` - сервисы
*   ``AS.LOGGER`` - логгер
*   ``AS.OPTIONS`` - настройки
*   ``AS.DICTIONARIES`` - кэш справочников

Типы событий
~~~~~~~~~~~~

*   ``formShow : 'formShow'`` - отображение формы
    (построение новой формы)

*   ``formDestroy : 'formDestroy'`` - метод `destroy`_ модели проигрывателя

*   ``dataLoad: 'dataLoad'`` - подгрузка данных

*   ``valueChange: 'valueChange'`` - изменение значения
    модели

*   ``markInvalid : 'markInvalid'`` - необходимость отображению подсветить невалидное значение

*   ``tableRowAdd: 'tableRowAdd'`` - добавление ряда в таблице

*   ``tableRowDelete: 'tableRowDelete'`` - удаление ряда в таблице

*   ``dictionaryLoad : 'dictionaryLoad'`` - подгрузка справочника

*   ``tagEdit : 'tagEdit'`` - редактирование тега

*   ``tagDelete : 'tagDelete'`` - удаление тега

*   ``loadComponentAdditionalInfo : 'loadComponentAdditionalInfo'`` -
    подгрузка дополнительной информации компонента (сейчас
    используется для пользовательского компонента)

Особенности реализации
~~~~~~~~~~~~~~~~~~~~~~

В области видимости скрипта (добавленный как к компоненту,
так и пользовательскому компоненту) имеются следующие
переменные:

*   ``model`` - модель текущего компонента;
*   ``view`` - отображение текущего компонента;
*   ``editable`` - режим (просмотр / редактирование);
*   ``model.playerModel`` - модель проигрывателя;
*   ``view.playerView`` - отображение проигрывателя.

Скрипт (добавленный как к компоненту, так и пользовательскому
компоненту) выполняется каждый раз при смене режима
проигрывателя (просмотр - редактирование). При этом *модель*
компонента остается та же, а *отображение* компонента каждый
раз пересоздается. Поэтому при написании скриптов следует
учесть следующее: если добавляются или переписываются методы
модели, либо происходит подписывание на события другой модели,
то рекомендуется использовать следующее:

.. code-block:: js
  :linenos:

  if (!model.inited) {
      //манипулирование моделями
      model.inited = true;
  }

**"Строгий режим" JavaScript:**

Начиная с версии Synergy 3.14, все пользовательские скрипты
выполняются с добавлением директивы `use strict`. Эта директива
означает, что соответствующий ей код будет выполнятся в так
называемом **"строгом режиме"**, поддерживающем стандарт `JavaScript`
`ECMAScript5 <http://www.ecma-international.org/publications/standards/Ecma-262.htm>`_

.. warning:: Если код скрипта содержит конструкции, не соответствующие стандарту ES5, то они не будут выполняться. Это не является ошибкой Synergy.

Проигрыватель
~~~~~~~~~~~~~

Для того, чтобы создать экземпляр проигрывателя, необходимо вызвать
метод ``AS.FORMS.createPlayer()``.

.. code-block:: js

    var player = AS.FORMS.createPlayer();

Методы проигрывателя
""""""""""""""""""""

.. js:function:: showFormByCode(formCode[,version])

    Отображает форму по ее коду, без создания соответствующего экземпляра asfData

    :param string formCode: Код формы.
    :param number version: Версия формы.

.. js:function:: showFormData(formUUID[, version[, dataUUID[, dataVersion]]])

    Отображает форму

    :param string formUUID: Идентификатор формы.
    :param number version: Номер версии формы.
    :param string dataUUID: Идентификатор данных формы.
    :param number dataVersion: Номер версии данных формы.

.. js:function:: saveFormData(callback)

    Сохраняет данные формы

    :param callback: Функция, которая будет вызвана после сохранения данных с параметром asfDataUUID.

.. js:function:: dataLoaded(definition[,data])

    Построение формы согласно definition и заполнение asfData значением параметра data.
    Вспомогательный метод, вызывающийся при выполнении методов ``showFormData`` и ``showFormByCode``.

    :param string definition: Описание формы в формате JSON.
    :param string data: Данные формы в форме JSON.

.. js:function:: destroy()

    Удаляет экземпляр проигрывателя

Базовые модели и отображения
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Базовая модель
"""""""""""""""

**Поля базовой модели**

.. js:data:: asfProperty

    Определение компонента из описания формы

.. js:data:: playerModel

    Модель проигрывателя

**Методы базовой модели**

.. js:function:: fireChangeEvents()

    Вызов событий изменения значения формы

.. js:function:: isEmpty()

    Пустое ли значение

.. js:function:: doSetValue(newValue)

    Вставить новое значение и отправить уведомление всем подписанным объектам, в т.ч. отображению

    :param string newValue: Значение компонента

.. js:function:: getErrors()

    Получение ошибок заполнения поля согласно настройкам ``asfProperty``

    :returns: возвращает массив ошибок. Если массив пустой, значит ошибки отсутствуют,
              иначе - его элементы имеют поля:

              * ``errorCode`` - код ошибки;
              * ``id`` - идентификатор компонента.

              Возможные коды ошибок:

              * ``emptyValue``
              * ``wrongValue``
              * ``deletedValue``
              * ``valueTooHigh``
              * ``valueTooSmall``

              Для одного и того же компонента может быть как несколько ошибок, так может и не быть ни одной.

.. js:function:: getLocale()

    Получение локали, настроенной в компоненте

    :returns: *(string)* Локаль пользователя

.. js:function:: getHTMLValue()

    :returns: *(string)* HTML-представлениe текстового значения поля со стилями

.. js:function:: getValue()

    :returns: *(string)* значение компонента

.. js:function:: getTextValue()

    :returns: *(string)* текстовое значение компонента

.. js:function:: getAsfData([blockNumber])

    :param number blockNumber: Номер строки динамической таблицы (если это компонент статической таблицы, то передавать эту переменную не нужно)
    :returns: *(asfData)* Данные компонента

.. js:function:: setAsfData(asfData)

    Вставить значение `asfData`

    :param asfData asfData: Данные компонента в формате JSON.

Базовое отображение
"""""""""""""""""""

    +-----------------------+----------------------+------------------------------+
    | Наименование          | Тип                  | Описание                     |
    +=======================+======================+==============================+
    | model                 | Наследует            | Модель                       |
    |                       | AS.FORMS.Model       |                              |
    +-----------------------+----------------------+------------------------------+
    | container             | div                  | Контейнер, в котором будет   |
    |                       |                      | отрисовываться отображение   |
    +-----------------------+----------------------+------------------------------+
    | input                 | input                | Поле ввода для некоторых     |
    |                       |                      | компонентов:                 |
    |                       |                      |                              |
    |                       |                      | *  текстовое поле            |
    |                       |                      | *  числовое поле             |
    |                       |                      | *  многострочный текст       |
    +-----------------------+----------------------+------------------------------+
    | playerView            |                      | Отображение проигрывателя    |
    +-----------------------+----------------------+------------------------------+

**Базовые методы отображения**

.. js:function:: unmarkInvalid()
.. js:function:: markInvalid()
.. js:function:: checkValid()
.. js:function:: setEnabled(enabled)
.. js:function:: setVisible(visible)
.. js:function:: updateValueFromModel()

    +-----------------------+----------------------+------------------------------+
    | Наименование          | Аргумент             | Описание                     |
    +=======================+======================+==============================+
    | unmarkInvalid         |                      | Убрать пометку неправильно   |
    |                       |                      | заполненного поля            |
    +-----------------------+----------------------+------------------------------+
    | markInvalid           |                      | Пометить поле как            |
    |                       |                      | неправильно заполненное      |
    +-----------------------+----------------------+------------------------------+
    | checkValid            |                      | Проверить корректность       |
    |                       |                      | текущего значения (если      |
    |                       |                      | поле заполнено неверно, то   |
    |                       |                      | вызовется метод              |
    |                       |                      | `markInvalid`)               |
    +-----------------------+----------------------+------------------------------+
    | setEnabled            | boolean enabled      | Сделать доступным или        |
    |                       |                      | недоступным для              |
    |                       |                      | редактирования               |
    +-----------------------+----------------------+------------------------------+
    | setVisible            | boolean visible      | Сделать видимым или          |
    |                       |                      | невидимым                    |
    +-----------------------+----------------------+------------------------------+
    | updateValueFromModel  |                      | Обновить отображение         |
    |                       |                      | согласно значению модели     |
    +-----------------------+----------------------+------------------------------+
