Перейти к содержимому

Форма в админке - вкладки, проверка значений, тулбар

Собираем свою форму правки в административной части: вкладки, сохранение с проверкой, показ ошибок без потери введённого и кнопки на панели.

Механика

Административная часть сайта строится на классах старого ядра. Современного аналога у неё нет, и форму собирают теми же средствами, что и штатные страницы платформы.

Страница формы обслуживает сразу два разных состояния. Сначала она принимает отправленные данные, потом рисует форму, и порядок этих частей в файле имеет значение.

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

Любое изменение данных на странице проверяют ключом сеанса. Без этой проверки страница принимает запрос откуда угодно, а сама административная часть - самое ценное место сайта.

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

При ошибке проверки форму показывают с уже введёнными значениями. Отдельный признак говорит форме брать данные из запроса, а не перечитывать их из базы.

Ошибки показывают привычным для административной части сайта способом. Сообщение выводится над формой, а поля остаются заполненными, чтобы человек не вводил всё заново.

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

Возврат к списку записей - обязательная часть сценария правки. После сохранения человек ожидает увидеть список с новой записью, а не пустую форму без объяснений.

Права на данные проверяет ваш код, а не сама платформа. Страница в административной части доступна любому сотруднику с доступом в раздел, и ограничения ставят явно.

Форма в административной части живёт по своим правилам, и спорить с ними дороже, чем принять. Сотрудники ждут привычных вкладок, кнопок на панели и сообщения об ошибке над формой, а не собственного интерфейса решения.

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

Шаги

  1. Проверить право на работу с данными в самом начале кода этой страницы.
  2. Принять и проверить отправленные данные ещё до вывода формы.
  3. Сохранить запись и увести сотрудника обратно к списку записей.
  4. При ошибке показать сообщение и вернуть в форму введённые значения.
  5. Собрать форму на вкладках и описать все её поля.
  6. Вернуть на панель нужные кнопки: переход к списку, добавление, удаление.

Код

Готовим страницу и проверяем право:

require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_admin_before.php';
\Bitrix\Main\Loader::includeModule('vendor.module');
// пролог админки подключают до любого своего кода страницы
if ($APPLICATION->GetGroupRight('vendor.module') < 'W') {
$APPLICATION->AuthForm('Доступ запрещён'); // дальше страница не выполняется
}

Проверка права идёт до любой работы с данными. Страница административной части сама по себе не закрыта: доступ в раздел ещё не означает право менять записи вашего модуля.

Принимаем отправленные данные:

$request = \Bitrix\Main\Context::getCurrent()->getRequest();
$errors = [];
if ($request->isPost() && $request['save'] && check_bitrix_sessid()) {
$result = ItemTable::update((int)$request['ID'], ['NAME' => (string)$request['NAME']]);
if (!$result->isSuccess()) { $errors = $result->getErrorMessages(); }
}
// блок стоит до вывода формы, иначе она покажет старые значения

Проверка ключа сеанса обязательна для любой операции записи данных. Без неё форму можно отправить со стороннего сайта от имени вошедшего администратора.

Уводим к списку после успеха:

if (!$errors && $request->isPost() && $request['save']) {
LocalRedirect('/bitrix/admin/vendor_items.php?' . http_build_query([
'lang' => LANGUAGE_ID,
]));
}
// возврат к списку после сохранения - привычное поведение админки

Переход к списку после сохранения экономит сотруднику лишний клик. Заодно он избавляет от повторной отправки формы при обновлении страницы в браузере.

Показываем ошибки без потери введённого:

if ($errors) {
CAdminMessage::ShowMessage(['MESSAGE' => 'Не удалось сохранить',
'DETAILS' => implode('<br>', $errors), 'TYPE' => 'ERROR']);
$bVarsFromForm = true; // форма возьмёт значения из запроса
}

Признак возврата значений спасает уже введённые сотрудником данные. Без него форма перечитает запись из базы, и человек потеряет всё, что успел набрать.

Собираем форму на вкладках:

$tabControl = new CAdminTabControl('vendorItemTabs', [
['DIV' => 'main', 'TAB' => 'Основное', 'TITLE' => 'Основные параметры'],
['DIV' => 'more', 'TAB' => 'Дополнительно', 'TITLE' => 'Прочие настройки'],
]);
$tabControl->Begin();
$tabControl->BeginNextTab();
// поля первой вкладки: подписи и значения выводятся ячейками таблицы
$tabControl->Buttons(); // кнопки сохранения и отмены
$tabControl->End();

Объект вкладок рисует и шапку, и подвал формы. Своя разметка вместо него ломает привычный вид административной части и лишает штатных кнопок.

Возвращаем кнопки панели:

$menu = new CAdminContextMenu([
['TEXT' => 'Список', 'LINK' => 'vendor_items.php?lang=' . LANGUAGE_ID, 'ICON' => 'btn_list'],
['TEXT' => 'Добавить', 'LINK' => 'vendor_item_edit.php?lang=' . LANGUAGE_ID, 'ICON' => 'btn_new'],
]);
$menu->Show();
// своя форма заменяет штатную панель, и нужные кнопки возвращают руками

Панель кнопок собирают отдельно от самой формы правки записи. Без неё сотрудник остаётся на странице правки без единой ссылки обратно, и это первое, о чём он спросит.

Проверяем страницу глазами обычного сотрудника:

printf("право на модуль: %s\n", $APPLICATION->GetGroupRight('vendor.module'));
printf("группы: %s\n", implode(',', $USER->GetUserGroupArray()));
// под администратором проверки прав проходят всегда и ничего не проверяют

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

Ещё одна привычная деталь - подтверждение опасных действий. Удаление записи из формы делают через отдельную кнопку с вопросом, а не тихой ссылкой рядом с сохранением.

Ограничения

Административная часть платформы остаётся на старом ядре. Современного набора классов для неё нет, и код формы пишут в процедурном стиле.

Своя форма правки не наследует штатные проверки платформы. Права, обязательность полей и защита от подделки запроса ложатся на ваш код целиком.

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

Файлы страниц административной части не попадают под автозагрузку классов решения. Их кладут в каталог административных страниц проекта и подключают явно.

Типичные проблемы

После сохранения форма показывает старые значения.

Блок сохранения данных стоит после вывода самой формы. Форма собирается раньше записи и успевает прочитать ещё прежние данные.

При ошибке проверки поля формы очищаются.

Не взведён признак возврата введённых значений из запроса. Форма перечитывает запись из базы и затирает всё введённое.

Сохранение молча не срабатывает.

Ключ сеанса не проверен или вовсе не передан формой. Страница отбрасывает такой запрос без сообщения, и выглядит это как отсутствие реакции.

У формы пропали кнопки перехода к списку.

Своя форма правки заменила штатную панель кнопок целиком. Нужные кнопки панели возвращают собственным контекстным меню.

Страницу открывает сотрудник без прав на данные.

Проверка права доступа не сделана в коде самой страницы. Доступ в административный раздел сам по себе прав на ваш модуль не даёт.

Частые вопросы

Можно ли собрать форму на D7?

В административном разделе - нет: там работают классы старого ядра. Современные средства применяют в публичной части и в своих интерфейсах на компонентах.

Где хранить файлы своих страниц админки?

В каталоге административных страниц проекта, с подключением файла модуля. Так они переживают обновление платформы и не путаются со штатными.

Как показать поле нестандартного вида?

Методами объекта вкладок для своего поля: они дают разметку ячейки и подпись. Так поле остаётся в общем оформлении формы.

Нужно ли проверять права, если пункт меню виден только администратору?

Да, обязательно: страница открывается по прямому адресу. Видимость пункта меню правом доступа не является.

Как сделать удаление записи из формы?

Отдельной кнопкой панели с подтверждением и проверкой ключа сеанса. После удаления человека возвращают к списку, а не оставляют на пустой форме.

Смежное

Первоисточник