Start now free!

How to use grids

How to use grids

Grids are a set of core components for creating a unified interface.

Grids
  • Developer tools (not user components).
  • Can work with abstract data (not bound except to infoblocks) .
General usage  
  • 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.
Components in detail

main.interface.toolbar  - a simple component for displaying a button

main.interface.toolbar.png

main.interface.grid  - a composite component for displaying a list

main.interface.grid.png

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

main.interface.form.png

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

result.png

component.php:

Code
<?
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();
 ?>
 
template.php:

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

editing_form.png

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)

yobe
07/07/2012 14:03:32
how can i use print option on this script.i want 2 print outs of the data filled on the form.
Anna Slyshkina
07/09/2012 12:11:41
Please contact our helpdesk to resolve the issue.
Partner Program
Free Online Training
Subscribe to Bitrix News