Документация для разработчиков
Темная тема

Создание формы редактирования

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

Принципы работы

Можно выделить следующий функционал, как правило, требуемый от административной страницы редактирования:

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

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

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

Начало

Для начала создадим файл bitrix/modules/subscribe/rubric_edit.php следующей структуры:

<?
// подключим все необходимые файлы:
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_admin_before.php"); // первый общий пролог
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/subscribe/include.php"); // инициализация модуля
require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/subscribe/prolog.php"); // пролог модуля
// подключим языковой файл
IncludeModuleLangFile(__FILE__);
// получим права доступа текущего пользователя на модуль
$POST_RIGHT = $APPLICATION->GetGroupRight("subscribe");
// если нет прав - отправим к форме авторизации с сообщением об ошибке
if ($POST_RIGHT == "D")
	$APPLICATION->AuthForm(GetMessage("ACCESS_DENIED"));
?>
<?
// здесь будет вся серверная обработка и подготовка данных
?>
<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_admin_after.php"); // второй общий пролог
?>
<?
// здесь будет вывод страницы с формой
?>
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/epilog_admin.php");?>

Это и есть "костяк страницы", обозначенный на схеме.

Далее, создадим языковой файл, например, /bitrix/modules/subscribe/lang/ru/rubric_edit.php для русского языка. В файле будем определять все языковые сообщения в виде элементов массива: $MESS['идентификатор_сообщения'] = "текст_сообщения";

Затем, поскольку с изначальными параметрами установки БУС каталог /bitrix/modules/ недоступен посредством HTTP-протокола, создадим файл /bitrix/admin/rubric_edit.php:

<?
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/subscribe/admin/rubric_edit.php");
?>

Теперь наш файл доступен по ссылке http://mysite.ru/bitrix/admin/rubric_edit.php.

Функционал страницы

Как видно из схемы, весь функционал страницы условно можно разделить на несколько составных частей:

  • Обработка и подготовка данных
    • Обработка и сохранение изменений
    • Выборка и подготовка данных для формы
    • Настройка интерфейса закладок и параметров административного меню страницы
  • Вывод данных
    • Вывод административного меню страницы
    • Вывод сообщений об ошибках
    • Вывод формы редактирования с метками закладок

В процессе работы нам потребуются экземпляры следующих классов:

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

Обработка и подготовка данных

Настройка интерфейса закладок

Административную форму можно разбить на страницы, переключаемые при помощи закладок. Для описания структуры заладок, нужно создать массив, элементами которого являются ассоциативные массивы, которые могут содержать следующие ключи:

Ключ Описание
DIV Уникальный идентификатор закладки.
TAB Текст, помещаемый на закладку.
TITLE Описание страницы, к которой ведет закладка.
ICON CSS-класс иконки, выводимой рыдом с описанием страницы.
ONSELECT JavaScript-сценарий, который будет выполнен при переключении на закладку.

Далее, нужно создать экземпляр класса CAdminTabControl и передать ему эту структуру.

$aTabs = array(
	array("DIV" => "edit1", "TAB" => GetMessage("rub_tab_rubric"), "ICON"=>"main_user_edit", "TITLE"=>GetMessage("rub_tab_rubric_title")),
	array("DIV" => "edit2", "TAB" => GetMessage("rub_tab_generation"), "ICON"=>"main_user_edit", "TITLE"=>GetMessage("rub_tab_generation_title")),
);
$tabControl = new CAdminTabControl("tabControl", $aTabs);

Обработка и сохранение изменений

Сначала, определим несколько переменных, которые нам понадобятся впоследствии:

$ID = intval($ID);		// идентификатор редактируемой записи
$message = null;		// сообщение об ошибке
$bVarsFromForm = false; // флаг "Данные получены с формы", обозначающий, что выводимые данные получены с формы, а не из БД.

Необходимость сохранения изменений мы определим по следующим параметрам:

  • Страница вызвана методом POST
  • Среди входных данных есть идентификаторы кнопок "Сохранить" и "Применить"

Если эти условия соблюдены и пройдены проверки безопасности, можно сохранять переданные скрипту данные:

if(
	$REQUEST_METHOD == "POST" // проверка метода вызова страницы
	&&
	($save!="" || $apply!="") // проверка нажатия кнопок "Сохранить" и "Применить"
	&&
	$POST_RIGHT=="W"          // проверка наличия прав на запись для модуля
	&&
	check_bitrix_sessid()     // проверка идентификатора сессии
)
{
	$rubric = new CRubric;
  
	// обработка данных формы
	$arFields = Array(
		"ACTIVE"         => ($ACTIVE <> "Y" ? "N" : "Y"),
		"NAME"           => $NAME,
		"SORT"           => $SORT,
		"DESCRIPTION"    => $DESCRIPTION,
		"LID"            => $LID,
		"AUTO"           => ($AUTO <> "Y" ? "N" : "Y"),
		"DAYS_OF_MONTH"  => $DAYS_OF_MONTH,
		"DAYS_OF_WEEK"   => (is_array($DAYS_OF_WEEK) ? implode(",", $DAYS_OF_WEEK) : ""),
		"TIMES_OF_DAY"   => $TIMES_OF_DAY,
		"TEMPLATE"       => $TEMPLATE,
		"VISIBLE"        => ($VISIBLE <> "Y" ? "N" : "Y"),
		"FROM_FIELD"     => $FROM_FIELD,
		"LAST_EXECUTED"  => $LAST_EXECUTED
	);
	// сохранение данных
	if($ID > 0)
	{
		$res = $rubric->Update($ID, $arFields);
	}
	else
	{
		$ID = $rubric->Add($arFields);
		$res = ($ID > 0);
	}
	if($res)
	{
		// если сохранение прошло удачно - перенаправим на новую страницу 
		// (в целях защиты от повторной отправки формы нажатием кнопки "Обновить" в браузере)
		if ($apply != "")
			// если была нажата кнопка "Применить" - отправляем обратно на форму.
			LocalRedirect("/bitrix/admin/rubric_edit.php?ID=".$ID."&mess=ok⟨=".LANG."&".$tabControl->ActiveTabParam());
		else
			// если была нажата кнопка "Сохранить" - отправляем к списку элементов.
			LocalRedirect("/bitrix/admin/rubric_admin.php?lang=".LANG);
	}
	else
	{
		// если в процессе сохранения возникли ошибки - получаем текст ошибки и меняем вышеопределённые переменные
		if($e = $APPLICATION->GetException())
			$message = new CAdminMessage(GetMessage("rub_save_error"), $e);
		$bVarsFromForm = true;
	}
}

Выборка и подготовка данных для формы

Для начала, определим значения по умолчанию. Все данные, полученные из БД будем сохранять в переменные с префиксом str_

$str_SORT          = 100;
$str_ACTIVE        = "Y";
$str_AUTO          = "N";
$str_DAYS_OF_MONTH = "";
$str_DAYS_OF_WEEK  = "";
$str_TIMES_OF_DAY  = "";
$str_VISIBLE       = "Y";
$str_LAST_EXECUTED = ConvertTimeStamp(false, "FULL");
$str_FROM_FIELD    = COption::GetOptionString("subscribe", "default_from");

Выберем данные:

if($ID>0)
{
	$rubric = CRubric::GetByID($ID);  
	if(!$rubric->ExtractFields("str_"))
		$ID=0;
}

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

// если данные переданы из формы, инициализируем их
if($bVarsFromForm)
	$DB->InitTableVarsForEdit("b_list_rubric", "", "str_");
$APPLICATION->SetTitle(($ID>0? GetMessage("rub_title_edit").$ID : GetMessage("rub_title_add")));

Задание параметров административного меню

Также можно задать административное меню, которое будет отображаться над таблицей со списком (только если у текущего пользователя есть права на редактирование). Административное формируется в виде массива, элементами которого являются ассоциативные массивы с ключами:

Ключ Описание
TEXT Текст пункта меню.
TITLE Текст всплывающей подсказки пункта меню.
LINK Ссылка на кнопке.
LINK_PARAM Дополнительные параметры ссылки (напрямую подставляются в тэг <A>).
ICON CSS-класс иконки действия.
HTML Задание пункта меню напрямую HTML-кодом.
SEPARATOR Разделитель между пунктами меню (true|false).
NEWBAR Новый блок элементов меню (true|false).
MENU Создание выпадающего подменю. Значение задается аналогично контекстному меню строки таблицы.

Пример:

$aMenu = array(
	array(
		"TEXT"  => GetMessage("rub_list"),
		"TITLE" => GetMessage("rub_list_title"),
		"LINK"  => "rubric_admin.php?lang=".LANG,
		"ICON"  => "btn_list",
	)
);
if($ID>0)
{
	$aMenu[] = array("SEPARATOR"=>"Y");
  
	$aMenu[] = array(
		"TEXT"  => GetMessage("rub_add"),
		"TITLE" => GetMessage("rubric_mnu_add"),
		"LINK"  => "rubric_edit.php?lang=".LANG,
		"ICON"  => "btn_new",
	);
	$aMenu[] = array(
		"TEXT"  => GetMessage("rub_delete"),
		"TITLE" => GetMessage("rubric_mnu_del"),
		"LINK"  => "javascript:if(confirm('".GetMessage("rubric_mnu_del_conf")."')) ".
			"window.location='rubric_admin.php?ID=".$ID."&action=delete⟨=".LANG."&".bitrix_sessid_get()."';",
		"ICON"  => "btn_delete",
	);
	$aMenu[] = array("SEPARATOR"=>"Y");
	$aMenu[] = array(
		"TEXT"  => GetMessage("rub_check"),
		"TITLE" => GetMessage("rubric_mnu_check"),
		"LINK"  => "template_test.php?lang=".LANG."&ID=".$ID
	);
}

Результирующая структура передается конструктору класса CAdminContextMenu.

Вывод данных

Как видно на схеме, подготовку страницы и основной вывод необходимо разделить подключением административного файла prolog_admin_after.php:

// не забудем разделить подготовку данных и вывод
require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/prolog_admin_after.php");

Прежде всего, выведем подготовленное административное меню.

// создадим экземпляр класса административного меню
$context = new CAdminContextMenu($aMenu);
// выведем меню
$context->Show();

Если есть сообщения об ошибках или об успешном сохранении - выведем их.

if($_REQUEST["mess"] == "ok" && $ID>0)
	CAdminMessage::ShowMessage(array("MESSAGE"=>GetMessage("rub_saved"), "TYPE"=>"OK"));
if($message)
	echo $message->Show();
elseif($rubric->LAST_ERROR!="")
	CAdminMessage::ShowMessage($rubric->LAST_ERROR);

Далее, выводим собственно форму. Для инициализации механизма закладок и вывода панели закладок следует использовать метод CAdminTabControl::Begin(). Для разделения закладок - CAdminTabControl::BeginNextTab(). Для завершения - CAdminTabControl::End().

<form method="POST" Action="<?echo $APPLICATION->GetCurPage()?>" ENCTYPE="multipart/form-data" name="post_form">
<?// проверка идентификатора сессии ?>
<?echo bitrix_sessid_post();?>
<input type="hidden" name="lang" value="<?=LANG?>">
<?if($ID>0 && !$bCopy):?>
	<input type="hidden" name="ID" value="<?=$ID?>">
<?endif;?>
<?
// отобразим заголовки закладок
$tabControl->Begin();
?>
<?
//********************
// первая закладка - форма редактирования параметров рассылки
//********************
$tabControl->BeginNextTab();
?>
	<tr>
		<td width="40%"><?echo GetMessage("rub_act")?></td>
		<td width="60%"><input type="checkbox" name="ACTIVE" value="Y"<?if($str_ACTIVE == "Y") echo " checked"?> /></td>
	</tr>
  
	<!--  HTML-код строк таблицы -->
  
	<tr>
		<td><?echo GetMessage("rub_auto")?></td>
		<td><input type="checkbox" name="AUTO" value="Y"<?if($str_AUTO == "Y") echo " checked"?> 
			OnClick="if(this.checked) tabControl.EnableTab('edit2'); else tabControl.DisableTab('edit2');" /></td>
	</tr>
<?
//********************
// вторая закладка - параметры автоматической генерации рассылки
//********************
$tabControl->BeginNextTab();
?>
	<tr class="heading">
		<td colspan="2"><?echo GetMessage("rub_schedule")?></td>
	</tr>
	<tr>
		<td width="40%"><span class="required">*</span><?echo GetMessage("rub_last_executed"). " (".FORMAT_DATETIME."):"?></td>
		<td width="60%"><?echo CalendarDate("LAST_EXECUTED", $str_LAST_EXECUTED, "post_form", "20")?></td>
	</tr>
  
	<!--  HTML-код строк таблицы -->
  
	<tr>
		<td><span class="required">*</span><?echo GetMessage("rub_post_fields_from")?></td>
		<td><input type="text" name="FROM_FIELD" value="<?echo $str_FROM_FIELD;?>" size="30" maxlength="255" /></td>
	</tr>
<?
// завершение формы - вывод кнопок сохранения изменений
$tabControl->Buttons(
	array(
		"disabled"=>($POST_RIGHT<"W"),
		"back_url"=>"rubric_admin.php?lang=".LANG,
	)
);
?>
<?
// завершаем интерфейс закладки
$tabControl->End();
?>

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

<?
// дополнительное уведомление об ошибках - вывод иконки около поля, в котором возникла ошибка
$tabControl->ShowWarnings("post_form", $message);
?>

Механизм закладок предоставляет также интерфейс для динамического управления закладками посредством JavaScript. В качестве примера, предоставим блокирование закладки:

<script language="JavaScript">
<!--
	if(document.post_form.AUTO.checked)
		tabControl.EnableTab('edit2');
	else
		tabControl.DisableTab('edit2');
//-->
</script>

Ну и завершим нашу страницу информационным сообщением:

<?echo BeginNote();?>
<span class="required">*</span><?echo GetMessage("REQUIRED_FIELDS")?>
<?echo EndNote();?>
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/main/include/epilog_admin.php");?>

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



© «Битрикс», 2001-2024, «1С-Битрикс», 2024