Базовая конфигурация

Рассмотрим создание и конфигурацию раскладки.

Схема раскладки контролов будет выглядеть следующим образом:

Рис. 1. Схема раскладки реестра.

Создание нового контрола и добавление контрола-раскладки.

  1. Создайте новый контрол, например с именем MyArea/MyRegistry. В этом контроле мы организуем реестр в рамках данного руководства разработчика.
  2. Откройте файл MyRegistry.wml и добавьте в качестве корневого тега контрол-раскладку Layout/browsers:Browser.

Списочный контрол

Подробнее о списочных контролах можно прочитать здесь.

Далее описан порядок добавления плоского списка в браузер реестра:

  1. Для Layout/browsers:Browser в опцию content добавьте списочный контрол, например плоский список.
<!-- MyRegistry.wml -->
<Layout.browsers:Browser>
   <ws:content>
      <Controls.list:View />
   </ws:content>
</Layout.browsers:Browser>
  1. Базовую конфигурацию списка перенесите в конфигурацию Layout/browsers:Browser.
<!-- MyRegistry.wml -->
<Layout.browsers:Browser source="{{_source}}" keyProperty="id" >
   <ws:content>
      <Controls.list:View />
   </ws:content>
</Layout.browsers:Browser>
// TypeScript
protected _source: null;
protected _beforeMount(): void {
   this._source = new SbisService({
      keyProperty: 'department',
      // Элементы статического источника описаны в отдельном файле, его можно найти в исходных файлах демо-примера
      data: MemorySourceData
   });
}

Конфигурация иерархического списка

Для обеспечения навигации по иерархическому списку необходимо задать опцию root в конфигурацию контрола Layout/browsers:Browser. Это обеспечит корректную работу поиска и навигации по хлебным крошкам.

Строка поиска

Подробнее о контроле "Строка поиска" можно прочитать здесь.

Далее описан порядок добавления строки поиска в браузер реестра:

  1. Для Layout/browsers:Browser в опцию search добавьте контрол Controls/search:Input.
  2. Для Layout/browsers:Browser в опцию searchParam установите имя поля, которое будет передаваться в параметре "Фильтр" при вызове списочного метода.
<!-- MyRegistry.wml -->
<Layout.browsers:Browser source="{{_source}}" keyProperty="id"
   searchParam="department">
   <ws:search>
        <Controls.search:Input />
   </ws:search>
   <ws:content>
      <Controls.list:View />
   </ws:content>
</Layout.browsers:Browser>

В некоторых случаях необходимо скрывать настройку строки поиска в браузере по определенному условию. В следующем примере показано как это сделать с помощью встроенного шаблона:

<!-- WML -->
<ws:template name="browser">
   <Layout.browsers:Browser search="{{ search }}"/>
</ws:template>

<ws:partial template="browser">
   <ws:search>
      <Controls.search:Input />
   </ws:search>
</ws:partial>

Настройка поиска со сменой раскладки

См. руководство.

Объединенный фильтр

Подробнее о контроле "Объединенный фильтр" можно прочитать здесь.

Далее описан порядок добавления объединенного фильтра в браузер реестра:

  1. Для Layout/browsers:Browser в опцию filterView добавьте контрол Controls/filter:View.
<!-- MyRegistry.wml -->
<Layout.browsers:Browser source="{{_source}}" keyProperty="id" searchParam="department">
   <ws:search>
      <Controls.search:Input />
   </ws:search>
   <ws:content>
      <Controls.list:View />
   </ws:content>
    <ws:filterView>
        <Controls.filter:View />
    </ws:filterView>
</Layout.browsers:Browser>
  1. В конфигурации Controls/filter:View в опцию detailPanelTemplateName установите шаблон для панели фильтров. Подробнее о конфигурации панели фильтров можно прочитать здесь.
    В следующем примере шаблон задан из отдельного WML-файла.
<!-- MyRegistry.wml -->
<Layout.browsers:Browser source="{{_source}}" keyProperty="id" searchParam="department">
   <ws:search>
      <Controls.search:Input />
   </ws:search>
   <ws:content>
      <Controls.list:View />
   </ws:content>
   <ws:filterView>
      <Controls.filter:View detailPanelTemplateName="wml!Engine-demo/Browser/BrowserFilterView/filterDetailPanelTemplate" />
   </ws:filterView>
</Layout.browsers:Browser>
<!-- Engine-demo/Browser/BrowserFilterView/filterDetailPanelTemplate.wml -->
<Controls.filterPopup:DetailPanel attr:class="controls-PanelFilter__width-m" items="{{items}}">
   <ws:itemTemplate templateName="wml!Engine-demo/Browser/BrowserFilterView/itemsTemplate"/>
   <ws:additionalTemplate templateName="wml!Engine-demo/Browser/BrowserFilterView/addItemsTemplate"/>
</Controls.filterPopup:DetailPanel>
<!-- Engine-demo/Browser/BrowserFilterView/itemsTemplate.wml -->
<ws:template name="owner">
   <Controls.source:SelectedKey bind:selectedKey="item.value">
      <Controls.filterPopup:Dropdown
         source="{{item.editorOptions.source}}"
         keyProperty="owner"
         displayProperty="title"/>
   </Controls.source:SelectedKey>
</ws:template>
 
<ws:template name="department">
   <Controls.source:SelectedKey bind:selectedKey="item.value">
      <Controls.filterPopup:Dropdown
         source="{{item.source}}"
         keyProperty="title"
         displayProperty="title"/>
   </Controls.source:SelectedKey>
</ws:template>
 
<ws:partial template="{{item.id}}" item="{{item}}"/>
<!-- Engine-demo/Browser/BrowserFilterView/addItemsTemplate.wml -->
<ws:template name="department">
   <Controls.filterPopup:Link
      caption="По департаменту"/>
</ws:template>
 
<ws:partial template="{{item.id}}" item="{{item}}"/>
  1. В конфигурации Controls/filter:View установите структуру фильтров. Для этого в конфигурации Layout/browsers:Browser установите значение для опции filterSource. Подробнее о настройке структуры фильтров читайте здесь.
<!-- MyRegistry.wml -->
<Layout.browsers:Browser source="{{_source}}" keyProperty="id" searchParam="department"
   filterSource="{{_items}}">
   <ws:search>
      <Controls.search:Input />
   </ws:search>
   <ws:content>
      <Controls.list:View />
   </ws:content>
   <ws:filterView>
      <Controls.filter:View detailPanelTemplateName="wml!Engine-demo/Browser/BrowserFilterView/filterDetailPanelTemplate" />
   </ws:filterView>
</Layout.browsers:Browser>
// MyRegistry.js
var filterButtonData = [
   {
      name: 'owner',
      resetValue: '0',
      value: '0',
      textValue: '',
      viewMode: 'frequent',
      editorOptions: {
         keyProperty: 'owner',
         displayProperty: 'title',
         source: new sourceLib.Memory({
            data: [
               {id: 0, title: 'По ответственному', owner: '0'},
               {id: 1, title: 'Новиков Д.В.', owner: 'Новиков Д.В.'},
               {id: 2, title: 'Кошелев А.Е.', owner: 'Кошелев А.Е.'},
               {id: 3, title: 'Субботин А.В.', owner: 'Субботин А.В.'},
               {id: 4, title: 'Чеперегин А.С.', owner: 'Чеперегин А.С.'}
            ],
            keyProperty: 'id'
         })
      }
   }
}];
var ModuleClass = Control.extend({
   _items: filterButtonData
});
  1. В конфигурации Controls/filter:View в опцию panelTemplateName установите шаблон для быстрых фильтров. Подробнее о конфигурации быстрых фильтров подробнее можно прочитать здесь.
<!-- MyRegistry.wml -->
<Layout.browsers:Browser source="{{_source}}" keyProperty="id" searchParam="department" filterSource="{{_items}}">
   <ws:search>
      <Controls.search:Input />
   </ws:search>
   <ws:content>
      <Controls.list:View />
   </ws:content>
   <ws:filterView>
      <Controls.filter:View detailPanelTemplateName="wml!Engine-demo/Browser/BrowserFilterView/filterDetailPanelTemplate"
         panelTemplateName="Controls/filterPopup:SimplePanel" />
   </ws:filterView>
</Layout.browsers:Browser>

Элементы быстрого фильтра настраиваются через источник данных Layout/browsers:Browser.

this._source = new BrowserMemory({
   idProperty: 'department',
   data: MemorySourceData,
   filter: MemorySourceFilter({
      owner: '0',
      department: 'По департаменту'
   })
});

Панель действий

Подробнее о контроле "Панель действий" можно прочитать здесь.

Далее описан порядок добавления панели действий в браузер реестра:

  1. Для Layout/browsers:Browser в опцию operationsPanel добавьте конфигурацию Controls/operations:Panel.
<!-- MyRegistry.wml -->
<Layout.browsers:Browser source="{{_source}}" keyProperty="id" searchParam="department" filterSource="{{_items}}">
   <ws:search>
      <Controls.search:Input />
   </ws:search>
   <ws:content>
      <Controls.list:View />
   </ws:content>
   <ws:filterView>
      <Controls.filter:View detailPanelTemplateName="wml!Engine-demo/Browser/BrowserFilterView/filterDetailPanelTemplate"
         panelTemplateName="Controls/filterPopup:SimplePanel" />
   </ws:filterView>
   <ws:operationsPanel>
      <Controls.operations:Panel
         parentProperty="parent"
         nodeProperty="@parent"
         keyProperty="id"
         on:itemClick="_panelItemClick()"/>
   </ws:operationsPanel>
</Layout.browsers:Browser>
  1. Для Controls/operations:Panel в опции source задайте конфигурацию команд. Подробнее о конфигурации команд читайте здесь.
<!-- MyRegistry.wml -->
<Layout.browsers:Browser source="{{_source}}" keyProperty="id" searchParam="department" filterSource="{{_items}}">
   <ws:search>
      <Controls.search:Input />
   </ws:search>
   <ws:content>
      <Controls.list:View />
   </ws:content>
   <ws:filterView>
      <Controls.filter:View detailPanelTemplateName="wml!Engine-demo/Browser/BrowserFilterView/filterDetailPanelTemplate"
         panelTemplateName="Controls/filterPopup:SimplePanel" />
   </ws:filterView>
   <ws:operationsPanel>
      <Controls.operations:Panel
         source="{{_operationsPanelSource}}"
         parentProperty="parent"
         nodeProperty="@parent"
         keyProperty="id"
         on:itemClick="_panelItemClick()"/>
   </ws:operationsPanel>
</Layout.browsers:Browser>
protected _operationsPanelData: null;
protected _operationsPanelSource: null;
protected _beforeMount(): void {
   this._operationsPanelSource = new sourceLib.Memory({
      keyProperty: 'id',
      data: _operationsPanelData
   });
   this._operationsPanelData = [{
      id: 'remove',
      icon: 'icon-Erase icon-error',
      '@parent': false,
      title: 'Удалить',
      parent: null
   }];
},
  1. Для Layout/browsers:Browser в опции operationsPanelExpanded настройте стартовое отображение панели действий.
<!-- MyRegistry.wml -->
<Layout.browsers:Browser source="{{_source}}" keyProperty="id" searchParam="department" filterSource="{{_items}}"
   bind:operationsPanelExpanded="_operationsPanelExpanded">
   <ws:search>
      <Controls.search:Input />
   </ws:search>
   <ws:content>
      <Controls.list:View />
   </ws:content>
   <ws:filterView>
      <Controls.filter:View detailPanelTemplateName="wml!Engine-demo/Browser/BrowserFilterView/filterDetailPanelTemplate"
         panelTemplateName="Controls/filterPopup:SimplePanel" />
   </ws:filterView>
   <ws:operationsPanel>
      <Controls.operations:Panel
         source="{{_operationsPanelSource}}"
         parentProperty="parent"
         nodeProperty="@parent"
         keyProperty="id"
         on:itemClick="_panelItemClick()"/>
   </ws:operationsPanel>
</Layout.browsers:Browser>
  1. Использование панели действий актуально, когда включен режим массового выбора записей. Для этого в конфигурации Layout/browsers:Browser в опции multiSelectVisibility установите значение visible или onhover.
    В демо-примере значение опции задается в обработчике клика по кнопкам, которые находятся под реестром.
<!-- MyRegistry.wml -->
<Layout.browsers:Browser source="{{_source}}" keyProperty="id" searchParam="department" filterSource="{{_items}}" bind:operationsPanelExpanded="_operationsPanelExpanded"
   multiSelectVisibility="{{_multiSelectVisibility}}">
   <ws:search>
      <Controls.search:Input />
   </ws:search>
   <ws:content>
      <Controls.list:View />
   </ws:content>
   <ws:filterView>
      <Controls.filter:View detailPanelTemplateName="wml!Engine-demo/Browser/BrowserFilterView/filterDetailPanelTemplate"
         panelTemplateName="Controls/filterPopup:SimplePanel" />
   </ws:filterView>
   <ws:operationsPanel>
      <Controls.operations:Panel
         source="{{_operationsPanelSource}}"
         parentProperty="parent"
         nodeProperty="@parent"
         keyProperty="id"
         on:itemClick="_panelItemClick()"/>
   </ws:operationsPanel>
</Layout.browsers:Browser>
<Controls.buttons:Button caption="Checkbox: onhover" on:click="_onToggleMultiSelectVisibility('onhover')"/>
<Controls.buttons:Button caption="Checkbox: hidden" on:click="_onToggleMultiSelectVisibility('hidden')"/>
// MyRegistry.js
var ModuleClass = Control.extend({
   _multiSelectVisibility: 'hidden',
   ...
   _onToggleMultiSelectVisibility: function(event, multiSelectVisibility) {
      this._multiSelectVisibility = multiSelectVisibility;
   }
});

А также для Layout/browsers:Browser свяжите опции selectedKeys и excludedKeys со свойствами контрола.

<!-- MyRegistry.wml -->
<Layout.browsers:Browser source="{{_source}}" keyProperty="id" searchParam="department" filterSource="{{_items}}" bind:operationsPanelExpanded="_operationsPanelExpanded" multiSelectVisibility="{{_multiSelectVisibility}}"
   bind:selectedKeys="_selectedKeys" bind:excludedKeys="_excludedKeys">
   <ws:search>
      <Controls.search:Input />
   </ws:search>
   <ws:content>
      <Controls.list:View />
   </ws:content>
   <ws:filterView>
      <Controls.filter:View detailPanelTemplateName="wml!Engine-demo/Browser/BrowserFilterView/filterDetailPanelTemplate"
         panelTemplateName="Controls/filterPopup:SimplePanel" />
   </ws:filterView>
   <ws:operationsPanel>
      <Controls.operations:Panel
         source="{{_operationsPanelSource}}"
         parentProperty="parent"
         nodeProperty="@parent"
         keyProperty="id"
         on:itemClick="_panelItemClick()"/>
   </ws:operationsPanel>
</Layout.browsers:Browser>
// MyRegistry.js
var ModuleClass = Control.extend({
   _selectedKeys: [],
   _excludedKeys: [],
   ...
});

Примечание

Если в опцию content для Layout.browsers:Browser подается список, обернутый в DOM-элемент, то список необходимо обернуть в Controls.list:Container.

<div>
    <Controls.list:Container>
        <Controls.list:View/>
    </Controls.list:Container>
</div>

Отображение элементов управления рядом со строкой поиска

Для отображения дополнительных элементов управления реестром, которые расположены рядом со строкой поиска, для Layout/browsers:Browser установите значение в опцию beforeFilterTemplate.

<!-- MyRegistry.wml -->
<Layout.browsers:Browser source="{{_source}}" keyProperty="id" searchParam="department" filterSource="{{_items}}" bind:operationsPanelExpanded="_operationsPanelExpanded" multiSelectVisibility="{{_multiSelectVisibility}}" bind:selectedKeys="_selectedKeys" bind:excludedKeys="_excludedKeys">
   <ws:beforeFilterTemplate>
      <div class="demo-browser-topTemplate">
         <Controls.buttons:Button
            icon="icon-AddButtonNew"
            buttonStyle="secondary"
            viewMode="ghost"
            class="demo-browser-button"/>
        </div>
   </ws:beforeFilterTemplate>
   <ws:search>
      <Controls.search:Input />
   </ws:search>
   <ws:content>
      <Controls.list:View />
   </ws:content>
   <ws:filterView>
      <Controls.filter:View detailPanelTemplateName="wml!Engine-demo/Browser/BrowserFilterView/filterDetailPanelTemplate"
         panelTemplateName="Controls/filterPopup:SimplePanel" />
   </ws:filterView>
   <ws:operationsPanel>
      <Controls.operations:Panel
         source="{{_operationsPanelSource}}"
         parentProperty="parent"
         nodeProperty="@parent"
         keyProperty="id"
         on:itemClick="_panelItemClick()"/>
   </ws:operationsPanel>
</Layout.browsers:Browser>

Удаление и перемещение записей

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