Bitrix Site Manager

Creating custom forms for the information block elements editing

The information block element creation and/or editing web form is undoubtedly one of the most frequently used ones. Furthermore, the Internet online stores and mass media find this kind of a web form the most popular in administration sections of their sites. Despite the fact that the form design and fields are automatically adjusted according to the information block settings and parameters, or that the Information Blocks module had been developed to cover the widest possible range of tasks, sometimes users find it desirable to customize a form according to their specific needs.

Consider an example of the editing form creation for a generic Interned media periodical.

A common article requires the following fields to exist in the form:

The process of the information block creation and customization is detailed in the help section. We shall only consider the lacking and redundant elements compared to the standard editing form:

We shall elaborate on the original code of /bitrix/modules/iblock/admin/iblock_element_edit.php, namely the customizable part of the code:

<form method="POST" action="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);?>
        </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);?>
        </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>

Save this script to a file, say /bitrix/php_interface/include/iblock_element_edit.php. Create the file /bitrix/php_interface/include/iblock_element_edit_before_save.php at the same location. The latter file will contain an element save handler script. Specify paths to these files in the Information Blocks module settings (for the required information block type) in fields Save operation handler and File with element editing form.

The spade-work is finished; now let us get down to the form design. Delete the unnecessary fields and re-layout the page /bitrix/php_interface/include/iblock_element_edit.php according to our requirements. The below is the resulting page code after the modification.

<form method="POST" action="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">Date (<?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>Title</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>Preamble</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, 300);?>
        </td>
    </tr>
    <?else:?>
    <tr>
        <td valign="top" align="right"><font class="tablefieldtext">Preamble 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"?>> Body / <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>Article</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);?>
        </td>
    </tr>
    <?else:?>
    <tr>
        <td valign="top" align="right"><font class="tablefieldtext">Body text 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"?>> Text / <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">Large 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>
    <tr>
        <td valign="top" align="right" class="tablebody" nowrap><font class="tablefieldtext">Picture in list:</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;">Create from large picture<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">Sections:</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"?>>Unbound</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>Validity and workflow</b></font></td>
    </tr>
    <?if ($WF=="Y" || $view=="Y"):?>
    <tr>
        <td valign="top" align="right"><font class="tablefieldtext">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">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">Modified:</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">Locked:</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)?"Edit":"Add")?>">
&nbsp;
<input <?if ($view=="Y" || $prn_LOCK_STATUS=="red") echo "disabled";?> class="button" type="submit" name="apply" value="Apply">
&nbsp;
<input <?if ($view=="Y" || $prn_LOCK_STATUS=="red") echo "disabled";?> type="submit" class="button" name="dontsave" value="Quit without saving">
</form>

The design is ready. Now we have to create the save operation handler. The arrays $_POST and $_FILES contain the saved fields and values that we may need to alter. The array $PROP contains the form properties.

Add the following condition to check for the article body text:

if (strlen($_POST['DETAIL_TEXT'])<=0)
    $error = new _CIBlockError(2, 
                               'DESCRIPTION_REQUIRED', 
                               'Please provide the article body.');

The _CIBlockError constructor takes 3 parameters: error severity, an identifier and the error description. If the editing form appears to have a variable named $error containing an instance of this class, no changes will be saved.

Redefine the field $_POST["ACTIVE_FROM"] to automatically set the article publication date:

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

Please note that this code does not respect the language preferences for the date format. If you need the format other than DD.MM.YYYY HH:MI:SS, handle it appropriately.

To automatically create the picture thumbnail that would be built on the large one, we need to create the handler function BXIBlockAfterSave. Being defined before an element is saved, it is automatically called upon the successful save operation. Define it in the beginning of the file /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);
        }
    }
}
?>

The above script creates a thumbnail from the large image and sets the appropriate thumbnail field if the flag MAKE_PREVIEW_PICTURE is set to "Y". The example is effective for JPEG images only.

The same function can be used to clear the cache of pages with the saved article:

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

That's all. We have got the form fully accustomed to our requirements. The changes of the completely different nature may be needed sometimes. For example, a form for uploading and editing a number of images may be required.  In this case, simply create a new page and add it to the administrative menu.

The following is the complete code of the page /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", "Please type the article body");
}
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, "/en/main_page/");
        BXClearCache(true, "/en/detail/".$arFields['ID']."/");
    }
}
?>