Модальная форма - форма, которая приостанавливает выполнение кода вызвавшей её процедуры и блокирует переключение фокуса на другие формы до своего закрытия. Она является незаменимой частью пользовательского интерфейса и порой единственным способом взаимодействия с пользователем.
В Aveva все возможности работы с модальными формами представлены объектом alert, который позволяет вызывать несколько видов форм:
!!alert.confirm('текст') |
![]() |
!!alert.error('текст') |
![]() |
!!alert.input('текст', 'значение_по_умолчанию') |
![]() |
!!alert.message('текст') |
![]() |
!!alert.question('текст') |
![]() |
!!alert.warning('текст') |
![]() |
Зачастую этих возможностей недостаточно.
Давайте посмотрим как можно решить эту проблему:
В макросах есть возможность использовать функцию waiton
waiton название_формы
Сделаем небольшой пример:
waitonTestForm.pmlfrm
setup form !!waitonTestForm BLOCKINGDIALOG !this.formTitle = 'Выберите значение' paragraph .paraQuestion AT X 0 YMIN ANCHOR LEFT+TOP TEXT '' WIDTH 50 LINE 5 button .btnFirst AT X 0 YMAX 'Первый' ANCHOR BOTTOM+RIGHT CALLBACK '!!waitonTestForm.setAnswer(!this.first)' WIDTH 7 button .btnSecond AT XMAX+1 YMIN 'Второй' ANCHOR BOTTOM+RIGHT CALLBACK '!!waitonTestForm.setAnswer(!this.second)' WIDTH 7 button .btnCancel AT XMAX FORM-SIZE YMIN 'Отмена' ANCHOR BOTTOM+RIGHT CALLBACK '!!waitonTestForm.setAnswer(||)' WIDTH 7 member .first is STRING member .second is STRING member .answer is STRING exit define method .setForm(!title is STRING, !question is STRING, !first is STRING, !second is STRING) !this.formTitle = !title !this.paraQuestion.val = !question !this.first = !first !this.btnFirst.tag = !first !this.second = !second !this.btnSecond.tag = !second endmethod define method .setAnswer(!text is STRING) !this.answer = !text !this.hide() endmethod
waitonTestFnc.pmlfnc
define function !!waitonTestFnc(!title is STRING, !question is STRING, !first is STRING, !second is STRING) is STRING kill !!waitonTestForm loadForm !!waitonTestForm !!waitonTestForm.setForm(!title, !question, !first, !second) waiton !!waitonTestForm return !!waitonTestForm.answer endfunction
Тестовый макрос:
!result = !!waitonTestFnc('Проверяем как работает ф-ция waiton в макросе', 'Количество каких элементов вывести на экран?', 'SITE', 'ZONE') if(undefined(!result) OR !result.empty()) then write 'Была выбрана отмена :(' else !items = !!collectallfor( !result, '', /* ) !!alert.message('В текущей MDB ' & !items.size() & ' элементов типа $!result') endif
При запуске макроса и выборе значения получим следующий результат:
В функциях и формах такой способ создания модального окна не работает. Если мы создадим форму
waitonTestStartForm.pmlfrm
setup form !!waitonTestStartForm !this.formTitle = 'Форма' button .btnStart AT X 0 Y 0 'Поехали!' ANCHOR BOTTOM+RIGHT CALLBACK '!this.start()' WIDTH 15 exit define method .start() !result = !!waitonTestFnc('Проверяем как работает ф-ция waiton в макросе', 'Количество каких элементов вывести на экран?', 'SITE', 'ZONE') if(undefined(!result) OR !result.empty()) then write 'Была выбрана отмена :(' else !items = !!collectallfor( !result, '', /* ) !!alert.message('В текущей MDB ' & !items.size() & ' элементов типа $!result') endif endmethod
и запустим её, то получим такой результат:
То есть на запуске функции waitonTestFnc выполнение программы не прерывается, переменной result значение не присваивается и возникает ошибка.
Как добиться нужного результата? Можно использовать callback, который бы вызывался после выбора значения. Рассмотрим пример:
modalForm.pmlfrm
setup form !!modalForm BLOCKINGDIALOG !this.formTitle = 'Выберите значение' paragraph .paraQuestion AT X 0 YMIN ANCHOR LEFT+TOP TEXT '' WIDTH 50 LINE 5 button .btnFirst AT X 0 YMAX 'Первый' ANCHOR BOTTOM+RIGHT CALLBACK '!this.answer(!this.first)' WIDTH 7 button .btnSecond AT XMAX+1 YMIN 'Второй' ANCHOR BOTTOM+RIGHT CALLBACK '!this.answer(!this.second)' WIDTH 7 button .btnCancel AT XMAX FORM-SIZE YMIN 'Отмена' ANCHOR BOTTOM+RIGHT CALLBACK '!this.answer(||)' WIDTH 7 member .first is STRING member .second is STRING member .answer is STRING member .callbackMethod is STRING exit define method .setForm(!title is STRING, !question is STRING, !first is STRING, !second is STRING, !callbackMethod is STRING) !this.formTitle = !title !this.paraQuestion.val = !question !this.first = !first !this.btnFirst.tag = !first !this.second = !second !this.btnSecond.tag = !second !this.callbackMethod = !callbackMethod endmethod define method .answer(!text is STRING) !this.answer = !text !this.hide() !callback = '$!this.callbackMethod' & '(|' & '$!this.answer' & '|)' $!callback endmethod
showModalTestForm.pmlfnc
define function !!showModalTestForm(!title is STRING, !question is STRING, !first is STRING, !second is STRING, !callbackMethod is STRING) kill !!modalForm pml load form !!modalForm !!modalForm.setForm(!title, !question, !first, !second, !callbackMethod) show !!modalForm endfunction
modalStartForm.pmlfrm
setup form !!modalStartForm !this.formTitle = 'Форма' button .btnStart AT X 0 Y 0 'Поехали!' ANCHOR BOTTOM+RIGHT CALLBACK '!this.start()' WIDTH 15 exit define method .start() !!showModalTestForm('Проверяем как работает ф-ция waiton в макросе', 'Количество каких элементов вывести на экран?', 'SITE', 'ZONE', '!!modalStartForm.valueSelected') endmethod define method .valueSelected(!result is STRING) if(undefined(!result) OR !result.empty()) then write 'Была выбрана отмена :(' else !items = !!collectallfor( !result, '', /* ) !!alert.message('В текущей MDB ' & !items.size() & ' элементов типа $!result') endif endmethod
Если запустим modalStartForm то получим ожидаемый результат
То есть наша форма после выбора значения запускает переданный ей метод.