Отображение узлов в виде групп

Базовый функционал группировки предоставляет возможность объединять записи в группы по общему признаку. При базовой группировке доступна лишь навигация по всему списку, а загрузка записей осуществляется либо по скроллу, либо по кнопке "Еще" внизу всего списка.

В случае, когда необходимо обеспечить навигацию для каждой группы по отдельности (при помощи кнопки "Ещё" внизу группы) или отобразить данные справа от заголовка узла (например, итоговую сумму значений дочерних элементов узла), используется функционал отображения узлов в виде групп.

Чтобы настроить отображение узлов в виде групп, сделайте следующее:

  1. В опции nodeTypeProperty укажите имя поля записи, которое содержит информацию о том как отображать этот узел: в виде группы или в виде узла.
<!-- WML -->
<Controls.treeGrid:View
   source="{{ _viewSource }}"
   parentProperty="parent"
   nodeProperty="type"
   rowSeparatorSize="s"
   nodeTypeProperty="nodeType" />
  1. В конфигурации источника данных для каждой записи установите поле с именем, указанным в опции nodeTypeProperty. Чтобы отобразить узел в виде группы, это поле должно иметь значение "group".
// TypeScript
import {Control} from 'UI/Base';
import {HierarchicalMemory} from 'Types/source';
 
export default class MyClass extends Control {
    protected _viewSource: HierarchicalMemory;
    protected _beforeMount(): void {
        this._viewSource = new HierarchicalMemory({
            keyProperty: 'key',
            data: [
                { 
                    key: 1, 
                    title: 'Товары и материалы', 
                    parent: null, 
                    type: true, 
                    hasChild: true,
                    nodeType: 'group'
                }
            ];
        });
    }
}
  1. Если заголовок узла, отображаемого в виде группы, необходимо растянуть на несколько колонок или на всю ширину таблицы, то необходимо использовать функцию обратного вызова colspanCallback, которая будет возвращать число объединяемых колонок, или 'end' чтобы использовать всю ширину таблицы.

В следующем примере приведена конфигурация функции обратного вызова colspanCallback.

<!-- WML -->
<Controls.treeGrid:View
   source="{{ _viewSource }}"
   parentProperty="parent"
   nodeProperty="type"
   nodeTypeProperty="nodeType"
   rowSeparatorSize="s"
   colspanCallback="{{ _colspanCallback }}">
// TypeScript
protected _colspanCallback(item: Model, column: IGroupNodeColumn, columnIndex: number, isEditing: boolean): TColspanCallbackResult 
{
    if (item.get(NODE_TYPE_PROPERTY) === 'group' && columnIndex === 0) {
       return 3;
    }
    return 1;
}

Отображение итогов в узле

Чтобы отобразить итоги по группе, сделайте следующее:

  1. Настройте источник данных так, чтобы для узлов в соответствующих колонках были данные итогов по этому узлу.
// TypeScript
import {HierarchicalMemory} from 'Types/source';
protected _beforeMount(): void {
this._viewSource = new HierarchicalMemory({
    keyProperty: 'key',
    data: [
        { 
            key: 1, 
            title: 'Канцелярия', 
            count: '', 
            price: '25', 
            parent: null, 
            type: true, 
            hasChild: true, 
            nodeType: 'group'
        },
        {
            key: 12, 
            title: 'блокнот', 
            count: '10 шт', 
            price: '15', 
            parent: 1, 
            type: null, 
            nodeType: null 
        },
        { 
            key: 13, 
            title: 'Ватман А4', 
            count: '100 шт', 
            price: '10', 
            parent: 1, 
            type: null, 
            nodeType: null
        },
    ]
};
  1. В функции colspanCallback верните число колонок, которое должен занимать заголовок узла. В остальных колонках будут выведены значения, которые возвращает источник данных для колонок этого узла.

В следующем примере заголовок узла, отображаемого в виде группы, занимает две колонки, а в третьей, будет выведено значение итогов по столбцу "price".

<!-- WML -->
<Controls.treeGrid:View
   source="{{ _viewSource }}"
   parentProperty="parent"
   nodeProperty="type"
   nodeTypeProperty="nodeType"
   rowSeparatorSize="s"
   colspanCallback="{{ _colspanCallback }}">
// TypeScript
protected _columns: IGroupNodeColumn[] = [
  {displayProperty: 'title', width: '300px'},
  {displayProperty: 'count', width: '100px'},
  {displayProperty: 'price', width: '100px'}
];
protected _colspanCallback(item: Model, column: IGroupNodeColumn, columnIndex: number, isEditing: boolean): TColspanCallbackResult 
{
    if (item.get(NODE_TYPE_PROPERTY) === 'group' && columnIndex === 0) {
        return 2;
    }
    return 1;
}

Выравнивание текста заголовка группы

Чтобы настроить выравнивание текста заголовка группы, установите значение для свойства textAlign в конфигурации groupNodeConfig. По умолчанию текст заголовка выравнивается по центру.

В следующем примере текст заголовка выровнен по правому краю колонки.

// TypeScript
protected _beforeMount(): void {
    this._columns: IGroupNodeColumn[]= [
        {
            displayProperty: 'title',
            width: '300px', 
            groupNodeConfig: { textAlign: 'right' }
        },
        {
            displayProperty: 'count',
             width: '100px'
        }
    ],
}

Выравнивание текста заголовка группы по колонке

Чтобы выровнять текст заголовка группы по колонке, сделайте следующее:

  1. Задайте colspan для колонки с заголовком группы с помощью функции обратного вызова colspanCallback.
<!-- WML -->
<Controls.treeGrid:View
   source="{{ _viewSource }}"
   columns= "{{_columns}}";
   parentProperty="parent"
   nodeProperty="type"
   nodeTypeProperty="nodeType"
   colspanCallback="{{ _colspanCallback }}">
// TypeScript
protected _colspanCallback(item: Model, column: IGroupNodeColumn, columnIndex: number, isEditing: boolean): TColspanCallbackResult 
{
    if (item.get(NODE_TYPE_PROPERTY) === 'group' && columnIndex === 0) {
        return 2;
    }
    return 1;
}
  1. Установите значение "right" для опции textAlign в конфигурации заголовка группы groupNodeConfig.
// TypeScript
protected _columns: IGroupNodeColumn[] = [
    {
        displayProperty: 'title',
        width: '300px', 
        groupNodeConfig: { textAlign: 'right' }
    },
    {   
        displayProperty: 'count',
        width: '100px'
    },
    {
        displayProperty: 'price',
        width: '100px'
    },
    {
        displayProperty: 'price1',
        width: '100px'
    }
];
  1. В конфигурации колонки, следующей за заголовком группы (в нашем примере это 3 колонка "price") в свойстве groupNodeConfig укажите опцию textVisible со значением false.

Таким образом, будет выведена горизонтальная линия (разделитель группы) справа от колонки с заголовком группы.

// TypeScript
protected _columns: IGroupNodeColumn[] = [
    {
        displayProperty: 'title',
        width: '300px', 
        groupNodeConfig: { textAlign: 'right' }
    },
    {
        displayProperty: 'count',
        width: '100px'
    },
    {
        displayProperty: 'price',
        width: '100px',
        groupNodeConfig: { textVisible: false }
    },
    {
        displayProperty: 'price1',
        width: '100px'
    }
]

Сохранение состояния развернутости группы

Поддерживается возможность после перезагрузки списка (например, при изменении параметров фильтра или поиска) сохранить группу развернутой.

Чтобы выполнить перезагрузку списка с сохранением развернутых групп, необходимо:

  1. Установить опцию deepReload в значение true:
    • на списке:
      <!-- WML -->
      <Controls.explorer:View 
          source="{{_viewSource}}" 
          deepReload="{{true}}" />
    • на контейнере данных или браузере, если они используются:
      <!-- WML -->
      <Controls.browser:Browser 
         source="{{_viewSource}}" 
         deepReload="{{true}}">
          <Controls.explorer:View name="explorerView" />
      </Controls.browser:Browser>
  2. Установить опцию searchNavigationMode в значение expand. Подробнее в статье:
<!-- WML -->
<Controls.browser:Browser 
   source="{{_viewSource}}" 
   deepReload="{{true}}"
   searchNavigationMode="expand">
    <Controls.explorer:View name="explorerView" />
</Controls.browser:Browser>