Grids
- Developer tools (not user components).
- Can work with abstract data (not bound except to infoblocks) .
- You create a component which selects, sorts or filters data;
- Data selected in the component template is given to be displayed in the component grid or the component form.
- If necessary, the instrument panel can be displayed in the component toolbar.
main.interface.toolbar - a simple component for displaying a button
main.interface.grid - a composite component for displaying a list
sorting elements in a list; the action menu for each element; bulk editing in the list; group actions on records; page navigation; search filter by list elements; list column settings; drag-and-drop list columns; list display settings; color scheme; saving filters; work in AJAX mode.
main.interface.form – component for displaying forms for editing
Example of use
I want to pause and go through a concrete example, to give a full picture of grids from a developer’s point of view. Let’s say that the data source for a grid is a list of system users. We create a list of users in the front-end with the capability of editing user data. Since this is the front-end, it’s logical to make our components for entering and editing users. The body of the list component will hold data, and the template of the component will display them using the grid. The situation is analogous for the editing form component.
I’ll put comments in the code.
1. List component
component.php:
Code
template.php:
<?
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true)
die();
//processing of POST
//gets an array of usergroups. will be used to filter users
$aGroups = array();
$gr_res = CGroup::GetDropDownList("AND ID!=2");
while($aGr = $gr_res->Fetch())
$aGroups[$aGr["REFERENCE_ID"]] = $aGr["REFERENCE"];
//unique identifier for the grid
$arResult["GRID_ID"] = "user_grid";
//specifies a filter for users
$arResult["FILTER"] = array(
array("id"=>"FIND", "name"=>"Find", "type"=>"quick", "items"=>array("login"=>"Login", "email"=>"Email", "name"=>"Name")),
array("id"=>"PERSONAL_BIRTHDAY", "name"=>"Birthday", "type"=>"date"),
array("id"=>"PERSONAL_PROFESSION", "name"=>"Job title"),
array("id"=>"PERSONAL_WWW", "name"=>"Web page"),
array("id"=>"PERSONAL_ICQ", "name"=>"ICQ", "params"=>array("size"=>15)),
array("id"=>"PERSONAL_GENDER", "name"=>"Gender", "type"=>"list", "items"=>array(""=>"(gender)", "M"=>"male", "F"=>"female")),
array("id"=>"GROUPS_ID", "name"=>"Groups", "type"=>"list", "items"=>$aGroups, "params"=>array("size"=>5, "multiple"=>"multiple"), "valign"=>"top"),
array("id"=>"PERSONAL_PHONE", "name"=>"Phone"),
array("id"=>"PERSONAL_CITY", "name"=>"City"),
);
//initialize a new object with the user preferences for our grid
$grid_options = new CGridOptions($arResult["GRID_ID"]);
//sorting order defined by the user
$aSort = $grid_options->GetSorting(array("sort"=>array("id"=>"desc"), "vars"=>array("by"=>"by", "order"=>"order")));
//desired number of users per page
$aNav = $grid_options->GetNavParams(array("nPageSize"=>10));
//passes the above filter to the grid
$aFilter = $grid_options->GetFilter($arResult["FILTER"]);
//if a filtering field does not match with API
if(isset($aFilter["PERSONAL_BIRTHDAY_from"]))
$aFilter["PERSONAL_BIRTHDAY_1"] = $aFilter["PERSONAL_BIRTHDAY_from"];
if(isset($aFilter["PERSONAL_BIRTHDAY_to"]))
$aFilter["PERSONAL_BIRTHDAY_2"] = $aFilter["PERSONAL_BIRTHDAY_to"];
if(isset($aFilter["FIND"]))
$aFilter[strtoupper($aFilter["FIND_list"])] = $aFilter["FIND"];
//returns a list of users according filter and order set by the current user
$aSortArg = each($aSort["sort"]);
$db_res = CUser::GetList($aSortArg["key"], $aSortArg["value"], $aFilter);
//splits the result of the selection into pages
$db_res->NavStart($aNav["nPageSize"]);
//loop for filling in each line of data in the grid
$aRows = array();
while($aRes = $db_res->GetNext())
{
//fields that require special view
$aCols = array(
"PERSONAL_GENDER" => ($aRes["PERSONAL_GENDER"] == "M"? "Male":($aRes["PERSONAL_GENDER"] == "F"? "Female":"")),
"EMAIL" => '<a href="mailto:'.$aRes["EMAIL"].'">'.$aRes["EMAIL"].'</a>',
"ID" => '<a href="'.$APPLICATION->GetCurPage().'?ID='.$aRes["ID"].'">'.$aRes["ID"].'</a>',
"LOGIN" => '<a href="edit-user.php?ID='.$aRes["ID"].'">'.$aRes["LOGIN"].'</a>',
);
//action menu for record
$aActions = Array(
array("ICONCLASS"=>"edit", "TEXT"=>"Edit", "ONCLICK"=>"jsUtils.Redirect(arguments, 'edit-user.php?ID=".$aRes["ID"]."')", "DEFAULT"=>true),
array("ICONCLASS"=>"copy", "TEXT"=>"Copy", "ONCLICK"=>"jsUtils.Redirect(arguments, '/bitrix/admin/user_edit.php?COPY_ID=".$aRes["ID"]."')"),
array("SEPARATOR"=>true),
array("ICONCLASS"=>"delete", "TEXT"=>"Delete", "ONCLICK"=>"if(confirm('Are you sure you want to delete this user?')) window.location='/bitrix/admin/user_admin.php?action=delete&ID=".$aRes["ID"]."&".bitrix_sessid_get()."';"),
);
//stores data. "data" - all selected records, "editable" - if a record is editable or not
$aRows[] = array("data"=>$aRes, "actions"=>$aActions, "columns"=>$aCols, "editable"=>($aRes["ID"]==11? false:true));
}
//builds $arResult
$arResult["ROWS"] = $aRows;
//info for the list footer
$arResult["ROWS_COUNT"] = $db_res->SelectedRowsCount();
//sorting
$arResult["SORT"] = $aSort["sort"];
$arResult["SORT_VARS"] = $aSort["vars"];
//page navigation
$db_res->bShowAll = false;
$arResult["NAV_OBJECT"] = $db_res;
//component template inclusion
$this->IncludeComponentTemplate();
?>
|
Code
<?
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true)
die();
?>
<?
//shows a toolbar
$APPLICATION->IncludeComponent(
"bitrix:main.interface.toolbar",
"",
array(
"BUTTONS"=>array(
array(
"TEXT"=>"List",
"TITLE"=>"Usel list",
"LINK"=>$APPLICATION->GetCurPage(),
"ICON"=>"btn-list",
),
array("SEPARATOR"=>true),
array(
"TEXT"=>"Copy admin",
"TITLE"=>"Create a copy of a user with ID=1",
"LINK"=>"/bitrix/admin/user_edit.php?COPY_ID=1",
"ICON"=>"btn-copy",
),
array(
"TEXT"=>"Copy current user",
"TITLE"=>"Create a copy of current user",
"LINK"=>"/bitrix/admin/user_edit.php?COPY_ID=".$GLOBALS["USER"]->GetID(),
"ICON"=>"btn-copy",
),
array("NEWBAR"=>true),
array(
"TEXT"=>"Add",
"TITLE"=>"Add a new user or a usergroup",
"MENU"=>array(
array("ICONCLASS"=>"add", "TEXT"=>"User", "ONCLICK"=>"jsUtils.Redirect(arguments, '/bitrix/admin/user_edit.php')"),
array("ICONCLASS"=>"add", "TEXT"=>"Usergroup", "ONCLICK"=>"jsUtils.Redirect(arguments, '/bitrix/admin/group_edit.php')"),
),
"ICON"=>"btn-new",
),
),
),
$component
);?>
<?
//include a grid component
$APPLICATION->IncludeComponent(
"bitrix:main.interface.grid",
"",
array(
//unique identifier of the grid
"GRID_ID"=>$arResult["GRID_ID"],
//description of grid columns
"HEADERS"=>array(
array("id"=>"LOGIN", "name"=>"Login", "sort"=>"login", "default"=>true, "editable"=>false),
array("id"=>"ACTIVE", "name"=>"Active", "default"=>true, "type"=>"checkbox", "editable"=>true),
array("id"=>"TIMESTAMP_X", "name"=>"Modified", "sort"=>"timestamp_x", "default"=>false),
array("id"=>"NAME", "name"=>"First name", "sort"=>"name", "default"=>true, "editable"=>array("size"=>20, "maxlength"=>255)),
array("id"=>"LAST_NAME", "name"=>"Last name", "sort"=>"last_name", "default"=>true, "editable"=>array("size"=>20, "maxlength"=>255)),
array("id"=>"EMAIL", "name"=>"Email", "sort"=>"email", "default"=>true, "editable"=>array("size"=>20, "maxlength"=>255)),
array("id"=>"LAST_LOGIN", "name"=>"Last authorized", "sort"=>"last_login"),
array("id"=>"DATE_REGISTER", "name"=>"Registration date", "sort"=>"date_register"),
array("id"=>"ID", "name"=>"ID", "sort"=>"id", "default"=>true, "align"=>"right"),
array("id"=>"PERSONAL_BIRTHDAY", "name"=>"Birthday", "sort"=>"personal_birthday", "default"=>true, "type"=>"date", "editable"=>true),
array("id"=>"PERSONAL_PROFESSION", "name"=>"Job title", "sort"=>"personal_profession"),
array("id"=>"PERSONAL_WWW", "name"=>"Web page", "sort"=>"personal_www"),
array("id"=>"PERSONAL_ICQ", "name"=>"ICQ", "sort"=>"personal_icq"),
array("id"=>"PERSONAL_GENDER", "name"=>"Gender", "sort"=>"personal_gender", "default"=>true, "type"=>"list", "editable"=>array("items"=>array(""=>"(gender)", "M"=>"Male", "F"=>"Female"))),
array("id"=>"PERSONAL_PHONE", "name"=>"Phone", "sort"=>"personal_phone"),
array("id"=>"PERSONAL_CITY", "name"=>"City", "sort"=>"personal_city"),
array("id"=>"PERSONAL_STREET", "name"=>"Street", "sort"=>"personal_street"),
array("id"=>"WORK_COMPANY", "name"=>"Company name", "sort"=>"work_company"),
array("id"=>"WORK_DEPARTMENT", "name"=>"Department", "sort"=>"work_department"),
array("id"=>"WORK_POSITION", "name"=>"Position", "sort"=>"work_position"),
array("id"=>"EXTERNAL_AUTH_ID", "name"=>"External code"),
),
//sorting
"SORT"=>$arResult["SORT"],
"SORT_VARS"=>$arResult["SORT_VARS"],
//data
"ROWS"=>$arResult["ROWS"],
//list footer; it is possible to add multiple sections
"FOOTER"=>array(array("title"=>"All", "value"=>$arResult["ROWS_COUNT"])),
//applies action to all records in grid
"ACTIONS"=>array(
//record deletion possible
"delete"=>true,
//drop-down list of actions
"list"=>array("activate"=>"Activate", "deactivate"=>"Deactivate"),
//custom html
"custom_html"=>'
<select name="action_on_files" onchange="this.form.folder_id.style.display=(this.value==\'move\'? \'\':\'none\');">
<option>- actions -</option>
<option value="move">Move</option>
</select>
<select name="folder_id" style="display:none">
<option value="folder1">folder1</option>
<option value="folder2">folder2</option>
</select>
',
),
//allows actions for all records
"ACTION_ALL_ROWS"=>true,
//allows editing in list
"EDITABLE"=>true,
//page navigation object
"NAV_OBJECT"=>$arResult["NAV_OBJECT"],
//ajax mode
"AJAX_MODE"=>"Y",
"AJAX_OPTION_JUMP"=>"N",
"AJAX_OPTION_STYLE"=>"Y",
//filter
"FILTER"=>$arResult["FILTER"],
),
$component
);
?>
|
When editing inside the list or performing a group action, our component receives the usual $_POST from the form. Typical form processing code looks like this:
Code
//form submitted
if(
$_SERVER["REQUEST_METHOD"] == "POST"
&& check_bitrix_sessid()
&& isset($_POST["action_button_".$arResult["GRID_ID"]])
)
{
if($_POST["action_button_".$arResult["GRID_ID"]] == "delete" && isset($_POST["ID"]) && is_array($_POST["ID"]))
{
foreach($_POST["ID"] as $ID);
}
if($_POST["action_button_".$arResult["GRID_ID"]] == "edit" && isset($_POST["FIELDS"]) && is_array($_POST["FIELDS"]))
{
foreach($_POST["FIELDS"] as $ID => $arFields);
}
if(!isset($_POST["AJAX_CALL"]))
LocalRedirect($path);
}
|
2. Editing form component
component.php:
Code
<?
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true)
die();
//processing of POST
//gets user ID
$db_res = CUser::GetByID($_REQUEST["ID"]);
$aRes = $db_res->GetNext();
//unique identifier of the form
$arResult["FORM_ID"] = "user_form";
//builds $arResult
$arResult["DATA"] = $aRes;
//including component template
$this->IncludeComponentTemplate();
?>
|
template.php:
Code
<?
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true)
die();
?>
<?$APPLICATION->IncludeComponent(
"bitrix:main.interface.toolbar",
"",
array(
"BUTTONS"=>array(
array(
"TEXT"=>"List",
"TITLE"=>"Usel list",
"LINK"=>"index.php",
"ICON"=>"btn-list",
),
),
),
$component
);?>
<?$APPLICATION->IncludeComponent(
"bitrix:main.interface.form",
"",
array(
//editing form identifier
"FORM_ID"=>$arResult["FORM_ID"],
//descriptions of tabs and fields in editing form
"TABS"=>array(
array("id"=>"tab1", "name"=>"User", "title"=>"Regitration info", "icon"=>"", "fields"=>array(
array("id"=>"DATE_REGISTER", "name"=>"Registration date", "type"=>"label"),
array("id"=>"ACTIVE", "name"=>"Active", "type"=>"checkbox"),
array("id"=>"NAME", "name"=>"First name"),
array("id"=>"EMAIL", "name"=>"Email", "required"=>true),
array("id"=>"LAST_NAME", "name"=>"Last name"),
)),
array("id"=>"tab11", "name"=>"Groups", "title"=>"User group membership", "icon"=>"", "fields"=>array(
array("id"=>"GROUPS", "name"=>"Groups", "type"=>"custom", "value"=>'Groups1', "colspan"=>true),
array("id"=>"GROUPS1", "name"=>"Groups", "type"=>"custom", "value"=>'Groups2'),
)),
array("id"=>"tab2", "name"=>"Personal information", "title"=>" Personal information", "icon"=>"", "fields"=>array(
array("id"=>"PERSONAL_BIRTHDAY", "name"=>"Birthday", "type"=>"date"),
array("id"=>"PERSONAL_PHOTO", "name"=>"Photo", "type"=>"file", $params=>array("iMaxW"=>150, "iMaxH"=>150, "sParams"=>"border=0", "strImageUrl"=>"", "bPopup"=>true, "sPopupTitle"=>false)),
array("id"=>"PERSONAL_PROFESSION", "name"=>"Job title"),
array("id"=>"PERSONAL_WWW", "name"=>"Web page"),
array("id"=>"PERSONAL_ICQ", "name"=>"ICQ", "params"=>array("size"=>15)),
array("id"=>"section1", "name"=>"Section", "type"=>"section"),
array("id"=>"PERSONAL_GENDER", "name"=>"Gender", "type"=>"list", "items"=>array(""=>"(gender)", "M"=>"Male", "F"=>"Female")),
array("id"=>"PERSONAL_PHONE", "name"=>"Phone"),
array("id"=>"PERSONAL_CITY", "name"=>"City"),
array("id"=>"PERSONAL_STREET", "name"=>"Street", "type"=>"textarea", "params"=>array("rows"=>5)),
)),
array("id"=>"tab3", "name"=>"Work information", "title"=>"Work information", "icon"=>"", "fields"=>array(
array("id"=>"WORK_COMPANY", "name"=>"Company name"),
array("id"=>"WORK_DEPARTMENT", "name"=>"Department"),
array("id"=>"WORK_POSITION", "name"=>"Position"),
)),
),
//form buttons; addition of custom buttons via "custom_html" is possible
"BUTTONS"=>array("back_url"=>"index.php", "custom_html"=>"", "standard_buttons"=>true),
//data for editing
"DATA"=>$arResult["DATA"],
),
$component
);
?>
|
Our component, after saving, receives the usual POST. Typical processing looks something like this:
Code
//form submitted
if($_SERVER["REQUEST_METHOD"] == "POST" && check_bitrix_sessid())
{
//if Save or Apply button is clicked
if(isset($_POST["save"]) || isset($_POST["apply"]))
{
//gather fields for update
$arFields = array(
"SORT" => $_POST["SORT"],
"NAME" => $_POST["NAME"],
);
//code needed to save data (enter here)
}
}
|
The data in the example shows principles in working with grid components, forms, and toolbar. For further study, I recommend the source code of the components in the “Common lists” (lists) module.
Archive with components created incorporating above code.
Files:
components.zip
(6.06 Kb)








