3.5.2.1.45. Table
В этом разделе:
Компонент Table
позволяет выводить информацию в табличном виде, сортировать данные, управлять колонками и заголовками таблицы, вызывать действия для выбранных строк.
XML-имя компонента: table
Пример описания таблицы в XML-дескрипторе экрана:
<data readOnly="true">
<collection id="ordersDc" class="com.company.sales.entity.Order" view="order-with-customer">
<loader id="ordersDl">
<query>
<![CDATA[select e from sales_Order e]]>
</query>
</loader>
</collection>
</data>
<layout>
<table id="ordersTable" dataContainer="ordersDc" width="100%">
<columns>
<column id="date"/>
<column id="amount"/>
<column id="customer"/>
</columns>
<rowsCount/>
</table>
</layout>
Здесь в элементе data
определен контейнер данных, который выбирает сущности Order
с помощью JPQL запроса select o from sales_Order o order by o.date
. Для компонента table
указывается используемый контейнер данных, а в элементе columns
- какие атрибуты сущности, содержащейся в контейнере, использовать в качестве колонок.
Если вы хотите указать источник данных для таблицы программно в контроллере экрана, используйте атрибут metaClass вместо декларативного указания значения dataContainer в XML.
Элементы table
-
rows
- обязательный элемент в случае, если для привязывания таблицы к данным используется атрибут datasource.Для строк можно настроить отображение заголовков - задать каждой строке свой значок в дополнительной колонке слева. Для этого в контроллере экрана необходимо реализовать интерфейс
ListComponent.IconProvider
и установить его таблице:@Inject private Table<Customer> table; @Subscribe protected void onInit(InitEvent event) { table.setIconProvider(new ListComponent.IconProvider<Customer>() { @Nullable @Override public String getItemIcon(Customer entity) { CustomerGrade grade = entity.getGrade(); switch (grade) { case PREMIUM: return "icons/premium_grade.png"; case HIGH: return "icons/high_grade.png"; case MEDIUM: return "icons/medium_grade.png"; default: return null; } } }); }
-
columns
- элемент, определяющий набор колонок таблицы. Если не задан, то столбцы таблицы будут автоматически определены из атрибутов представления, используемого при загрузке данных из контейнера данных. Элементcolumns
имеет следующие атрибуты:-
includeAll
– загружает все атрибуты представления, используемого при загрузке данных из контейнера данных.В приведенном ниже примере мы покажем все атрибуты из представления, используемого в
customersDc
. Если представление содержит системные свойства, они также будут показаны.<table id="table" width="100%" height="100%" dataContainer="customersDc"> <columns includeAll="true"/> </table>
Если представление сущности содержит ссылочный атрибут, этот атрибут выводится в соответствии с его шаблоном @NamePattern. Если вы хотите показать какой-то конкретный атрибут, он должен быть определен в представлении, а также в элементе
column
:<columns includeAll="true"> <column id="address.street"/> </columns>
Если представление не указано, атрибут
includeAll
загрузит все атрибуты из данной сущности и ее предков.
-
exclude
– разделенный запятыми список атрибутов, которые не должны быть загружены в таблицу.В приведенном ниже примере мы покажем все атрибуты, за исключением атрибутов
name
иorder
:<table id="table" width="100%" height="100%" dataContainer="customersDc"> <columns includeAll="true" exclude="name, order"/> </table>
Каждая колонка описывается во вложенном элементе
column
со следующими атрибутами:-
id
− обязательный атрибут, содержит название атрибута сущности, выводимого в колонке. Может быть как непосредственным атрибутом сущности, находящейся в контейнере, так и атрибутом связанной сущности - переход по графу объектов обозначается точкой. Например:<columns> <column id="date"/> <column id="customer"/> <column id="customer.name"/> <column id="customer.address.country"/> </columns>
-
collapsed
− необязательный атрибут, при указанииtrue
колонка будет изначально скрыта. Пользователь может управлять отображением колонок с помощью меню, доступного по кнопке в правой верхней части таблицы, если атрибутcolumnControlVisible
таблицы неfalse
. По умолчаниюcollapsed
имеет значениеfalse
.
-
expandRatio
− необязательный атрибут, определяющий относительную длину для каждой колонки. Принимает значение большее или равное 0. Если хотя бы одной колонке установлено значение атрибутаexpandRatio
, все неявные значения игнорируются и учитываются только явно присвоенные значения. Если вы одновременно установите атрибуты width иexpandRatio
, это вызовет ошибку в приложении.
-
width
− необязательный атрибут, отвечает за изначальную ширину колонки. Может принимать только числовые значения в пикселах.
-
align
- необязательный атрибут, устанавливает выравнивание текста в ячейках данной колонки. Возможные значения:LEFT
,RIGHT
,CENTER
. По умолчаниюLEFT
.
-
editable
− необязательный атрибут, разрешает/запрещает редактирование данной колонки в редактируемой таблице. Чтобы колонка была редактируемой, атрибут editable всей таблицы также должен быть установлен вtrue
. Динамическое изменение значения этого атрибута не поддерживается.
-
sortable
− необязательный атрибут, позволяющий запретить сортировку колонки. Вступает в действие, если атрибут sortable всей таблицы установлен вtrue
(что имеет место по умолчанию).
-
sort
− необязательный атрибут, позволяющий задать начальную сортировку таблицы по указанной колонке в соответствии с направлением сортировки. Возможные значения:-
ASCENDING
– сортировка по возрастанию (например, A-Z, 1..9). -
DESCENDING
– сортировка по убыванию (например, Z-A, 9..1).
<columns> <column property="name" sort="DESCENDING"/> </columns>
-
Обратите внимание: если значение атрибута settingsEnabled установлено в
true
, таблица сортируется в соответствии с настройками пользователя.В одно и то же время таблица может быть сортирована только по одной колонке. Таким образом, приведенный ниже пример:
<columns> <column property="name" sort="DESCENDING"/> <column property="parent" sort="ASCENDING"/> </columns>
вызовет исключение.
Если одновременно для колонки установить атрибуты
sort
иsortable="false"
, это также вызовет исключение.-
maxTextLength
- необязательный атрибут, позволяет ограничивать количество символов в ячейке. При этом если разница между фактическим и допустимым количеством символов не превышает порог в 10 символов, "лишние" символы не скрываются. Для просмотра полной записи надо кликнуть на ее видимую часть. Пример колонки с ограничением в 10 символов:
-
link
- установка атрибута вtrue
позволяет отобразить в ячейке таблицы ссылку на экран просмотра экземпляра сущности (поддерживается только для Web Client). Атрибутlink="true"
) может указываться и для колонок примитивных типов: в этом случае, при нажатии на ссылку будет открываться редактор основной сущности таблицы. Такой подход может применяться для упрощения навигации - пользователи смогут открывать редактор одним кликом по некоторому ключевому атрибуту.
-
linkScreen
- позволяет указать идентификатор экрана, который будет открыт по нажатию на ссылку, включенную свойствомlink
.
-
linkScreenOpenType
- задает режим открытия экрана (THIS_TAB
,NEW_TAB
илиDIALOG
).
-
linkInvoke
- позволяет заменить открытие окна на вызов метода контроллера.@Inject private Notifications notifications; public void linkedMethod(Entity item, String columnId) { Customer customer = (Customer) item; notifications.create() .withCaption(customer.getName()) .show(); }
-
необязательный атрибут
generator
содержит ссылку на метод в контроллере экрана, который создает визуальный компонент для отображения содержимого ячейки:<columns> <column id="name"/> <column id="imageFile" generator="generateImageFileCell"/> </columns>
public Component generateImageFileCell(Employee entity){ Image image = uiComponents.create(Image.NAME); image.setSource(FileDescriptorResource.class).setFileDescriptor(entity.getImageFile()); return image; }
Он может быть использован вместо передачи реализации
Table.ColumnGenerator
в метод addGeneratedColumn(). -
Элемент
column
может содержать вложенный элемент formatter для представления значения атрибута в виде, отличном от стандартного для данного Datatype:<column id="date"> <formatter class="com.haulmont.cuba.gui.components.formatters.DateFormatter" format="yyyy-MM-dd HH:mm:ss" useUserTimezone="true"/> </column>
-
-
rowsCount
− необязательный элемент, создающий для таблицы компонентRowsCount
, который позволяет загружать в таблицу данные постранично. Размер страницы задается путем ограничения количества записей в контейнере методомsetMaxResults()
loader'а. Как правило, это делает связанный с загрузчиком данных таблицы компонент Filter, однако при отсутствии универсального фильтра можно вызвать этот метод и напрямую из контроллера экрана.Компонент
RowsCount
может также отобразить общее число записей, возвращаемых текущим запросом в контейнере данных, без извлечения этих записей. По клику пользователя на знак "?" вызываетсяcom.haulmont.cuba.core.global.DataManager#getCount
, что приводит к выполнению в БД запроса с такими же, как у текущего запроса условиями, но с агрегатной функциейCOUNT(*)
вместо результатов. Полученное число отображается вместо знака "?".Атрибут
autoLoad
компонентаRowsCount
, установленный в значениеtrue
, позволяет автоматически загружать общее число записей. Его можно установить в XML-дескрипторе:<rowsCount autoLoad="true"/>
Также включить или отключить автоматическую загрузку количества записей можно с помощью API в контроллере экрана:
boolean autoLoadEnabled = rowsCount.getAutoLoad(); rowsCount.setAutoLoad(false);
-
actions
− необязательный элемент для описания действий, связанных с таблицей. Кроме описания произвольных действий, поддерживаются следующие стандартные действия, определенные в пакетеcom.haulmont.cuba.gui.actions.list
:create
,edit
,remove
,refresh
,add
,exclude
,excel
.
Атрибуты table
-
Атрибут
emptyStateMessage
позволяет задать сообщение в тех случаях, когда нет загруженных данных, установлены нулевые значения или контейнер данных пуст. Данный атрибут часто используется совместно с атрибутом emptyStateLinkMessage. Сообщение может содержать информацию о том, какие данные должна содержать таблица. Например:<table id="table" emptyStateMessage="No data added to the table" ... width="100%">
Атрибут
emptyStateMessage
поддерживает загрузку сообщений из пакета сообщений. Если вы не хотите отображать сообщение, просто не указывайте этот атрибут.
-
Атрибут
emptyStateLinkMessage
позволяет задать сообщение в виде гиперссылки в тех случаях, когда нет загруженных данных, установлены нулевые значения или контейнер данных пуст. Данный атрибут часто используется совместно с атрибутом emptyStateMessage. Сообщение должно описывать действие, которое необходимо выполнить для заполнения таблицы. Например:<table id="table" emptyStateMessage="No data added to the table" emptyStateLinkMessage="Add data (Ctrl+\)" ... width="100%">
Атрибут
emptyStateLinkMessage
поддерживает загрузку сообщений из пакета сообщений. Если вы не хотите отображать сообщение, просто не указывайте этот атрибут.Чтобы обработать событие перехода по ссылке, используйте метод setEmptyStateLinkClickHandler или подпишитесь на соответствующее событие в контроллере экрана:
@Install(to = "customersTable", subject = "emptyStateLinkClickHandler") private void customersTableEmptyStateLinkClickHandler(Table.EmptyStateClickEvent<Customer> emptyStateClickEvent) { screenBuilders.editor(emptyStateClickEvent.getSource()) .newEntity() .show(); }
-
Атрибут
multiselect
позволяет задать режим множественного выделения строк в таблице. Еслиmultiselect
равенtrue
, то пользователь может выделить несколько строк с помощью клавиатуры или мыши, удерживая клавиши Ctrl или Shift. По умолчанию режим множественного выделения отключен.
-
Атрибут
sortable
разрешает или запрещает сортировку в таблице. По умолчанию имеет значениеtrue
. Если сортировка разрешена, то при нажатии на название колонки справа от названия появляется значок /. Сортировку некоторой отдельной колонки можно запретить с помощью атрибута sortable этой колонки.При включенной с помощью элемента
rowsCount
(см. выше) страничной загрузке таблицы сортировка производится разными способами в зависимости от того, умещаются ли все записи на одной странице. Если умещаются, то сортировка производится в памяти, без обращений к БД. Если же страниц больше одной, то сортировка производится на базе данных путем отправки нового запроса с соответствующимORDER BY
.Колонка таблицы может ссылаться на локальный атрибут или на связанную сущность. Например:
<table id="ordersTable" dataContainer="ordersDc"> <columns> <column id="customer.name"/> <!-- the 'name' attribute of the 'Customer' entity --> <column id="contract"/> <!-- the 'Contract' entity --> </columns> </table>
В последнем случае, сортировка на базе данных производится по атрибутам, указанным в аннотации
@NamePattern
связанной сущности. Если у связанной сущности нет такой аннотации, то сортировка производится в памяти только в пределах текущей страницы.Если колонка таблицы ссылается на неперсистентный атрибут, то сортировка на базе данных производится по атрибутам, указанным в параметре
related()
аннотации@MetaProperty
. Если такой параметр не указан, то сортировка производится в памяти только в пределах текущей страницы.Если таблица соединена со вложенным property container, который содержит коллекцию связанных сущностей, то для того, чтобы таблицу можно было сортировать, атрибут-коллекция должен быть упорядоченного типа (
List
илиLinkedHashSet
). Если атрибут имеет типSet
, то атрибутsortable
не оказывает влияния и пользователи не смогут сортировать таблицу.Если необходимо, можно создать собственную реализацию сортировки.
-
Атрибут
presentations
управляет механизмом представлений. Значение по умолчанию равноfalse
. Когда значение атрибута равноtrue
, то в верхнем правом углу таблицы появляется значок . Механизм представлений реализован только для блока Web Client.
-
Установка атрибута
columnControlVisible
вfalse
запрещает пользователю скрывать колонки с помощью меню, выпадающего при нажатии на кнопку в правой части шапки таблицы. Флажками в меню отмечаются отображаемые в данный момент колонки. Существуют дополнительные пункты меню:-
Select all
− показать все колонки таблицы; -
Deselect all
− спрятать все колонки, кроме первой. Первая колонка не скрывается для правильного отображения таблицы.
-
-
Установка атрибута
reorderingAllowed
вfalse
запрещает пользователю менять местами колонки, перетаскивая их с помощью мыши.
-
Установка атрибута
columnHeaderVisible
вfalse
скрывает заголовок таблицы.
-
При установленном в
false
атрибутеshowSelection
текущая строка не имеет выделения.
-
Атрибут
contextMenuEnabled
разрешает или запрещает показывать контекстное меню. По умолчанию атрибут имеет значениеtrue
. В контекстном меню отображаются действия таблицы (если они есть), и пункт Системная информация, содержащий информацию о выбранной сущности (если у пользователя есть разрешениеcuba.gui.showInfo
).
-
Если атрибуту
multiLineCells
таблицы присвоить значениеtrue
, то ячейки, содержащие текст с переносами строк, будут отображать его в несколько строк. В таком режиме в веб-клиенте для правильной работы полосы прокрутки все строки текущей страницы таблицы будут загружены веб-браузером сразу, без ленивой загрузки видимой части таблицы. По умолчанию атрибут имеет значениеfalse
.
-
Атрибут
aggregatable
включает режим агрегации строк таблицы. Поддерживаются следующие операции:-
SUM
- сумма -
AVG
- среднее значение -
COUNT
- количество -
MIN
- минимальное значение -
MAX
- максимальное значение
Для агрегируемых колонок необходимо указать элемент
aggregation
с атрибутомtype
, задающим функцию агрегации. По умолчанию в агрегируемых колонках поддерживаются только числовые типы данных, такие какInteger
,Double
,Long
иBigDecimal
. Агрегированные значения столбцов выводятся в дополнительной строке вверху таблицы. Пример описания таблицы с агрегацией:<table id="itemsTable" aggregatable="true" dataContainer="itemsDc"> <columns> <column id="product"/> <column id="quantity"/> <column id="amount"> <aggregation type="SUM"/> </column> </columns> </table>
Элемент
aggregation
может содержать атрибутeditable
. Установка атрибута в значениеtrue
совместно с использованием метода setAggregationDistributionProvider() позволяет реализовать функциональность распределения значения агрегируемой ячейки между строками таблицы.Элемент
aggregation
может также содержать атрибутstrategyClass
, указывающий класс, реализующий интерфейсAggregationStrategy
(см. ниже пример установки стратегии агрегации программно).Атрибут
valueDescription
задает текст всплывающей подсказки, отображаемой при наведении курсора мыши по агрегированному значению. Для операций, перечисленных выше (SUM
,AVG
,COUNT
,MIN
,MAX
), всплывающие подсказки уже есть по умолчанию.Для отображения агрегированного значения в виде, отличном от стандартного для данного Datatype, для него можно указать Formatter:
<column id="amount"> <aggregation type="SUM"> <formatter class="com.company.sample.MyFormatter"/> </aggregation> </column>
Атрибут
aggregationStyle
позволяет задать положение строки агрегации:TOP
илиBOTTOM
. По умолчанию используетсяTOP
.В дополнение к операциям, перечисленным выше, можно задать собственную стратегию агрегации путем создания класса, реализующего интерфейс
AggregationStrategy
, и передачи его методуsetAggregation()
классаTable.Column
в составе экземпляраAggregationInfo
. Например:public class TimeEntryAggregation implements AggregationStrategy<List<TimeEntry>, String> { @Override public String aggregate(Collection<List<TimeEntry>> propertyValues) { HoursAndMinutes total = new HoursAndMinutes(); for (List<TimeEntry> list : propertyValues) { for (TimeEntry timeEntry : list) { total.add(HoursAndMinutes.fromTimeEntry(timeEntry)); } } return StringFormatHelper.getTotalDayAggregationString(total); } @Override public Class<String> getResultClass() { return String.class; } }
AggregationInfo info = new AggregationInfo(); info.setPropertyPath(metaPropertyPath); info.setStrategy(new TimeEntryAggregation()); Table.Column column = weeklyReportsTable.getColumn(columnId); column.setAggregation(info);
-
-
Атрибут
editable
позволяет перевести таблицу в режим in-place редактирования ячеек. В этом режиме в колонках, имеющих атрибутeditable = true
, отображаются компоненты для редактирования значений атрибутов сущности, находящейся в источнике данных.Тип компонента для каждой редактируемой колонки выбирается автоматически на основании типа атрибута сущности. Например, для строковых и числовых атрибутов используется TextField, для
Date
- DateField, для перечислений - LookupField, для ссылок на другие сущности - PickerField.Для редактируемой колонки типа
Date
можно дополнительно указать атрибутыdateFormat
илиresolution
аналогично описанным для DateField.Для редактируемой колонки, отображающей связанную сущность, можно дополнительно указать атрибуты optionsContainer и captionProperty. При указании
optionsContainer
вместо PickerField используется компонент LookupField.Произвольно настроить отображение ячеек, в том числе для редактирования содержимого, можно с помощью метода
Table.addGeneratedColumn()
- см. ниже.
-
В веб-клиенте с темой, основанной на Halo, атрибут
stylename
позволяет применять к таблице предопределенные стилиTable
. Стили задаются в XML-дексрипторе или контроллере экрана с помощью атрибутаstylename
:<table id="table" dataContainer="itemsDc" stylename="no-stripes"> <columns> <column id="product"/> <column id="quantity"/> </columns> </table>
Чтобы применить стиль программно, выберите одну из констант класса
HaloTheme
с префиксом компонентаTABLE_
:table.setStyleName(HaloTheme.TABLE_NO_STRIPES);
- Стили компонента Table
-
borderless
- удаляет внешнюю рамку таблицы.
-
compact
- уменьшает отступы внутри ячеек таблицы.
-
no-header
- скрывает заголовки таблицы.
-
no-horizontal-lines
- удаляет горизонтальные строковые разделители.
-
no-stripes
- отключает чередование цветов строк таблицы.
-
no-vertical-lines
- удаляет вертикальные разделители столбцов.
-
small
- уменьшает размер шрифта и отступы внутри ячеек таблицы.
Методы интерфейса Table
-
метод
addColumnCollapsedListener
() позволяет отслеживать видимость колонок таблицы с помощью интерфейса слушателяColumnCollapsedListener
.
-
getSelected()
,getSingleSelected()
- возвращают экземпляры сущностей, соответствующие выделенным в таблице строкам. Коллекцию можно получить вызовом методаgetSelected()
. Если ничего не выбрано, возвращается пустой набор. Еслиmultiselect
отключен, удобно пользоваться методомgetSingleSelected()
, возвращающим одну выбранную сущность илиnull
, если ничего не выбрано.
-
addSelectionListener()
- позволяет отслеживать выделение строк таблицы, например:customersTable.addSelectionListener(customerSelectionEvent -> notifications.create() .withCaption("You selected " + customerSelectionEvent.getSelected().size() + " customers") .show());
Также отслеживание изменений можно реализовать, подписавшись на соответствующее событие:
@Subscribe("customersTable") protected void onCustomersTableSelection(Table.SelectionEvent<Customer> event) { notifications.create() .withCaption("You selected " + customerSelectionEvent.getSelected().size() + " customers") .show(); }
Источник события
SelectionEvent
можно отследить с помощью метода isUserOriginated().
-
Метод
addGeneratedColumn()
позволяет задать собственное представление данных в колонке. Он принимает два параметра: идентификатор колонки и реализацию интерфейсаTable.ColumnGenerator
. Идентификатор может совпадать с одним из идентификаторов, указанных для колонок таблицы в XML-дескрипторе - в этом случае новая колонка вставляется вместо заданной в XML. Если идентификатор не совпадает ни с одной колонкой, создается новая справа.Метод
generateCell()
интерфейсаTable.ColumnGenerator
вызывается таблицей для каждой строки, и в него передается экземпляр сущности, отображаемой в данной строке. МетодgenerateCell()
должен вернуть визуальный компонент, который и будет отображаться в ячейке.Пример использования:
@Inject private GroupTable<Car> carsTable; @Inject private CollectionContainer<Car> carsDc; @Inject private CollectionContainer<Color> colorsDc; @Inject private UiComponents uiComponents; @Inject private Actions actions; @Subscribe protected void onInit(InitEvent event) { carsTable.addGeneratedColumn("color", entity -> { LookupPickerField<Color> field = uiComponents.create(LookupPickerField.NAME); field.setValueSource(new ContainerValueSource<>(carsTable.getInstanceContainer(entity), "color")); field.setOptions(new ContainerOptions<>(colorsDc)); field.addAction(actions.create(LookupAction.class)); field.addAction(actions.create(OpenAction.class)); return field; }); }
В данном случае в ячейках колонки
color
таблицы отображается компонент LookupPickerField. Компонент будет сохранять свое значение в атрибутcolor
сущности, экземпляр которой отображается в данной строке.Метод
getInstanceContainer()
, возвращающий контейнер с текущим экземпляром сущности, должен использоваться только в data binding компонентов, создаваемых при генерации ячеек таблицы.Если в ячейке необходимо отобразить просто динамически сформированный текст, вместо компонента Label используйте класс
Table.PlainTextCell
. Это упростит отрисовку и сделает таблицу быстрее.Если в метод
addGeneratedColumn()
передан идентификатор колонки, не объявленной в XML-дескрипторе, то может понадобиться установить заголовок новой колонки следующим образом:carsTable.getColumn("colour").setCaption("Colour");
Существует также более декларативный подход, использующий XML-атрибут generator.
-
Метод
requestFocus()
позволяет установить фокус на определенное поле конкретной записи. Принимает два параметра: экземпляр сущности, определяющий строку и идентификатор колонки. Пример программной установки фокуса:table.requestFocus(item, "count");
-
Метод
scrollTo()
позволяет программно прокрутить таблицу до нужной записи. Метод принимает экземпляр сущности, определяющий нужную строку в таблице.Пример использования метода:
table.scrollTo(item);
-
Метод
setCellClickListener()
может избавить от необходимости добавлять генерируемые колонки с компонентами, если нужно нарисовать что-либо в ячейках и получать оповещения когда пользователь кликает на эти ячейки. Имплементация классаCellClickListener
, передаваемая в данный метод, получает текущий экземпляр сущности и идентификатор колонки. Содержимое ячеек будет завернуто в элементspan
со стилемcuba-table-clickable-cell
, который можно использовать для задания отображения ячеек.Пример использования
CellClickListener
:@Inject private Table<Customer> customersTable; @Inject private Notifications notifications; @Subscribe protected void onInit(InitEvent event) { customersTable.setCellClickListener("name", customerCellClickEvent -> notifications.create() .withCaption(customerCellClickEvent.getItem().getName()) .show()); }
-
С помощью метода
setAggregationDistributionProvider()
можно задать провайдерAggregationDistributionProvider
, определяющий правила распределения агрегированного значения между ячейками таблицы. Если пользователь вводит значение в агрегированную ячейку, оно распределяется по составляющим ячейкам в соответствии с кастомным алгоритмом. Алгоритм может учитывать и существующие значения ячеек. Поддерживается только для стиля агрегацииTOP
. Для того чтобы сделать агрегированные ячейки редактируемыми, используйте атрибут editable элементаaggregation
.При создании провайдера используется объект
AggregationDistributionContext<E>
, который содержит данные, необходимые для распределения агрегируемого значения:-
Column column
− колонка, в которой произошло изменение значения в общей или групповой агрегации; -
Object value
− новое значение агрегации; -
Collection<E> scope
− коллекция сущностей, на которые повлияет изменение значения агрегации; -
boolean isTotalAggregation
указывает, в какой агрегации произошли изменения: в общей или групповой.В качестве примера рассмотрим таблицу, представляющую бюджет. Пользователь создает категории бюджета и задает для каждой из них проценты, в соответствии с которыми должна распределяться сумма дохода. Далее в агрегируемой ячейке указывается общая сумма дохода, после чего происходит распределение по категориям.
Пример описания в дескрипторе:
<table id="budgetItemsTable" width="100%" dataContainer="budgetItemsDc" aggregatable="true" editable="true" showTotalAggregation="true"> ... <columns> <column id="category"/> <column id="percent"/> <column id="sum"> <aggregation editable="true" type="SUM"/> </column> </columns> ... </table>
Реализация в контроллере:
budgetItemsTable.setAggregationDistributionProvider(context -> { Collection<BudgetItem> scope = context.getScope(); if (scope.isEmpty()) { return; } double value = context.getValue() != null ? ((double) context.getValue()) : 0; for (BudgetItem budgetItem : scope) { budgetItem.setSum(value / 100 * budgetItem.getPercent()); } });
-
-
Метод
getAggregationResults()
возвращает мэп с результатами агрегации, где ключи в мэп − идентификаторы столбцов таблицы, а значения − значения агрегации.
-
Метод
setStyleProvider()
позволяет задать стиль отображения ячеек таблицы. Параметром метода должна быть реализация интерфейсаTable.StyleProvider
. МетодgetStyleName()
этого интерфейса вызывается таблицей отдельно для каждой строки и для каждой ячейки. Если метод вызван для строки, то первый параметр содержит экземпляр сущности, отображаемый этой строкой, а второй параметрnull
. Если же метод вызван для ячейки, то второй параметр содержит имя атрибута, отображаемого этой ячейкой.Пример задания стилей:
@Inject protected Table customersTable; @Subscribe protected void onInit(InitEvent event) { customersTable.setStyleProvider((customer, property) -> { if (property == null) { // style for row if (hasComplaints(customer)) { return "unsatisfied-customer"; } } else if (property.equals("grade")) { // style for column "grade" switch (customer.getGrade()) { case PREMIUM: return "premium-grade"; case HIGH: return "high-grade"; case MEDIUM: return "medium-grade"; default: return null; } } return null; }); }
Далее нужно определить заданные для строк и ячеек стили в теме приложения. Подробная информация о создании темы находится в Создание темы приложения. Для веб-клиента новые стили определяются в файле
styles.scss
. Имена стилей, заданные в контроллере, совместно с префиксами, обозначающими строку или колонку таблицы, образуют CSS-селекторы. Например:.v-table-row.unsatisfied-customer { font-weight: bold; } .v-table-cell-content.premium-grade { background-color: red; } .v-table-cell-content.high-grade { background-color: green; } .v-table-cell-content.medium-grade { background-color: blue; }
-
Метод
addPrintable()
позволяет задать специфическое представление данных колонки при выводе в XLS-файл, осуществляемом стандартным действиемexcel
или напрямую с помощью классаExcelExporter
. Метод принимает идентификатор колонки и реализацию интерфейсаTable.Printable
для нее. Например:ordersTable.addPrintable("customer", new Table.Printable<Customer, String>() { @Override public String getValue(Customer customer) { return "Name: " + customer.getName; } });
Метод
getValue()
интерфейсаTable.Printable
должен возвращать данные, которые будут находиться в ячейке таблицы. Это может быть не только строка - метод может возвращать значения других типов, например, числовые данные или даты, и они будут представлены в XLS-файле соответствующим образом.Если форматированный вывод в XLS необходим для генерируемой колонки, нужно использовать реализацию интерфейса
Table.PrintableColumnGenerator
, передавая ее методуaddGeneratedColumn()
. Значение для вывода в ячейку XLS-документа задается в методеgetValue()
этого интерфейса:ordersTable.addGeneratedColumn("product", new Table.PrintableColumnGenerator<Order, String>() { @Override public Component generateCell(Order entity) { Label label = uiComponents.create(Label.NAME); Product product = order.getProduct(); label.setValue(product.getName() + ", " + product.getCost()); return label; } @Override public String getValue(Order entity) { Product product = order.getProduct(); return product.getName() + ", " + product.getCost(); } });
Если генерируемой колонке тем или иным способом не задано представления
Printable
, то в случае, если колонке соответствует атрибут сущности, будет выведено его значение, в противном случае не будет выведено ничего.
-
Метод
setItemClickAction()
позволяет задать действие, выполняемое при двойном клике на строке таблицы. Если такое действие не задано, при двойном клике таблица пытается найти среди своих действий подходящее в следующем порядке:-
Действие, назначенное на клавишу Enter посредством свойства
shortcut
. -
Действие с именем
edit
. -
Действие с именем
view
.Если такое действие найдено и имеет свойство
enabled = true
, оно выполняется.
-
-
Метод
setEnterPressAction()
позволяет задать действие, выполняемое при нажатии клавиши Enter. Если такое действие не задано, таблица пытается найти среди своих действий подходящее в следующем порядке:-
Действие, назначенное методом
setItemClickAction()
. -
Действие, назначенное на клавишу Enter посредством свойства
shortcut
. -
Действие с именем
edit
. -
Действие с именем
view
.
Если такое действие найдено и имеет свойство
enabled = true
, оно выполняется. -
-
setEmptyStateLinkClickHandler
позволяет задать обработчик, который будет вызван после нажатия на гиперссылку в сообщении, установленном в атрибуте emptyStateLinkMessage:@Subscribe public void onInit(InitEvent event) { customersTable.setEmptyStateLinkClickHandler(emptyStateClickEvent -> screenBuilders.editor(emptyStateClickEvent.getSource()) .newEntity() .show()); }
-
Метод
setItemDescriptionProvider
задает провайдер, служащий для генерации всплывающих подсказок для ячеек таблицы.В приведенном ниже примере мы покажем использование метода
setItemDescriptionProvider
для таблицыdepartmentsTable
. СущностьDepartment
имеет три атрибута:name
,active
,parentDept
.@Inject private Table<Department> departmentsTable; @Subscribe public void onInit(InitEvent event) { departmentsTable.setItemDescriptionProvider(((department, property) -> { if (property == null) { (1) if (department.getParentDept() == null) { return "Parent Department"; } } else if (property.equals("active")) { (2) return department.getActive() ? "Active department" : "Inactive department"; } return null; })); }
1 – описание для строки. 2 – описание для колонки "active".
Внешний вид компонента Table
можно настроить с помощью переменных SCSS с префиксом $cuba-table-*
. Эти переменные можно изменить в визуальном редакторе после расширения темы или создания новой темы.
- Атрибуты table
-
align - aggregatable - aggregationStyle - caption - captionAsHtml - columnControlVisible - columnHeaderVisible - contextHelpText - contextHelpTextHtmlEnabled - contextMenuEnabled - css - dataContainer - description - descriptionAsHtml - editable - emptyStateLinkMessage - emptyStateMessage - enable - box.expandRatio - height - htmlSanitizerEnabled - id - metaClass - multiLineCells - multiselect - presentations - reorderingAllowed - settingsEnabled - showSelection - sortable - stylename - tabIndex - textSelectionEnabled - visible - width
- Элементы table
-
actions - buttonsPanel - columns - rows - rowsCount
- Атрибуты columns
- Атрибуты column
-
align - caption - captionAsHtml - captionProperty - collapsed - dateFormat - editable - expandRatio - generator - id - link - linkInvoke - linkScreen - linkScreenOpenType - maxTextLength - optionsContainer - resolution - sort - sortable - visible - width
- Элементы column
- Атрибуты aggregation
- Предопределенные стили table
-
borderless - compact - no-header - no-horizontal-lines - no-stripes - no-vertical-lines - small
- API
-
addGeneratedColumn - addPrintable - addColumnCollapseListener - addSelectionListener - applySettings - generateCell - getAggregationResults - getSelected - requestFocus - saveSettings - scrollTo - setAggregationDistributionProvider - setClickListener - setEmptyStateLinkClickHandler - setEnterPressAction - setItemClickAction - setItemDescriptionProvider - setStyleProvider