Как исправить ошибку модальности при переопределении открываемой формы в веб-клиенте 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Часто возникает задача: при обращении к обработке или документу проверить права пользователя (или другие условия) и, в зависимости от результата, открыть одну из нескольких разных форм. Проанализируем типичную ситуацию: разработчик в основной форме пишет код в обработчике ПриОткрытии, устанавливает параметр Отказ = Истина и тут же вызывает ОткрытьФорму для нужной формы.

В тонком или толстом клиенте такой подход иногда работает, но в веб-клиенте неизбежно возникает ошибка: "Использование модальных окон в данном режиме запрещено". Включение режима использования модальности в конфигурации не решает проблему. Разберем по шагам, почему это происходит, и рассмотрим правильные способы реализации такого механизма.

Почему возникает ошибка модального окна?

Выясним причину такого поведения системы. Согласно стандартам разработки 1С, в управляемом приложении категорически не рекомендуется выполнять программное открытие и закрытие (отмену открытия) формы в одном вызове встроенного языка. Это нарушает порядок инициализации окон.

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

Кроме того, если переход к обработке осуществляется через внешнюю HTTP-ссылку (навигационную ссылку), которая явно указывает на конкретную форму, стандартные механизмы перехвата форм не срабатывают, так как платформа пытается открыть указанный путь напрямую.

Решение 1: Использование события ОбработкаПолученияФормы

Если пользователи открывают обработку стандартным способом (через меню раздела), рассмотрим правильный платформенный механизм переопределения форм. В модуле менеджера обработки существует специальное событие ОбработкаПолученияФормы. Оно отрабатывает на сервере до начала отрисовки интерфейса на клиенте, что экономит серверные вызовы.

Посмотрим на пример реализации в модуле менеджера:


Процедура ОбработкаПолученияФормы(ВидФормы, Параметры, ВыбраннаяФорма, ДополнительнаяИнформация, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь;
    
    ДоступПользователя = ПроверитьПользователяНаДоступ();
    Если ДоступПользователя = "Количество" Тогда
        ВыбраннаяФорма = "УправляемаяФормаКоличество";
    Иначе
        ВыбраннаяФорма = "ОсновнаяФорма";
    КонецЕсли;

КонецПроцедуры

Мы устанавливаем СтандартнаяОбработка = Ложь и передаем в параметр ВыбраннаяФорма имя нужной нам формы. Важное примечание: этот метод не отработает в веб-клиенте, если переход происходит по внешней навигационной ссылке, жестко привязанной к конкретной форме.

Решение 2: Динамическая настройка одной формы

Самый надежный подход для веб-клиента и переходов по ссылкам — отказаться от использования нескольких разных форм. Создадим одну универсальную (динамическую) управляемую форму. В обработчике ПриСозданииНаСервере выполним проверку доступа пользователя и программно настроим интерфейс.

Рассмотрим, как это работает:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    ДоступПользователя = ПроверитьПользователяНаДоступ();
    
    Если ДоступПользователя = "Количество" Тогда
        // Скрываем ненужные группы или страницы
        Элементы.ГруппаПолныеДанные.Видимость = Ложь;
        Элементы.ГруппаКоличество.Видимость = Истина;
    Иначе
        Элементы.ГруппаПолныеДанные.Видимость = Истина;
        Элементы.ГруппаКоличество.Видимость = Ложь;
    КонецЕсли;

КонецПроцедуры

Управляя свойством Видимость у элементов формы, мы полностью исключаем необходимость вызывать ОткрытьФорму, тем самым избегая любых конфликтов отрисовки в браузере.

Решение 3: Переход через Общую команду

Если переделывать логику на одну форму нецелесообразно, а пользователи заходят в веб-клиент по внешним ссылкам, изменим точку входа. Вместо выдачи ссылки на форму обработки, создадим Общую команду.

  1. Создаем Общую команду в дереве метаданных.
  2. Размещаем ее в нужном разделе командного интерфейса (или просто используем как независимую точку входа).
  3. Выдаем пользователям навигационную ссылку именно на эту Общую команду.

В модуле общей команды выполняем клиентский код:


&НаКлиенте
Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
    
    Доступ = ВызватьСервернуюФункциюПроверкиДоступа();
    
    Если Доступ = "Количество" Тогда
        ОткрытьФорму("Обработка.ОценкаКачества.Форма.УправляемаяФормаКоличество", , ПараметрыВыполненияКоманды.Источник, ПараметрыВыполненияКоманды.Уникальность, ПараметрыВыполненияКоманды.Окно);
    Иначе
        ОткрытьФорму("Обработка.ОценкаКачества.Форма.ОсновнаяФорма", , ПараметрыВыполненияКоманды.Источник, ПараметрыВыполненияКоманды.Уникальность, ПараметрыВыполненияКоманды.Окно);
    КонецЕсли;
    
КонецПроцедуры

В данном случае открытие происходит корректно, так как форма определяется до начала какого-либо процесса отрисовки окон в браузере. Мы не пытаемся отменить уже начавшееся открытие, поэтому ошибки модальности не возникает.

Решение 4: Использование параметров навигационной ссылки

Начиная с версии платформы 8.3.19, механизм навигационных ссылок поддерживает передачу дополнительных параметров непосредственно в URL (аналогично GET-запросам в веб-разработке). Если внешняя система или сайт формирует ссылку для перехода в веб-клиент, в эту ссылку можно заложить параметры запуска.

Проанализируем этот вариант: при старте в процедуре ПриСозданииНаСервере основной формы мы можем прочитать параметры, переданные в свойстве Параметры формы, и сразу же перестроить интерфейс или программно инициировать нужные действия без переоткрытия окон. Это отличная альтернатива, позволяющая сделать точку входа гибкой и не зависящей от сложной маршрутизации на клиенте.

← На главную