2.2.7.5. Скрипт

В режимі конструктора «Скрипт» можливо створити розширення поведінки форми за допомогою налаштованої логіки. Скрипти використовують мову програмування JavaScript та виконуються браузером, як основний код додатку.

Рис. 2.2.7.5.1. Конструктор – Скрипт

Для створення скриптів необхідні деякі знання основ JavaScript:

  • Основи мови (вирази, інструкції, функції, змінні, змінні та інше)
  • Модулі JavaScript
  • Асинхронні функції

Окрім того, щоб робити запит до сервера, ознайомтеся з документацією UnityBase, особливо з модулем @ unitybase / ub-pub, об’єктом connection та класом ClientRepository.

        В системі доступні шаблони для певних дій за атрибутами. Для їх використання (копіювання до буферу обміну) необхідно в дизайнері (типу документів, форми задач та інших елементах системи) обрати атрибут та натиснути «Згенерувати скрипт», після чого обрати дію.

Рис. 2.2.7.5.2. Шаблони скриптів

Модуль

Кожен скрипт форми повинен бути модулем CommonJS, тобто він повинен  містити такий рядок, як:

module.exports = {
// …
}

Примітка: Будь-який скрипт записується всередині конструкції:

module.exports = {
}

        Взаємодія з формою подійно-орієнтована, та об’єкт, що експортується модулем, повинен містити обробники подій як властивості. Наприклад:

module.exports = {
loaded() {
console.log(‘Inside “loaded” event handler for the form!’)
}
}

В скрипті може бути лише один module.exports. У випадку, якщо в одному скрипті необхідно задати дві чи більше подій, вони перераховуються в одному module.exports, через кому. Не визначайте декілька module.exports – це не працюватиме.

Events (Події)

Назва ключа в об’єкті, що експортується (не плутати з назвою функції, це різні речі), визначає на яку подію функція буде реагувати. Прив’язка події до функції основана на конвенції про іменування.

Кожен обробник подій може бути асинхронним чи повертати promise (не обов’язково, але може якщо потрібно, в такому випадку код буде очікувати завершення обробки події).

Іноді одна й те сама подія оброблюється декількома обробниками. Наприклад, може бути конкретний обробник подій дій action_beforeExecute_action1 та загальний обробник подій action_beforeExecute. Це не звичайна ситуація, але якщо це відбудеться, загальний обробник подій буде виконаний перед конкретним обробником події.

   

Аргумент події

Кожен обробник подій приймає рівно один аргумент, за узгодженням, якщо обробник не використовує параметр, не вказуйте його, але якщо обробник використовує аргумент події, назвіть його event.

module.exports = {
loaded(event) {
console.log(
‘Inside “loaded” event handler for the form for document: %s’,
event.document.getNativeAttribute(
‘docNumber’)
)
}
}

Ви можете «вимагати» службові сценарії, як і в будь-якому клієнтському модулі UB.

const UB = require(‘@unitybase/ub-pub’)

module.exports = {
// …
}

Примітка: якщо ви використовуєте зовнішні сценарії, ви несете відповідальність за підтримку сценарію форми при зміні зовнішнього модуля (та іноді вони можуть мати критичні зміни), використовуйте його відповідно.

 Можливості аргументу події залежать від форми об’єкту. Наприклад, для форми задач BPM подія міститиме властивість task, а для документу Scriptum міститиме властивість document. Завдання, пов’язані зі Scriptum Document матимуть властивості task та document. 

Це також точка налаштування, для великої інтеграції можна розробити додатковий інструмент доступу до об’єктів у вашій користувацькій моделі та зробити його видимим всередині скриптів форми.

Кожна така властивість називається засобом доступу до об’єкту даних оскільки надає засоби для отримання чи встановлення значень для атрибутів відповідного об’єкту.

API об’єктів доступу до об’єктів:

  • getAttribute – значення, що повертає, користувацький атрибуту, (з бібліотеки атрибутів, а не атрибут об’єкту). 

event.document.getAttribute(‘color’)

  • getNativeAttribute – значення, що повертається, атрибуту, що налаштовується. «Native» позначає атрибут сутності, а не атрибут з бібліотеки атрибутів.

event.document.getNativeAttribute(‘docNumber’)

  • setAttribute – змінити значення користувацького атрибуту. Щоб очистити значення, встановіть null

event.document.setAttribute(
‘fullName’,
event.document.getAttribute(
‘firstName’) + ‘ ‘ + event.document.getAttribute(‘lastName’)
)

  • setNativeAttribute – змінити значення власного атрибуту. Щоб очистити значення, встановіть null«Native» позначає атрибут сутності.

 Деякі атрибути відносяться до словників. Їх значення – числа – ID записів, на які вони вказують. Якщо вам потрібно в скрипті значення зі словника, необхідно написати додатковий код, наприклад:

module.exports = {
async document_attributeChanged_organization(event) {

if (event.value) {

const orgCode = await UB.Repository(‘org_organization’)
.attrs(
‘code’)
.where(
‘ID’‘=’, event.value)
.selectScalar()

console.log(‘Selected organization with ID=%d, code=%s’, event.value, orgCode)

else {
console.log(‘Cleaned up “organization” attribute!’)
}
}
}

Примітки до прикладу:

  • Зверніть увагу, що використовується UB.Repository – це частина UnityBase API, зверніться до документації UnityBase для отримання детальної інформації про це.
  • Всі UB.Repository методи вибору являються асинхронними, тому обробник подій також повинен бути асинхронним, і ми «чекатимемо» виклику «selectScalar».
  • В цьому прикладі показано, як робити запит словника, такий синтаксис event.document.getAttribute(‘organization.code’)неправильний та не повертає бажане значення.    

   

Деякі засоби доступу до об’єкту можуть надавати додаткові методи. Наприклад, засіб доступу до об’єкту Scriptum Document надає такі методи:

  • Властивість state повертає код поточного стану документу

if (event.document.state === ‘draft’) {
// It’s a draft!
}

  • userHasRole – функція, що перевіряє чи є у користувача документа роль (не UB), його код.

if (event.document.userHasRole(‘author’)) {
// It’s the document author!
}

  • getParticipants – функція, що повертає інформацію про ролі учасників документу. Значення функції, що повертається – масив об’єктів наступної структури:

{
ID: 3000012,
unitType: 
‘ORG’,
code: 
‘0123123’,
name: 
‘organization1’,
isFixed: 
true
}

Застосування:

const participantsOfResponsibleRole = event.document.getParticipants(‘responsible’)

  • removeParticipant – функція, видаляє будь-якого учасника з ролі документа. Першим аргументом функції являється код ролі, а другим повинен бути orgUnitID, наприклад, staffUnitID.

event.document.removeParticipant(‘responsible’, participantID)

  • addParticipant – функція, додає учасника до ролі документа. Першим аргументом функції являється код ролі, а другим повинен бути orgUnitID, наприклад, staffUnitID.

event.document.addParticipant(‘responsible’, participantID)

  • getCurrentUserRoles – функція, повертає ролі поточного користувача документа у вигляді масиву рядків. Повертає масив рядків, наприклад:[‘author’, ‘manager’]

const userRoles = event.document.getCurrentUserRoles()

Події глобальної форми

Події ініціалізації форми:

  • inited
  • loaded

Це дві схожі події, єдина різниця між ними в тому, що initied викликаються лише при першому завантаженні даних форми, а loaded викликаються кожен раз при завантаженні форми (користувач може використовувати кнопку панелі інструментів «Оновити» для перезавантаження форми).

Події збереження форми:

  • beforeSave
  • saved

Всередині beforeSave можна відмінити збереження: 

module.exports = {
beforeSave(event) {
if (!!event.document.getAttribute(‘hasCategory’) && !event.document.getAttribute(‘categoryID’)) {
// “categoryID” must be specified, if “hasCategory” toggle is toggled
event.cancelSave()
}
}
}

Події дії

Якщо подія «before» та «after»:

  • action_beforeExecute
  • action_beforeExecute_<actionCode>
  • action_executed
  • action_executed_<actionCode>

Подія без суфіксу коду дії буде викликатися для будь-якої події, а події зі суфіксом коду дії будуть викликатися лише для визначених дій.

Всі події мають додаткову властивість – actionCode. Що використовується для універсальних обробників подій дій (без коду дії в назві події).

У обробників «before» також є наступні додаткові методи:

  • cancelAction – дозволяє не викликати дію. Використовується для перевірок.
  • skipStandardConfirmDialog – виклик цього методу означає «Не викликати жодного підтвердження перед дією». Використовується у випадках, коли всередині обробника викликається інтерфейс користувача та необхідно перекрити стандартний. Скоріше за все необхідно буде використовувати обробник асинхронних подій, що повертає повідомлення підтвердження після того як користувач підтвердить дію в інтерфейсі користувача. Додайте ключове слово async :

const customUI = require(‘path_to_my_custom_ui_module’)

module.exports = {
async action_beforeExecute_approve(event) {
const confirmResult = await customUI.approveActionDialog()
if (!confirmResult) {
event.cancelAction()
}
}
}

Події атрибутів

Події атрибутів являються варіаціями самої загальної attributeChanged події:

  • <dataObject>_attributeChanged
  • <dataObject>_nativeAttributeChanged
  • <dataObject>_attributeChanged_<attributeCode>
  • <dataObject>_nativeAttributeChanged_<attributeCode>

Як видно з шаблону назви події, кожен варіант подій фільтрує події по об’єкту даних (наприклад завдання чи документ), типу атрибуту (налаштовуваний – з бібліотеки атрибутів чи власний – атрибут сутності) та код атрибуту.

Сам об’єкт події містить такі властивості, що стосуються лише до подій attributeChange:

  • dataObject
  • attributeCode
  • attributeKind
  • value
  • oldValue – попереднє значення

module.exports = {
document_attributeChanged(event) {
if (event.attributeCode === ‘firstName’ || event.attributeCode === ‘lastName’) {
event.document.setAttribute(
‘fullName’,
event.document.getAttribute(
‘firstName’) + ‘ ‘ + event.document.getAttribute(‘lastName’)
)
}
}
}

Даний результат можна досягти за допомогою іншого підходу – замість одного обробника подій для всіх змін атрибутів документа з логікою всередині, що аналізує, який атрибут змінився, тієї ж цілі можна досягти маючи два окремих обробника подій – по одному на атрибут:

module.exports = {
document_attributeChanged_firstName(event) {
event.document.setAttribute(
‘fullName’,
event.value + 
‘ ‘ + event.document.getAttribute(‘lastName’)
)
},

document_attributeChanged_lastName(event) {
event.document.setAttribute(
‘fullName’,
event.document.getAttribute(
‘firstName’) + ‘ ‘ + event.value
)
}
}

В останньому варіанті код чистіше. Рекомендовано використовувати саме такий підхід.

Зміна властивостей елементу форми

        Скрипти форм дозволяють змінювати макет форми під час виконання:

  • змінити властивість елементу (вузлів) форми
  • змінити елемент форми (вузли), необхідні правила, що його підтримують (форми виконання документів та задач)
  • змінити елементи форми (вузли) accessRules для форм, що підтримують його (наприклад форми документів)

Об’єкт події має спеціальну властивість form, що містить спеціальний об’єкт з такими методами:

  • setNodeProperty
  • setNodeRequiredRule
  • setNodeAccessRule 

Всі вищезгадані методи приймають числовий nodeId в якості першого аргументу, key в якості другого та value – третього.

module.exports = {
document_attributeChanged_country(event) {
// Do not allow changing ‘city’ (nodeId = 10), unless country value is set
event.form.setNodeProperty(
10,
‘disabled’,
!event.value
)
}
}

Налагоджувальні скрипти

Виведення інформації в Console.log – це виведення інформації в консоль браузера: F12, закладка Console

Є декілька способів налагодження скриптів форм. Всі вони вимагають створення документу та його випробування:

  • помістіть debugger оператор в скрипти, вони відкриють DevTools в браузері (клавіша F12) та спробуйте:

module.exports = {
document_attributeChanged_firstName(event) {

debugger

event.document.setAttribute(
‘fullName’,
event.value + 
‘ ‘ + event.document.getAttribute(‘lastName’)
)
}
}

  • використайте console.debug

module.exports = {
document_attributeChanged_firstName(event) {

console.debug(‘document_attributeChanged_firstName event: %j’, event)

event.document.setAttribute(
‘fullName’,
event.value + 
‘ ‘ + event.document.getAttribute(‘lastName’)
)
}
}

  • використайте контрольні точки: відкрийте DevTools в браузері, знайдіть сценарій, підказку – подивіться під clientRequire/models/cust/public/designedFormsзалежно від середовища назви моделі може бути не «cust»

При роботі з довідниками передаються та повертаються id значень довідника. Для переліку значень довідника з множинним вибором – використовуйте квадратні дужки (наприклад [3000000001781, 3000000001748])

        Приклади скриптів наведені у додатку 1 до інструкції.

Отримайте персональну пропозицію

    Цей сайт захищено reCAPTCHA, а також застосовуються Політика конфіденційності та Умови надання послуг Google.
    +38 (044) 323 00 86