Часто возникает задача: при обращении к обработке или документу проверить права пользователя (или другие условия) и, в зависимости от результата, открыть одну из нескольких разных форм. Проанализируем типичную ситуацию: разработчик в основной форме пишет код в обработчике ПриОткрытии, устанавливает параметр Отказ = Истина и тут же вызывает ОткрытьФорму для нужной формы.
В тонком или толстом клиенте такой подход иногда работает, но в веб-клиенте неизбежно возникает ошибка: "Использование модальных окон в данном режиме запрещено". Включение режима использования модальности в конфигурации не решает проблему. Разберем по шагам, почему это происходит, и рассмотрим правильные способы реализации такого механизма.
Выясним причину такого поведения системы. Согласно стандартам разработки 1С, в управляемом приложении категорически не рекомендуется выполнять программное открытие и закрытие (отмену открытия) формы в одном вызове встроенного языка. Это нарушает порядок инициализации окон.
В веб-клиенте архитектура браузеров накладывает дополнительные ограничения. Когда мы пытаемся отменить стандартное открытие формы и тут же вызываем открытие новой, браузер воспринимает это как синхронный вызов всплывающего (блокирующего) окна. Платформа 1С перехватывает этот конфликт отрисовки и прерывает выполнение, выдавая ошибку о модальности.
Кроме того, если переход к обработке осуществляется через внешнюю HTTP-ссылку (навигационную ссылку), которая явно указывает на конкретную форму, стандартные механизмы перехвата форм не срабатывают, так как платформа пытается открыть указанный путь напрямую.
Если пользователи открывают обработку стандартным способом (через меню раздела), рассмотрим правильный платформенный механизм переопределения форм. В модуле менеджера обработки существует специальное событие ОбработкаПолученияФормы. Оно отрабатывает на сервере до начала отрисовки интерфейса на клиенте, что экономит серверные вызовы.
Посмотрим на пример реализации в модуле менеджера:
Процедура ОбработкаПолученияФормы(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ДоступПользователя = ПроверитьПользователяНаДоступ();
Если ДоступПользователя = "Количество" Тогда
ВыбраннаяФорма = "УправляемаяФормаКоличество";
Иначе
ВыбраннаяФорма = "ОсновнаяФорма";
КонецЕсли;
КонецПроцедуры
Мы устанавливаем СтандартнаяОбработка = Ложь и передаем в параметр ВыбраннаяФорма имя нужной нам формы. Важное примечание: этот метод не отработает в веб-клиенте, если переход происходит по внешней навигационной ссылке, жестко привязанной к конкретной форме.
Самый надежный подход для веб-клиента и переходов по ссылкам — отказаться от использования нескольких разных форм. Создадим одну универсальную (динамическую) управляемую форму. В обработчике ПриСозданииНаСервере выполним проверку доступа пользователя и программно настроим интерфейс.
Рассмотрим, как это работает:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ДоступПользователя = ПроверитьПользователяНаДоступ();
Если ДоступПользователя = "Количество" Тогда
// Скрываем ненужные группы или страницы
Элементы.ГруппаПолныеДанные.Видимость = Ложь;
Элементы.ГруппаКоличество.Видимость = Истина;
Иначе
Элементы.ГруппаПолныеДанные.Видимость = Истина;
Элементы.ГруппаКоличество.Видимость = Ложь;
КонецЕсли;
КонецПроцедуры
Управляя свойством Видимость у элементов формы, мы полностью исключаем необходимость вызывать ОткрытьФорму, тем самым избегая любых конфликтов отрисовки в браузере.
Если переделывать логику на одну форму нецелесообразно, а пользователи заходят в веб-клиент по внешним ссылкам, изменим точку входа. Вместо выдачи ссылки на форму обработки, создадим Общую команду.
В модуле общей команды выполняем клиентский код:
&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
Доступ = ВызватьСервернуюФункциюПроверкиДоступа();
Если Доступ = "Количество" Тогда
ОткрытьФорму("Обработка.ОценкаКачества.Форма.УправляемаяФормаКоличество", , ПараметрыВыполненияКоманды.Источник, ПараметрыВыполненияКоманды.Уникальность, ПараметрыВыполненияКоманды.Окно);
Иначе
ОткрытьФорму("Обработка.ОценкаКачества.Форма.ОсновнаяФорма", , ПараметрыВыполненияКоманды.Источник, ПараметрыВыполненияКоманды.Уникальность, ПараметрыВыполненияКоманды.Окно);
КонецЕсли;
КонецПроцедуры
В данном случае открытие происходит корректно, так как форма определяется до начала какого-либо процесса отрисовки окон в браузере. Мы не пытаемся отменить уже начавшееся открытие, поэтому ошибки модальности не возникает.
Начиная с версии платформы 8.3.19, механизм навигационных ссылок поддерживает передачу дополнительных параметров непосредственно в URL (аналогично GET-запросам в веб-разработке). Если внешняя система или сайт формирует ссылку для перехода в веб-клиент, в эту ссылку можно заложить параметры запуска.
Проанализируем этот вариант: при старте в процедуре ПриСозданииНаСервере основной формы мы можем прочитать параметры, переданные в свойстве Параметры формы, и сразу же перестроить интерфейс или программно инициировать нужные действия без переоткрытия окон. Это отличная альтернатива, позволяющая сделать точку входа гибкой и не зависящей от сложной маршрутизации на клиенте.