Инструменты пользователя

Инструменты сайта


eaze:autocomplete_в_vt

Настройка autocomplete

Autocomplete для полей обычно применяют в тех случаях, когда нужно выбрать значение из списка с >= 1500 элементов.

Все контролы, необходимые для работы autocomplete уже есть в Eaze, осталось только их грамотно подключить и настроить. Список затрагиваемых файлов:

  • pages.xml
  • actions.xml
  • Get*Action
  • index.tmpl.php
  • Save*Action
  • data.tmpl.php

Рассмотрим пример с поиском по названию объекта в КЛАДРе. Основная задача autocomplete - поместить на форму идентификатор. Есть KladdFactory, поиск в ней по title. Внутри на формах это поле parentKladdrId.

pages.xml

Для начала создадим соответствующую запись в группе 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 (который мы опишем далее).

actions.xml

Добавим 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.

GetAction

В GetKladdrListAction нам нужно получить объект из поисковой формы и отправить его в Response для того, чтобы там его отобразить. Помним, что ищем мы по parentKladdrId

protected function beforeAction() {
    // get autocomplete objects
    if( !empty( $this->search['parentKladdrId'] ) ) {
        $searchParentKladdr = KladdrFactory::GetById( $this->search['parentKladdrId'] );
        Response::setParameter( 'searchParentKladdr', $searchParentKladdr );
    }
}

index.tmpl.php

В шаблон списка нужно добавить 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>

SaveAction

Идея такая же, как и в 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(). Если используете обычные поля, то эту часть можно упустить.

data.tmpl.php

Шаблон для добавления и редактирования данных

Поля объекта

<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>
1) по сути, он должен называться Class, но так исторически сложилось, надо поправить
eaze/autocomplete_в_vt.txt · Последние изменения: 2011/09/13 17:51 — zenden