Autocomplete для полей обычно применяют в тех случаях, когда нужно выбрать значение из списка с >= 1500 элементов.
Все контролы, необходимые для работы autocomplete уже есть в Eaze, осталось только их грамотно подключить и настроить. Список затрагиваемых файлов:
Рассмотрим пример с поиском по названию объекта в КЛАДРе. Основная задача autocomplete - поместить на форму идентификатор. Есть KladdFactory, поиск в ней по title. Внутри на формах это поле parentKladdrId.
Для начала создадим соответствующую запись в группе controls
<pageGroup name="controls" boot=""> <page uri="controls://kladdr/list/autocomplete/"> <actions>Base.Kladdr.GetKladdrListAutocomplete</actions> </page> </pageGroup>
Тут вроде бы все понятно - /int/controls/kladdr/list/autocomplete/
ссылается на экшн Base.Kladdr.GetKladdrListAutocomplete
(который мы опишем далее).
Добавим GetKladdrListAutocomplete в группу autocomplete.
<group name="autocomplete"> <action name="GetKladdrListAutocomplete"> <path>../../Kladdr.Common/actions/controls/GetObjectsAutocomplete</path> <parameters> <request> <param name="goa_Object">'Kladdr'</param> <param name="goa_Search">array()</param> <param name="goa_Options">array( BaseFactory::CustomSql => KladdrUtility::GetTitleCustomSql( Request::getString( "q" ) ) )</param> <param name="goa_ResultFormat">array('label' => 'GetName', 'title' => 'GetName', 'id' => 'kladdrId')</param> </request> </parameters> </action> </group>
Где GetObjectsAutocomplete - стандатный экшн, который должен быть у вас в пакете <Project>.Common. Он работает с Factory, которые мы получаем от MFD.
Параметр | Пример | Описание |
---|---|---|
goa_Object | 'Kladdr' | Название класса, по которому мы хотим искать1) |
goa_Search | array( "statusId" => 1 ) | Поисковый массив, который мы будем передавать в <Class>Factory::Get() |
goa_Options | array( BaseFactory::CustomSql => KladdrUtility::GetTitleCustomSql( Request::getString( "q" ) ) ) | Массив с опциями, который передается в <Class>Factory::Get(). Основное тут Request::getString( 'q' ) - поисковый запрос, который приходит с формы |
goa_ResultFormat | array('label' => 'GetName', 'title' => 'GetName', 'id' => 'kladdrId') | Элемент массива, который будет преобразован в JSON отправлен в Response |
Здесь GetName() - это метод у класса Kladdr, c помощью которого выводится полный путь до деревни или города, обычно хватает поля title.
В GetKladdrListAction нам нужно получить объект из поисковой формы и отправить его в Response для того, чтобы там его отобразить. Помним, что ищем мы по parentKladdrId
protected function beforeAction() { // get autocomplete objects if( !empty( $this->search['parentKladdrId'] ) ) { $searchParentKladdr = KladdrFactory::GetById( $this->search['parentKladdrId'] ); Response::setParameter( 'searchParentKladdr', $searchParentKladdr ); } }
В шаблон списка нужно добавить html-код в форму поиска и javascript для инициализации контрола.
Поисковая форма
<div class='row'> <label>{lang:vt.kladdr.parentKladdrId}</label> <?= FormHelper::FormInput( '', !empty( $searchParentKladdr ) ? $searchParentKladdr->GetName() : '', 'parentKladdr-autocomplete', 'autocomplete', array( 'size' => 40 ) ); ?> <?= FormHelper::FormHidden( 'search[parentKladdrId]', $search['parentKladdrId'], 'parentKladdr-value' ); ?> </div>
Где-то внизу
<script type='text/javascript'> initAutocomplete( '#parentKladdr-autocomplete', '#parentKladdr-value', controlsRoot + 'kladdr/list/autocomplete/' ); </script>
Идея такая же, как и в GetAction, только у нас есть объект на форме.
protected function beforeSave() { // Set Parent Kladdr Object for AutoComplete if( !empty( $this->currentObject->parentKladdrId ) ) { $this->currentObject->parentKladdr = KladdrFactory::GetById( $this->currentObject->parentKladdrId, array() , array( BaseFactory::WithoutDisabled => true ) ); } }
На самом деле этот код можно не писать, но тут он нужен для того, чтобы получить зависимые объекты для функции GetName(). Если используете обычные поля, то эту часть можно упустить.
Шаблон для добавления и редактирования данных
Поля объекта
<div data-row="parentKladdrId" class="row"> <label>{lang:vt.kladdr.parentKladdrId}</label> <?= FormHelper::FormInput( '', !empty( $object->parentKladdr ) ? $object->parentKladdr->GetName() : '', 'parentKladdr-autocomplete', 'autocomplete', array( 'size' => 40 ) ); ?> <?= FormHelper::FormHidden( $prefix . '[parentKladdrId]', $object->parentKladdrId, 'parentKladdr-value' ); ?> </div>
Где-то внизу
<script type="text/javascript"> initAutocomplete( '#parentKladdr-autocomplete', '#parentKladdr-value', controlsRoot + 'kladdr/list/autocomplete/' ); </script>