K4:Работа классом EditPickerHelper
From In-Portal Developers Guide
Revision as of 13:40, 25 December 2008
| ||
---|---|---|
Статьи в этой категории | ||
|
inp_edit_picker
" на форме редактирования.
Блок "inp_edit_picker
" представляет из себя два поля в одном из которых находятся выбранные элементы, а во втором все доступные элементы за исключением уже выбранных. Данный блок позволяет выбрать несколько элементов одновременно и перенести их во второй список.
Класс EditPickerHelper автоматизирует обработку данных, полученных из блока "inp_edit_picker
".
Contents |
Использование на шаблоне
Блок "inp_edit_picker
" является стандартным начиная с Core v 4.2.2. Использовать его в шаблоне можно следующим образом:
<inp2:m_RenderElement
name="inp_edit_picker" prefix="sample-prefix" field="OptionField" title="la_fld_OptionField"
optprefix="option-prefix" option_key_field="OptionId" option_value_field="OptionTitle"
size="10" style="CSS definitions"
/>
Ниже приведено описание параметров блока "inp_edit_picker
". Параметры "name
", "prefix
", "field
", "title
" и "style
" являются стандартными для всех блоков, используемых на формах редактирования, поэтому в данной статье они описаны не будут.
параметр | описание параметра |
---|---|
optprefix (string) | Префикс, данные которого будут использованы для заполнения списка доступных и выбранных опций. |
option_key_field (string) | Поле, объявленное в unit config префикса опций, которое содержит идентификатор (ID ) опции.
|
option_value_field (string) | Поле, объявленное в unit config префикса опций, которое содержит название опции. |
size (int) | Количество показываемых опций без боковой полосы прокрутки. По умолчанию данный параметр равен 15. |
Базовая настройка
Независимо от используемого типа хранения данных, полученных из блока "inp_edit_picker
" необходимо выполнить следующие два действия.
Прописать в конфигурационном файле префикса описание поля, которое будет использоваться для хранения данных, полученных из блока "inp_edit_picker
":
$config = Array( 'Prefix' => 'sample-prefix', 'Fields' => Array ( 'OptionField' => Array ( 'type' => 'string', 'formatter' => 'kOptionsFormatter', 'options_sql' => 'SELECT %1$s FROM ' . TABLE_PREFIX . 'OptionTable', 'option_key_field' => 'OptionId', 'option_title_field' => 'OptionTitle', 'required' => 1, 'not_null' => 1, 'default' => 0 ), ), 'Grids' => Array ( 'Default' => Array ( 'Icons' => Array ('default' => 'icon16_custom.gif'), 'Fields' => Array( 'OptionField' => Array ( 'title' => 'la_col_OptionField', 'data_block' => 'grid_picker_td', 'filter_block' => 'grid_picker_filter', 'header_block' => 'grid_column_title_no_sorting' ), ), ), ), );
Учитывая форму хранения значений в поле OptionField
ему не представляется возможным сделать осмысленную сортировку. В следствие чего используется блок "grid_column_title_no_sorting
", который убирает возможность сортировки по полю.
В случае, когда данные будут храниться в отдельной таблице поле должно быть виртуальным. |
Прописать в шаблоне редактирования тег, использующий данное поле. К данному моменту результатом использования блока "inp_edit_picker
" будут заполненные списки доступных и выбранных опций, правда в обоих из них будет полных список опций. Для того, чтобы выбранные опции показывались правильно, нужно в обработчике событий используемого префикса опций (в данной статье это "option-prefix
") переписать метод SetCustomQuery. Сутью переписывания метода является добавления фильтра по выбранным и доступным опциям:
/** * Applies edit picker filters * * @param kEvent $event */ function SetCustomQuery(&$event) { $edit_picker_helper =& $this->Application->recallObject('EditPickerHelper'); /* @var $edit_picker_helper EditPickerHelper */ $edit_picker_helper->applyFilter($event, 'OptionId'); }
После выполнения выше указанных действий всё должно корректно заработать. Правда для хранения данных в связанной таблице (каждое выбранное значение будет отдельной записью) требуется дополнительная настройка, описанная ниже.
Хранение данных в связанной таблице
У связанной таблицы должен быть свой конфигурационный файл и обработчик событий, так как она должна быть подчинённым префиксом относительно главного. В данной статье главный префикс это "sample-prefix
".
Создать конфигурационный файл подчинённого префикса, в котором кроме связки его с главным префиксом прописать hook, который будет сохранять выбранные данные.
$config = Array ( 'Prefix' => 'sample-prefix-child', 'Hooks' => Array ( Array ( 'Mode' => hAFTER, 'Conditional' => false, 'HookToPrefix' => '#PARENT#', 'HookToSpecial' => '*', 'HookToEvent' => Array('OnAfterItemCreate', 'OnAfterItemUpdate'), 'DoPrefix' => '', 'DoSpecial' => '*', 'DoEvent' => 'OnSaveChildren', ), ), 'ForeignKey' => 'ParentId', 'ParentTableKey' => 'ParentId', 'ParentPrefix' => 'parent', 'AutoDelete' => true, 'AutoClone' => true, 'Fields' => Array ( 'ChildId' => Array ('type' => 'int', 'not_null' => 1, 'default' => 0), 'ParentId' => Array ('type' => 'int', 'not_null' => 1, 'required' => 1, 'default' => 0), 'OptionId' => Array ('type' => 'int', 'not_null' => 1, 'required' => 1, 'default' => 0), ), );
В обработчике событий подчинённого префикса прописать тело hook:
/** * [HOOK] Saves changes from edit picker * * @param kEvent $event */ function OnSaveChildren(&$event) { $edit_picker_helper =& $this->Application->recallObject('EditPickerHelper'); /* @var $edit_picker_helper EditPickerHelper */ $edit_picker_helper->SaveValues($event, 'OptionField', 'OptionId'); }
В конфигурационном файле главного префикса нужно прописать его связку с подчинённым префиксом:
$config = Array ( 'SubItems' => Array('sample-prefix-child'), );
Добавить в обработчик событий главного префикса загрузку значений в блок "inp_edit_picker
" из подчинённой таблицы:
/** * Loads edit picker data * * @param kEvent $event */ function OnAfterItemLoad(&$event) { parent::OnAfterItemLoad($event); $edit_picker_helper =& $this->Application->recallObject('EditPickerHelper'); /* @var $edit_picker_helper EditPickerHelper */ $edit_picker_helper->LoadValues($event, 'OptionId', 'sample-prefix-child.OptionId'); }
В обработчике тегов (TagProcessor
) переписать метод PrepareListElementParams, который будет использоваться для вывода данных (из тэга PrintList) из связанной таблицы в списке главного префикса:
function PrepareListElementParams(&$object, &$block_params) { $edit_picker_helper =& $this->Application->recallObject('EditPickerHelper'); /* @var $edit_picker_helper EditPickerHelper */ $event = new kEvent($object->getPrefixSpecial() . ':OnAfterItemLoad'); $edit_picker_helper->LoadValues($event, 'OptionField', 'sample-prefix-child.OptionId'); }
После этого, для каждой записи в списке, выбранные в поле OptionField
опции будут выводиться через запятую.
Фильтрация в списке
На данный момент нету стандартного фильтра, который будет корректно осуществлять фильтрацию данных по связанной таблице. Из-за этого надо будет переписать класс "kSearchHelper
", который зарегистрирован в фабрике классов под pseudo "SearchHelper
".
Для начала нужно создать класс наследник:
class ESearchHelper extends kSearchHelper { function getCustomFilterSearchClause(&$object, $field_name, $filter_type, $field_options) { if ($field_name == 'OptionField' && $filter_type == 'options') { extract( $this->getFieldInformation($object, $field_name) ); $field_value = strlen($field_options['submit_value']) ? $this->Conn->qstr($field_options['submit_value']) : false; if ($field_value) { $sub_sql = 'SELECT children.ParentId FROM ' . $this->Application->getUnitOption('sample-prefix-child', 'TableName') . ' children WHERE children.OptionId = ' . $field_value; $filter_value = $object->TableName . '.' . $object->IDField . ' IN (' . $sub_sql . ')'; } $field_options['sql_filter_type'] = $sql_filter_type; $field_options['value'] = $filter_value; return $field_options; } return parent::getCustomFilterSearchClause($object, $field_name, $filter_type, $field_options); } }
Файл будет называться "e_search_helper.php
" (согласно правилу назначения имён) и находиться в директории "custom/units/sections
".
Потом нужно зарегистрировать новый класс в фабрике классов:
$config = Array ( 'RegisterClasses' => Array ( Array ('pseudo' => 'SearchHelper', 'class' => 'ESearchHelper', 'file' => 'e_search_helper.php'), ), );