1C-Битрикс: Управление сайтом

Пользовательские формы редактирования элементов

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

Рассмотрим в качестве примера форму редактирования статьи информационного издания. Для нашего издания необходимы поля:
  • заголовок статьи;
  • текст анонса;
  • картинка для анонса;
  • текст статьи;
  • большая картинка;
  • время выхода статьи;
  • автор;
  • статус документооборота для утверждения редактором;
  • список разделов для привязки.
Процесс создания и настройки информационных блоков подробно описан в документации. Поэтому лишь рассмотрим отсутствующие и лишние, по сравнению со стандартной формой редактирования, элементы:
  • множество лишних полей (сортировка, дата окончания показа, ...);
  • необходимо изменить порядок полей редактирования;
  • было бы удобнее, если при вводе только большой картинки автоматически из нее создавалась картинка для анонса;
  • необходимо чтобы поле со статьей тоже было обязательным (вместе с названием);
  • при публикации новости автоматически записывать время в поле с датой новости.

Для начала возьмем оригинальный код страницы /bitrix/modules/iblock/admin/iblock_element_edit.php, а именно, ту ее часть, которая настраивается:

<form method="POST"
action="/bitrix/admin/iblock_element_edit.php?type=<?
echo $type?>&lang=<?
echo LANG?>&IBLOCK_ID=<?
echo $IBLOCK_ID?>&<?
echo GetFilterParams("filter_");?>#tb" ENCTYPE="multipart/form-data"
name="form_element">
<?echo GetFilterHiddens("filter_");?>
<input type="hidden" name="Update" value="Y">
<input type="hidden" name="from" value="<?echo htmlspecialchars($from)?>">
<input type="hidden" name="WF" value="<?echo htmlspecialchars($WF)?>">
<input type="hidden" name="return_url" value="<?echo $return_url?>">
<input type="hidden" name="ID" value="<?echo $ID?>">
<input type="hidden"
name="IBLOCK_SECTION_ID" value="<?echo IntVal($IBLOCK_SECTION_ID)?>">
<table border="0" cellspacing="1" cellpadding="3"
class="edittable" width="100%">
<?if ($WF=="Y" || $view=="Y"):?>
<tr>
<td valign="top"
align="right"><font
class="tablefieldtext"><?=GetMessage("IBLOCK_WF_STATUS")?></font></td>
<td valign="top"
nowrap><font class="tablebodytext">
<?echo SelectBox("WF_STATUS_ID",
CWorkflowStatus::GetDropDownList("N", "desc"), "",
$str_WF_STATUS_ID);?></font></td>
</tr>
<?endif;?>
<?
if($ID>0):
$p = CIblockElement::GetByID($ID);
$pr = $p->ExtractFields("prn_");

if(CModule::IncludeModule("workflow")):
if(strlen($pr["DATE_CREATE"])>0):
?>
<tr>
<td valign="top" align="right"><font
class="tablefieldtext"><?echo
GetMessage("IBLOCK_CREATED")?></font></td>
<td valign="top"><font
class="tablebodytext"><?echo $pr["DATE_CREATE"]?><?
if (intval($pr["CREATED_BY"])>0):
?>&nbsp;&nbsp;&nbsp;[<a
class="tablebodylink"
href="user_edit.php?lang=<?
=LANG?>&ID=<?=$pr["CREATED_BY"]?>"><?
echo $pr["CREATED_BY"]?></a>]&nbsp;<?
=htmlspecialcharsex($pr["CREATED_USER_NAME"])?><?
endif;
?></font></td>
</tr>
<?endif;?>
<tr>
<td valign="top"
align="right"><font
class="tablefieldtext"><?echo
GetMessage("IBLOCK_LAST_UPDATE")?></font></td>
<td valign="top"><font
class="tablebodytext"><?echo $str_TIMESTAMP_X?><?
if (intval($str_MODIFIED_BY)>0):
?>&nbsp;&nbsp;&nbsp;[<a class="tablebodylink"
href="user_edit.php?lang=<?
=LANG?>&ID=<?=$str_MODIFIED_BY?>"><?
echo $str_MODIFIED_BY?></a>]&nbsp;<?=$str_USER_NAME?><?
endif;
?></font></td>
</tr>
<?endif?>
<?if($WF=="Y" && strlen($prn_WF_DATE_LOCK)>0):?>
<tr>
<td valign="top" align="right" nowrap><font
class="tablefieldtext"><?echo
GetMessage("IBLOCK_DATE_LOCK")?></font></td>
<td valign="top" nowrap><font
class="tablebodytext"><?echo $prn_WF_DATE_LOCK?><?
if (intval($prn_WF_LOCKED_BY)>0):
?>&nbsp;&nbsp;&nbsp;[<a class="tablebodylink"
href="user_edit.php?lang=<?=lang?>&id=<?
=$prn_WF_LOCKED_BY?>"><?
echo $prn_WF_LOCKED_BY?></a>]&nbsp;<?
=$prn_LOCKED_USER_NAME?><?
endif;
?></font></td>
</tr>
<?endif;?>
<?endif;?>
<tr>
<td valign="top" width="50%" align="right"><font
class="tablefieldtext"><?
echo GetMessage("IBLOCK_ACTIVE")?></font></td>
<td valign="top" width="50%"><input
type="checkbox" name="ACTIVE"
value="Y"<?if($str_ACTIVE=="Y")echo " checked"?>></td>
</tr>
<tr>
<td valign="top" align="right"><font
class="tablefieldtext"><?
echo GetMessage("IBLOCK_ACTIVE_PERIOD")?>(<?
echo CLang::GetDateFormat("SHORT");?>)</font></td>
<td valign="top"><font class="tablebodytext">
<?echo CalendarPeriod("ACTIVE_FROM",
$str_ACTIVE_FROM,
"ACTIVE_TO",
$str_ACTIVE_TO,
"form_element",
"N",
"class=\"typeselect\"",
"class=\"typeinput\"", "19")?>
</font>
</td>
</tr>
<?if($arIBTYPE["SECTIONS"]=="Y"):?>
<tr>
<td valign="top" align="right"><font
class="tablefieldtext"><?
echo GetMessage("IBLOCK_SECTION")?></font></td>
<td valign="top" align="left">
<?$l = CIBlockSection::GetTreeList(Array("IBLOCK_ID"=>$IBLOCK_ID));?>
<select name="IBLOCK_SECTION[]" size="14" multiple class="typeselect">
<option value="0"<?
if (is_array($str_IBLOCK_ELEMENT_SECTION) &&
in_array(0, $str_IBLOCK_ELEMENT_SECTION))
echo " selected"?>>
<?echo GetMessage("IBLOCK_CONTENT")?></option>
<?
while($l->ExtractFields("l_")):
?><option value="<?echo $l_ID?>"<?
if (is_array($str_IBLOCK_ELEMENT_SECTION) &&
in_array($l_ID, $str_IBLOCK_ELEMENT_SECTION))
echo " selected"?>>
<?echo str_repeat(" . ", $l_DEPTH_LEVEL)?>
<?echo $l_NAME?></option><?
endwhile;
?>
</select>
</td>
</tr>
<?endif?>
<tr>
<td valign="top" align="right"><font
class="tablefieldtext"><font
class="required">*</font><?
echo GetMessage("IBLOCK_NAME")?></font></td>
<td valign="top">
<input type="text" name="NAME" size="50"
maxlength="255" class="typeinput"
value="<?echo $str_NAME?>">
</td>
</tr>
<tr>
<td valign="top" align="right"><font
class="tablefieldtext"><?
echo GetMessage("IBLOCK_SORT")?></font></td>
<td valign="top">
<input type="text" name="SORT"
size="7" class="typeinput"
maxlength="10" value="<?echo $str_SORT?>">
</td>
</tr>
<?if(COption::GetOptionString("iblock", "show_xml_id", "N")=="Y"):?>
<tr>
<td valign="top" align="right"><font class="tablefieldtext"><?echo GetMessage("IBLOCK_EXTERNAL_CODE")?></font></td>
<td valign="top">
<input type="text" size="20" name="XML_ID" maxlength="255" class="typeinput" value="<?echo $str_XML_ID?>">
</td>
</tr>
<?endif?>
<tr>
<td valign="top" align="right"><font class="tablefieldtext"><?echo GetMessage("IBLOCK_CODE")?></font></td>

<td valign="top">
<input type="text" size="20" name="CODE" maxlength="255" class="typeinput" value="<?echo $str_CODE?>">
</td>
</tr>
<?if(count($PROP)>0):?>
<tr>
<td valign="top" align="center" colspan="2"
class="tablehead"><font
class="tableheadtext"><b><?
echo GetMessage("IBLOCK_ELEMENT_PROP_VALUE");?></b></font></td>
</tr>
<?
foreach($PROP as $prop_code=>$prop_fields):
$prop_values = $prop_fields["VALUE"];
?>
<tr>
<td valign="top" align="right"><font
class="tablefieldtext"><?
echo htmlspecialcharsex($prop_fields["NAME"])?>:</font></td>
<td valign="top">
<font class="tablebodytext"><?
_ShowPropertyField('PROP['.$prop_fields["ID"].']',
$prop_fields,
$prop_values,
((!$bVarsFromForm) &&
($ID<=0)), $bVarsFromForm);?></font>
</td>
</tr>
<?endforeach;?>
<?endif?>

<tr>
<td valign="top" align="center" colspan="2"
class="tablehead" nowrap><font
class="tableheadtext"><b><?
echo GetMessage("IBLOCK_ELEMENT_PREVIEW")?></b></font></td>
</tr>
<tr>
<td valign="top" align="right"
class="tablebody" nowrap><font
class="tablefieldtext"><?echo GetMessage("IBLOCK_PICTURE")?></font></td>
<td valign="top" align="left" class="tablebody"><font class="tablebodytext">
<?echo CFile::InputFile("PREVIEW_PICTURE",
20, $str_PREVIEW_PICTURE, false, 0,
"IMAGE", "class=\"typefile\"", 40);?><br>
<?echo CFile::ShowImage($str_PREVIEW_PICTURE, 200, 200, "border=0", "", true)?>
</font>
</td>
</tr>

<?if (ereg('(MSIE|Internet Explorer) ([0-9]).([0-9])+',
$_SERVER['HTTP_USER_AGENT'],
$version) &&
IntVal($version[2]) >= 5 &&
COption::GetOptionString("iblock",
"use_htmledit",
"Y") == "Y" &&
CModule::IncludeModule("fileman")):?>
<tr>
<td valign="top" colspan="2">
<?CFileMan::AddHTMLEditorFrame("PREVIEW_TEXT",
$str_PREVIEW_TEXT,
"PREVIEW_TEXT_TYPE",
$str_PREVIEW_TEXT_TYPE, 300,
"N",
0,
"",
"",
$arIBlock["LID"]
);?>
</td>
</tr>
<?else:?>
<tr>
<td valign="top" align="right"><font class="tablefieldtext"><?echo GetMessage("IBLOCK_DESC_TYPE")?></font></td>
<td valign="top">
<font class="tablebodytext">
<input type="radio"
name="PREVIEW_TEXT_TYPE"
value="text"<?
if ($str_PREVIEW_TEXT_TYPE != "html")
echo " checked"?>>
<?echo GetMessage("IBLOCK_DESC_TYPE_TEXT")?> /
<input type="radio" name="PREVIEW_TEXT_TYPE"
value="html"<?
if ($str_PREVIEW_TEXT_TYPE=="html")
echo " checked"?>> <?echo GetMessage("IBLOCK_DESC_TYPE_HTML")?>
</font>
</td>
</tr>
<tr>
<td valign="top" align="center"colspan="2" width="100%">
<textarea cols="110" class="typearea"
rows="10" name="PREVIEW_TEXT"
wrap="virtual"><?echo $str_PREVIEW_TEXT?></textarea>
</td>
</tr>
<?endif?>
<tr>
<td valign="top" align="center" colspan="2"
class="tablehead" nowrap><font
class="tableheadtext"><b><?
echo GetMessage("IBLOCK_ELEMENT_DETAIL")?></b></font></td>
</tr>
<tr>
<td valign="top" align="right"><font class="tablefieldtext">
<?echo GetMessage("IBLOCK_PICTURE")?></font></td>
<td valign="top"><font class="tablebodytext">
<?echo CFile::InputFile("DETAIL_PICTURE",
20, $str_DETAIL_PICTURE, false, 0,
"IMAGE", "class=\"typefile\"", 40);?><br>
<?echo CFile::ShowImage($str_DETAIL_PICTURE, 200, 200, "border=0", "", true)?>
</font>
</td>
</tr>
<?if (ereg('(MSIE|Internet Explorer) ([0-9]).([0-9])+',
$_SERVER['HTTP_USER_AGENT'],
$version) && IntVal($version[2])>=5 &&
COption::GetOptionString("iblock",
"use_htmledit",
"Y") == "Y" &&
CModule::IncludeModule("fileman")):?>
<tr>
<td valign="top" colspan="2">
<?CFileMan::AddHTMLEditorFrame("DETAIL_TEXT",
$str_DETAIL_TEXT,
"DETAIL_TEXT_TYPE",
$str_DETAIL_TEXT_TYPE,
440,
"N",
0,
"",
"",
$arIBlock["LID"]
);?>
</td>
</tr>
<?else:?>
<tr>
<td valign="top" align="right"><font class="tablefieldtext"><?echo GetMessage("IBLOCK_DESC_TYPE")?></font></td>
<td valign="top">
<font class="tablebodytext">
<input type="radio" name="DETAIL_TEXT_TYPE"
value="text"
<?if ($str_DETAIL_TEXT_TYPE!="html")
echo " checked"?>>
<?echo GetMessage("IBLOCK_DESC_TYPE_TEXT")?> /
<input type="radio" name="DETAIL_TEXT_TYPE"
value="html"
<?if ($str_DETAIL_TEXT_TYPE=="html")
echo " checked"?>>
<?echo GetMessage("IBLOCK_DESC_TYPE_HTML")?>
</font>
</td>
</tr>
<tr>
<td valign="top" align="center" colspan="2">
<textarea cols="110" rows="20"
class="typearea" name="DETAIL_TEXT"
wrap="virtual"><?echo $str_DETAIL_TEXT?></textarea>
</td>
</tr>
<?endif?>
<?if (CModule::IncludeModule("workflow")):?>
<tr>
<td class="tablehead" align="center"
colspan="2"><font
class="tableheadtext"><b><?=GetMessage("IBLOCK_COMMENTS")?></b></font></td>
</tr>
<tr>
<td valign="top" align="center" colspan="2">
<textarea name="WF_COMMENTS" class="typearea" cols="110" rows="10"><?echo $str_WF_COMMENTS?></textarea></td>
</tr>
<?endif?>
<?
if ($view!="Y" && CModule::IncludeModule("catalog") && CCatalog::GetByID($IBLOCK_ID))
{
include($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/catalog/admin/templates/product_edit.php");
}
?>
</table>
<br>
<input <?if ($view=="Y" ||
$prn_LOCK_STATUS=="red")
echo "disabled";?>
type="submit" class="button"
name="save"
value="<?echo (($ID > 0)?GetMessage('IBLOCK_SAVE'):GetMessage('IBLOCK_ADD'))?>">
&nbsp;
<input <?if ($view=="Y" || $prn_LOCK_STATUS=="red")
echo "disabled";?>
class="button"
type="submit"
name="apply"
value="<?echo GetMessage('IBLOCK_APPLY')?>">
&nbsp;
<input <?if ($view=="Y" || $prn_LOCK_STATUS=="red")
echo "disabled";?>
type="submit"
class="button"
name="dontsave"
value="<? echo GetMessage("IBLOCK_DONT_SAVE") ?>">
&nbsp;
<input type="reset" value="<?echo GetMessage('IBLOCK_RESET');?>" class="button">
</form>

Сохраним этот скрипт в файл, например, в /bitrix/php_interface/include/iblock_element_edit.php, создадим там же файл /bitrix/php_interface/include/iblock_element_edit_before_save.php - в нем будет находиться скрипт, отвечающий за обработку во время сохранения элемента. Теперь в настройках модуля информационных блоков необходимо для типа указать пути к этим файлам в поля "Файл для редактирования элемента, позволяющий модифицировать поля перед сохранением" и "Файл с формой редактирования элемента".

Это была подготовительная часть, перейдем к изменению внешнего вида формы. Удалим лишние поля и переверстаем страницу /bitrix/php_interface/include/iblock_element_edit.php под наши нужды. После всех изменений получился следующий код:

<form method="POST" action="/bitrix/admin/iblock_element_edit.php?type=<?echo $type?>
&lang=<?echo LANG?>&IBLOCK_ID=<?echo $IBLOCK_ID?>&<?
echo GetFilterParams("filter_");?>#tb" ENCTYPE="multipart/form-data" name="form_element">
<?echo GetFilterHiddens("filter_");?>
<input type="hidden" name="Update" value="Y">
<input type="hidden" name="from" value="<?echo htmlspecialchars($from)?>">
<input type="hidden" name="WF" value="<?echo htmlspecialchars($WF)?>">
<input type="hidden" name="return_url" value="<?echo $return_url?>">
<input type="hidden" name="ID" value="<?echo $ID?>">
<input type="hidden" name="IBLOCK_SECTION_ID" value="<?echo IntVal($IBLOCK_SECTION_ID)?>">
<table border="0" cellspacing="1" cellpadding="3" class="edittable" width="100%">
<?
$prop_code = "AUTHOR";
$prop_fields = $PROP[$prop_code];
$prop_values = $prop_fields["VALUE"];
?>
<tr>
<td valign="top" align="right"><font class="tablefieldtext"><?echo htmlspecialcharsex($prop_fields["NAME"])?>:</font></td>
<td valign="top">
<font class="tablebodytext"><?
_ShowPropertyField('PROP['.$prop_fields["ID"].']',
$prop_fields, $prop_values, ((!$bVarsFromForm) && ($ID<=0)), $bVarsFromForm);?></font>
</td>
</tr>
<tr>
<td valign="top" align="right"><font class="tablefieldtext">Дата (<?echo CLang::GetDateFormat("SHORT");?>)</font></td>
<td valign="top"><font class="tablebodytext">
<?echo CalendarDate("ACTIVE_FROM", $str_ACTIVE_FROM, "form_element", "20", "class=\"typeinput\"")?>
</font>
</td>
</tr>
<tr>
<td valign="top" align="right"><font class="tablefieldtext"><font class="required">*</font>Заголовок</font></td>
<td valign="top">
<textarea name="NAME" cols="50" rows="5" class="typearea"><?echo $str_NAME?></textarea>
</td>
</tr>
<tr>
<td valign="top" align="center" colspan="2" class="tablehead" nowrap><font class="tableheadtext"><b>Анонс</b></font></td>
</tr>
<?if (ereg('(MSIE|Internet Explorer) ([0-9]).([0-9])+',
$_SERVER['HTTP_USER_AGENT'],
$version) &&
IntVal($version[2])>=5 &&
COption::GetOptionString("iblock", "use_htmledit", "Y")=="Y" &&
CModule::IncludeModule("fileman")):?>
<tr>
<td valign="top" colspan="2">
<?CFileMan::AddHTMLEditorFrame("PREVIEW_TEXT",
$str_PREVIEW_TEXT,
"PREVIEW_TEXT_TYPE",
$str_PREVIEW_TEXT_TYPE, 440,
"N",
0,
"",
"",
$arIBlock["LID"]
);?>
</td>
</tr>
<?else:?>
<tr>
<td valign="top" align="right"><font class="tablefieldtext">Тип анонса:</font></td>
<td valign="top">
<font class="tablebodytext">
<input type="radio"
name="PREVIEW_TEXT_TYPE"
value="text"<?
if ($str_PREVIEW_TEXT_TYPE!="html")
echo " checked"?>> Текст /
<input type="radio"
name="PREVIEW_TEXT_TYPE"
value="html"<?
if ($str_PREVIEW_TEXT_TYPE=="html")
echo " checked"?>> HTML
</font>
</td>
</tr>
<tr>
<td valign="top" align="center"colspan="2" width="100%">
<textarea cols="110" class="typearea" rows="10" name="PREVIEW_TEXT" wrap="virtual"><?echo $str_PREVIEW_TEXT?></textarea>
</td>
</tr>
<?endif?>
<tr>
<td valign="top" align="center" colspan="2" class="tablehead" nowrap><font class="tableheadtext"><b>Статья</b></font></td>
</tr>
<?if (ereg('(MSIE|Internet Explorer) ([0-9]).([0-9])+',
$_SERVER['HTTP_USER_AGENT'],
$version) && IntVal($version[2])>=5 &&
COption::GetOptionString("iblock",
"use_htmledit",
"Y") == "Y" &&
CModule::IncludeModule("fileman")):?>
<tr>
<td valign="top" colspan="2">
<?CFileMan::AddHTMLEditorFrame("DETAIL_TEXT",
$str_DETAIL_TEXT,
"DETAIL_TEXT_TYPE",
$str_DETAIL_TEXT_TYPE,
440,
"N",
0,
"",
"",
$arIBlock["LID"]
)?>
</td>
</tr>
<?else:?>
<tr>
<td valign="top" align="right"><font class="tablefieldtext">Тип текста статьи:</font></td>
<td valign="top">
<font class="tablebodytext">
<input type="radio" name="DETAIL_TEXT_TYPE"
value="text"<?
if ($str_DETAIL_TEXT_TYPE!="html")
echo " checked"?>> Текст /
<input type="radio" name="DETAIL_TEXT_TYPE"
value="html"<?if($str_DETAIL_TEXT_TYPE=="html")echo " checked"?>> HTML
</font>
</td>
</tr>
<tr>
<td valign="top" align="center" colspan="2">
<textarea cols="110" rows="20" class="typearea" name="DETAIL_TEXT" wrap="virtual"><?echo $str_DETAIL_TEXT?></textarea>
</td>
</tr>
<?endif?>
<tr>
<td valign="top" align="right"><font class="tablefieldtext">Большая картинка</font></td>
<td valign="top"><font class="tablebodytext">
<?echo CFile::InputFile("DETAIL_PICTURE", 20, $str_DETAIL_PICTURE, false, 0, "IMAGE", "class=\"typefile\"", 40);?><br>
<?echo CFile::ShowImage($str_DETAIL_PICTURE, 200, 200, "border=0", "", true)?>
</font>
</td>
</tr>
<tr>
<td valign="top" align="right" class="tablebody" nowrap><font class="tablefieldtext">Картинка в списке:</font></td>
<td valign="top" align="left" class="tablebody"><font class="tablebodytext">
<input type="checkbox" name="MAKE_PREVIEW_PICTURE" value="Y" onClick="document.getElementById('PREVIEW_PICTURE').disabled=this.checked;">Создать из большой картинки<br>
<?echo CFile::InputFile("PREVIEW_PICTURE", 20, $str_PREVIEW_PICTURE, false, 0, "IMAGE", "class=\"typefile\"", 40);?><br>
<?echo CFile::ShowImage($str_PREVIEW_PICTURE, 200, 200, "border=0", "", true)?>
</font>
</td>
</tr>
<?if($arIBTYPE["SECTIONS"]=="Y"):?>
<tr>
<td valign="top" align="right"><font class="tablefieldtext">Разделы:</font></td>
<td valign="top" align="left">
<?$l = CIBlockSection::GetTreeList(Array("IBLOCK_ID"=>$IBLOCK_ID));?>
<select name="IBLOCK_SECTION[]" size="14" multiple class="typeselect">
<option value="0"<?if(is_array($str_IBLOCK_ELEMENT_SECTION) && in_array(0, $str_IBLOCK_ELEMENT_SECTION))echo " selected"?>>Не привязан к разделу</option>
<?
while($l->ExtractFields("l_")):
?><option value="<?echo $l_ID?>"
<?if (is_array($str_IBLOCK_ELEMENT_SECTION) &&
in_array($l_ID, $str_IBLOCK_ELEMENT_SECTION))
echo " selected"?>>
<?echo str_repeat(" . ", $l_DEPTH_LEVEL)?><?echo $l_NAME?></option><?
endwhile;
?>
</select>
</td>
</tr>
<?endif?>
<tr>
<td valign="top" align="center" colspan="2" class="tablehead"><font class="tableheadtext"><b>Активность и документооборот</b></font></td>
</tr>
<?if ($WF=="Y" || $view=="Y"):?>
<tr>
<td valign="top" align="right"><font class="tablefieldtext">Статус:</font></td>
<td valign="top" nowrap><font class="tablebodytext">
<?echo SelectBox("WF_STATUS_ID", CWorkflowStatus::GetDropDownList("N", "desc"), "", $str_WF_STATUS_ID);?></font></td>
</tr>
<?endif;?>
<?
if($ID>0):
$p = CIblockElement::GetByID($ID);
$pr = $p->ExtractFields("prn_");

if(CModule::IncludeModule("workflow")):
if(strlen($pr["DATE_CREATE"])>0):
?>
<tr>
<td valign="top" align="right"><font class="tablefieldtext">Создана:</font></td>
<td valign="top"><font class="tablebodytext"><?echo $pr["DATE_CREATE"]?><?
if (intval($pr["CREATED_BY"])>0):
?>&nbsp;&nbsp;&nbsp;[<a class="tablebodylink" href="user_edit.php?lang=<?=lang?>&id=<?=$pr["created_by"]?>"><?echo $pr["CREATED_BY"]?></a>]&nbsp;<?=htmlspecialcharsex($pr["CREATED_USER_NAME"])?><?
endif;
?></font></td>
</tr>
<?endif;?>
<tr>
<td valign="top" align="right"><font class="tablefieldtext">Изменена:</font></td>
<td valign="top"><font class="tablebodytext"><?echo $str_TIMESTAMP_X?><?
if (intval($str_MODIFIED_BY)>0):
?>&nbsp;&nbsp;&nbsp;[<a class="tablebodylink" href="user_edit.php?lang=<?=lang?>&id=<?=$str_modified_by?>"><?echo $str_MODIFIED_BY?></a>]&nbsp;<?=$str_USER_NAME?><?
endif;
?></font></td>
</tr>
<?endif?>
<?if($WF=="Y" && strlen($prn_WF_DATE_LOCK)>0):?>
<tr>
<td valign="top" align="right" nowrap><font class="tablefieldtext">Заблокирована:</font></td>
<td valign="top" nowrap><font class="tablebodytext"><?echo $prn_WF_DATE_LOCK?><?
if (intval($prn_WF_LOCKED_BY)>0):
?>&nbsp;&nbsp;&nbsp;[<a class="tablebodylink" href="user_edit.php?lang=<?=lang?>&id=<?=$prn_wf_locked_by?>"><?echo $prn_WF_LOCKED_BY?></a>]&nbsp;<?=$prn_LOCKED_USER_NAME?><?
endif;
?></font></td>
</tr>
<?endif;?>
<?endif;?>
<?if (CModule::IncludeModule("workflow")):?>
<tr>
<td valign="top" align="center" colspan="2">
<textarea name="WF_COMMENTS" class="typearea" cols="110" rows="10"><?echo $str_WF_COMMENTS?></textarea></td>
</tr>
<?endif?>
</table>
<br>
<input <?if ($view=="Y" || $prn_LOCK_STATUS=="red") echo "disabled";?> type="submit" class="button" name="save" value="<?echo (($ID > 0)?"Изменить":"Добавить")?>">
&nbsp;
<input <?if ($view=="Y" || $prn_LOCK_STATUS=="red") echo "disabled";?> class="button" type="submit" name="apply" value="Применить">
&nbsp;
<input <?if ($view=="Y" || $prn_LOCK_STATUS=="red") echo "disabled";?> type="submit" class="button" name="dontsave" value="Выйти без сохранения">
</form>

Внешний вид готов, теперь приступим к странице-обработчику перед сохранением. Чтобы как-то повлиять на сохраняемые поля необходимо модифицировать одноименные поля в массивах $_POST и $_FILES, значения всех свойств необходимо модифицировать в массиве $PROP.

Для проверки что текст статьи введен используем следующее условие:

if (strlen($_POST['DETAIL_TEXT'])<=0)
$error = new _CIBlockError(2, 'DESCRIPTION_REQUIRED', 'Введите текст статьи');

Конструктор объекта _CIBlockError принимает три параметра: степень серьезности ошибки, произвольный идентификатор и текст ошибки. Если на странице редактирования определить переменную $error со значением этого объекта, то сохранения внесённых изменений не произойдет. Для того чтобы значения, пришедшие из формы, не потерялись, после инициализации переменной $error также инициализируйте переменную $bVarsFromForm=true. Переменная $bVarsFromForm как раз указывает, что значения в полях необходимо показывать те, которые пришли из формы.

Для автоматической установки даты новости в момент публикации переопределим поле $_POST["ACTIVE_FROM"]:

if ($_POST["WF_STATUS_ID"]==1 && strlen($_POST["ACTIVE_FROM"])<=0)
{
$_POST["ACTIVE_FROM"] = date("d.m.Y H:i:s");
}

В данном случае мы фиксированно считаем что формат даты для языка в котором мы работаем DD.MM.YYYY HH:MI:SS, если у вас формат другой, то необходимо обработать его.

Для автоматического создания маленькой картинки на основе большой воспользуемся функцией BXIBlockAfterSave. Если ее определить до сохранения элемента, то она автоматически будет вызвана после успешного сохранения элемента. Определим ее в начале файла /bitrix/php_interface/include/iblock_element_edit_before_save.php:

<?
function BXIBlockAfterSave($arFields)
{
if($_POST['MAKE_PREVIEW_PICTURE']=='Y')
{
$dbr = CIBlockElement::GetByID($arFields['ID']);
if(($ar = $dbr->Fetch()) && $ar['DETAIL_PICTURE']>0)
{
$img_path = $_SERVER['DOCUMENT_ROOT'].CFile::GetPath($ar['DETAIL_PICTURE']);
$width = 200;
$height = 200;
list($width_orig, $height_orig) = getimagesize($img_path);
if($width && ($width_orig < $height_orig))
$width = ($height / $height_orig) * $width_orig;
else
$height = ($width / $width_orig) * $height_orig;
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($img_path);
imagecopyresized($image_p, $image, 0, 0, 0, 0,
$width, $height, $width_orig, $height_orig);
$new_img_path = tempnam("/tmp", "FOO").".jpg";
imagejpeg($image_p, $new_img_path);
$be = new CIBlockElement();
$be->Update($arFields['ID'],
Array('PREVIEW_PICTURE' => CFile::MakeFileArray($new_img_path)),
false);
@unlink($new_img_path);
}
}
}
?>

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

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

function BXIBlockAfterSave($arFields)
{
if($arFields['WF_STATUS_ID']==1)
{
BXClearCache(true, "/ru/main_page/");
BXClearCache(true, "/ru/detail/".$arFields['ID']."/");
}
}

Вот и все. Теперь у нас есть форма полностью настроенная для наших нужд. Иногда бывает необходимо выполнить изменения совсем другого характера, например, форма ввода и изменения одновременно несколько картинок, в этом случае необходимо просто создать свою новую страницу и добавить ее в административное меню. В заключении приведем полный код страницы /bitrix/php_interface/include/iblock_element_edit_before_save.php:

<?
if($REQUEST_METHOD=="POST" && strlen($Update)>0 && $view!="Y" && (!$error) && empty($dontsave) && strlen($_POST['DETAIL_TEXT'])<=0)
$error = new _CIBlockError(2, "DESCRIPTION_REQUIRED", "Введите текст статьи");
elseif($_POST["WF_STATUS_ID"] == 1 && strlen($_POST["ACTIVE_FROM"]) <= 0)
$_POST["ACTIVE_FROM"] = date("d.m.Y H:i:s");

function BXIBlockAfterSave($arFields)
{
if($_POST['MAKE_PREVIEW_PICTURE']=='Y')
{
$dbr = CIBlockElement::GetByID($arFields['ID']);
if(($ar = $dbr->Fetch()) && $ar['DETAIL_PICTURE']>0)
{
$img_path = $_SERVER['DOCUMENT_ROOT'].CFile::GetPath($ar['DETAIL_PICTURE']);
$width = 200;
$height = 200;
list($width_orig, $height_orig) = getimagesize($img_path);
if($width && ($width_orig < $height_orig))
$width = ($height / $height_orig) * $width_orig;
else
$height = ($width / $width_orig) * $height_orig;
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($img_path);
imagecopyresized($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
$new_img_path = tempnam("/tmp", "FOO").".jpg";
imagejpeg($image_p, $new_img_path);
$be = new CIBlockElement();
$be->Update($arFields['ID'], Array('PREVIEW_PICTURE'=>CFile::MakeFileArray($new_img_path)), false);
@unlink($new_img_path);
die($new_img_path);
}
}

if($arFields['WF_STATUS_ID']==1)
{
BXClearCache(true, "/ru/main_page/");
BXClearCache(true, "/ru/detail/".$arFields['ID']."/");
}
}
?>

Пользовательские комментарии

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

Добавлять комментарии могут только зарегистрированные пользователи. Сообщения для просмотра появляются после модерации.
2
Александр Баланцев
Цитата
Для начала возьмем оригинальный код страницы /bitrix/modules/iblock/admin/iblock_element_edit.php, а именно, ту ее часть, которая настраивается:

Не совсем верно, код приведенный в примере, отличается от оригинала. В файле /bitrix/modules/iblock/admin/iblock_element_edit.php надо скопировать код от строки:

Код
//START of the custom form
до строки:

Код
//END of the custom form

и вставьте его в свою форму.
Только тогда сохраниться верстка  формы в противном случае, как в примере она развалиться.
© «Битрикс», 2001-2012, «1C-Битрикс», 2012