Компонент Table
позволяет выводить информацию в табличном виде, сортировать данные, управлять колонками и заголовками таблицы, вызывать действия
для выбранных строк.
XML-имя компонента: table
Компонент реализован для блоков Web Client и Desktop Client.
Пример описания таблицы в XML-дескрипторе экрана:
<dsContext> <collectionDatasource id="ordersDs" class="com.sample.sales.entity.Order" view="orderWithCustomer"> <query> select o from sales$Order o order by o.date </query> </collectionDatasource> </dsContext> <layout> <table id="ordersTable" width="300px"> <columns> <column id="date"/> <column id="customer.name"/> <column id="amount"/> </columns> <rows datasource="ordersDs"/> </table>
Здесь в элементе dsContext
определен источник данных collectionDatasource
, который выбирает сущности Order
с помощью JPQL запроса
select o from sales$Order o order by o.date
. Для компонента table
в элементе rows
указывается используемый источник данных, а в элементе columns
- какие атрибуты сущности, содержащейся в источнике данных, использовать в качестве колонок.
Элементы table
:
-
rows
- обязательный элемент, в атрибутеdatasource
которого необходимо объявить используемый таблицей источник данных.Для строк можно настроить отображение заголовков - задать каждой строке свой значок в дополнительной колонке слева. Для этого в контроллере экрана необходимо реализовать интерфейс
Table.IconProvider
и установить его таблице:@Inject protected Table customersTable; ... customersTable.setIconProvider(new Table.IconProvider() { @Nullable @Override public String getItemIcon(Entity entity) { CustomerGrade grade = ((Customer) 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
- обязательный элемент, определяет набор колонок таблицы.Каждая колонка описывается во вложенном элементе
column
со следующими атрибутами:-
id
− обязательный атрибут, содержит название атрибута сущности, выводимого в колонке. Может быть как непосредственным атрибутом сущности, находящейся в источнике данных, так и атрибутом связанной сущности - переход по графу объектов обозначается точкой. Например:<columns> <column id="date"/> <column id="customer"/> <column id="customer.name"/> <column id="customer.address.country"/> </columns>
-
caption
− необязательный атрибут, содержит заголовок колонки. Если не задан, будет отображено локализованное название атрибута сущности. -
collapsed
− необязательный атрибут, при указанииtrue
колонка будет изначально скрыта. Пользователь может управлять отображением колонок с помощью меню, доступного по кнопке в правой верхней части таблицы, если атрибутcolumnControlVisible
таблицы неfalse
. По умолчаниюcollapsed
имеет значениеfalse
. -
width
− необязательный атрибут, отвечает за изначальную ширину колонки. -
align
- необязательный атрибут, устанавливает выравнивание текста в ячейках данной колонки. Возможные значения:LEFT
,RIGHT
,CENTER
. По умолчаниюLEFT
. -
editable
− необязательный атрибут, разрешает/запрещает редактирование данной колонки в редактируемой таблице. Чтобы колонка была редактируемой, атрибутeditable
всей таблицы (см. ниже) также должен быть установлен вtrue
. -
maxTextLength
- необязательный атрибут, позволяет ограничивать количество символов в ячейке. При этом если разница между фактическим и допустимым количеством символов не превышает порог в 10 символов, "лишние" символы не скрываются. Для просмотра полной записи надо кликнуть на ее видимую часть. Пример колонки с ограничением в 5 символов: -
link
- установка атрибута вtrue
позволяет отобразить в ячейке таблицы ссылку на экран просмотра экземпляра сущности (поддерживается только для Web Client). Атрибутlink="true"
) может указываться и для колонок примитивных типов: в этом случае, при нажатии на ссылку будет открываться редактор основной сущности таблицы. Такой подход может применяться для упрощения навигации - пользователи смогут открывать редактор одним кликом по некоторому ключевому атрибуту. -
linkScreen
- позволяет указать идентификатор экрана, который будет открыт по нажатию на ссылку, включенную свойствомlink
. -
linkScreenOpenType
- задает режим открытия экрана (THIS_TAB
,NEW_TAB
илиDIALOG
). -
linkInvoke
- позволяет заменить открытие окна на вызов метода контроллера. -
Элемент
column
может содержать вложенный элемент formatter для представления значения атрибута в виде, отличном от стандартного для данного Datatype:<column id="date"> <formatter class="com.haulmont.cuba.gui.components.formatters.DateFormatter" format="yyyy-MM-dd HH:mm:ss"/> </column>
-
-
rowsCount
− необязательный элемент, создающий для таблицы компонентRowsCount
, который позволяет загружать в таблицу данные постранично. Размер страницы задается путем ограничения количества записей в источнике данных методомCollectionDatasource.setMaxResults()
. Как правило, это делает связанный с источником данных таблицы компонент Filter, однако при отсутствии универсального фильтра можно вызвать этот метод и напрямую из контроллера экрана.Компонент
RowsCount
может также отобразить общее число записей, возвращаемых текущим запросом в источнике данных, без извлечения этих записей. Для этого при щелчке пользователя на знаке "?" он вызывает методAbstractCollectionDatasource.getCount()
, что приводит к выполнению в БД запроса с такими же, как у текущего запроса условиями, но с агрегатной функциейCOUNT(*)
вместо результатов. Полученное число отображается вместо знака "?". -
actions
− необязательный элемент для описания действий, связанных с таблицей. Кроме описания произвольных действия поддерживаются следующие стандартные действия, определяемые перечислениемListActionType
:create
,edit
,remove
,refresh
,add
,exclude
,excel
. -
buttonsPanel
- необязательный элемент, создающий над таблицей контейнер ButtonsPanel для отображения кнопок действий.
Атрибуты table
:
-
Атрибут
multiselect
позволяет задать режим множественного выделения строк в таблице. Еслиmultiselect
равенtrue
, то пользователь может выделить несколько строк с помощью клавиатуры или мыши, удерживая клавиши Ctrl или Shift. По умолчанию режим множественного выделения отключен. -
Атрибут
sortable
разрешает или запрещает сортировку в таблице. По умолчанию имеет значениеtrue
. Если сортировка разрешена, то при нажатии на название колонки справа от названия появляется значок /.При включенной с помощью элемента
rowsCount
(см. выше) страничной загрузке таблицы сортировка производится разными способами в зависимости от того, умещаются ли все записи на одной странице. Если умещаются, то сортировка производится в памяти, без обращений к БД. Если же страниц больше одной, то сортировка производится на базе данных путем отправки нового запроса с соответствующимORDER BY
.Колонка таблицы может ссылаться на локальный атрибут или на связанную сущность. Например:
<table id="ordersTable"> <columns> <column id="customer.name"/> <!-- the 'name' attribute of the 'Customer' entity --> <column id="contract"/> <!-- the 'Contract' entity --> </columns> <rows datasource="ordersDs"/> </table>
В последнем случае, сортировка на базе данных производится по атрибутам, указанным в аннотации
@NamePattern
связанной сущности. Если у связанной сущности нет такой аннотации, то сортировка производится в памяти только в пределах текущей страницы.Если колонка таблицы ссылается на неперсистентный атрибут, то сортировка на базе данных производится по атрибутам, указанным в параметре
related()
аннотации@MetaProperty
. Если такой параметр не указан, то сортировка производится в памяти только в пределах текущей страницы. -
Атрибут
presentations
управляет механизмом представлений. Значение по умолчанию равноfalse
. Когда значение атрибута равноtrue
, то в верхнем правом углу таблицы появляется значок . Механизм представлений реализован только для блока Web Client. -
Установка атрибута
columnControlVisible
вfalse
запрещает пользователю скрывать колонки с помощью меню, выпадающего при нажатия на кнопку в правой части шапки таблицы. Флажками в меню отмечаются отображаемые в данный момент колонки. -
Установка атрибута
reorderingAllowed
вfalse
запрещает пользователю менять местами колонки, перетаскивая их с помощью мыши. -
Атрибут
contextMenuEnabled
разрешает или запрещает показывать контекстное меню. По умолчанию атрибут имеет значениеtrue
. В контекстном меню отображаются действия таблицы (если они есть), и пункт , содержащий информацию о выбранной сущности (если у пользователя есть разрешениеcuba.gui.showInfo
, см. руководство по подсистеме безопасности). -
Если атрибуту
multiLineCells
таблицы присвоить значениеtrue
, то ячейки, содержащие текст с переносами строк, будут отображать его в несколько строк. В таком режиме в веб клиенте для правильной работы полосы прокрутки все строки текущей страницы таблицы будут загружены веб-браузером сразу, без ленивой загрузки видимой части таблицы. По умолчанию атрибут имеет значениеfalse
. -
Атрибут
aggregatable
включает режим агрегации строк таблицы. Поддерживаются следующие операции:-
SUM
- сумма -
AVG
- среднее значение -
COUNT
- количество -
MIN
- минимальное значение -
MAX
- максимальное значение
Для агрегируемых колонок необходимо указать элемент
aggregation
с атрибутомtype
, задающим функцию агрегации. Агрегированные значения столбцов выводятся в дополнительной строке вверху таблицы. Пример описания таблицы с агрегацией:<table id="itemsTable" aggregatable="true"> <columns> <column id="product"/> <column id="quantity"/> <column id="amount"> <aggregation type="SUM"/> </column> </columns> <rows datasource="itemsDs"/> </table>
Для отображения агрегированного значения в виде, отличном от стандартного для данного Datatype, для него можно указать Formatter:
<column id="amount"> <aggregation type="SUM"> <formatter class="com.company.sample.MyFormatter"/> </aggregation> </column>
В дополнение к операциям, перечисленным выше, можно задать собственную стратегию агрегации путем создания класса, реализующего интерфейс
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.Для редактируемой колонки, отображающей связанную сущность, можно дополнительно указать атрибуты optionsDatasource и captionProperty. При указании
optionsDatasource
вместо PickerField используется компонент LookupField.Произвольно настроить отображение ячеек, в том числе для редактирования содержимого, можно с помощью метода
Table.addGeneratedColumn()
- см. ниже.
Методы интерфейса Table
:
-
getSelected()
,getSingleSelected()
- возвращают экземпляры сущностей, соответствующие выделенным в таблице строкам. Коллекцию можно получить вызовом методаgetSelected()
. Если ничего не выбрано, возвращается пустой набор. Еслиmultiselect
отключен, удобно пользоваться методомgetSingleSelected()
, возвращающим одну выбранную сущность илиnull
, если ничего не выбрано. -
Метод
addGeneratedColumn()
позволяет задать собственное представление данных в колонке. Он принимает два параметра: идентификатор колонки и реализацию интерфейсаTable.ColumnGenerator
. Идентификатор может совпадать с одним из идентификаторов, указанных для колонок таблицы в XML-дескрипторе - в этом случае новая колонка вставляется вместо заданной в XML. Если идентификатор не совпадает ни с одной колонкой, создается новая справа.Метод
generateCell()
интерфейсаTable.ColumnGenerator
вызывается таблицей для каждой строки, и в него передается экземпляр сущности, отображаемой в данной строке. МетодgenerateCell()
должен вернуть визуальный компонент, который и будет отображаться в ячейке.Пример использования:
@Inject protected Table carsTable; @Inject protected ComponentsFactory componentsFactory; @Override public void init(Map<String, Object> params) { carsTable.addGeneratedColumn("colour", new Table.ColumnGenerator() { @Override public Component generateCell(Entity entity) { LookupPickerField field = componentsFactory.createComponent(LookupPickerField.NAME); field.setDatasource(carsTable.getItemDatasource(entity), "colour"); field.setOptionsDatasource(coloursDs); field.addLookupAction(); field.addOpenAction(); return field; } }); }
В данном случае в ячейках колонки
colour
таблицы отображается компонент LookupPickerField. Компонент должен сохранять свое значение в атрибутcolour
сущности, экземпляр которой отображается в данной строке. Для этого у таблицы методомgetItemDatasource()
запрашивается источник данных для текущего экземпляра сущности, и передается компонентуLookupPickerField
.Если в ячейке необходимо отобразить просто динамически сформированный текст, вместо компонента Label используйте класс
Table.PlainTextCell
. Это упростит отрисовку и сделает таблицу быстрее.Если в метод
addGeneratedColumn()
передан идентификатор колонки, не объявленной в XML-дескрипторе, то может понадобиться установить заголовок новой колонки следующим образом:carsTable.getColumn("colour").setCaption("Colour");
-
Метод
setClickListener()
может избавить от необходимости добавлять генерируемые колонки с компонентами, если нужно нарисовать что-либо в ячейках и получать оповещения когда пользователь кликает на эти ячейки. Имплементация классаCellClickListener
, передаваемая в данный метод, получает текущий экземпляр сущности и идентификатор колонки. Содержимое ячеек будет завернуто в элементspan
со стилемcuba-table-clickable-cell
, который можно использовать для задания отображения ячеек. -
Метод
setStyleProvider()
позволяет задать стиль отображения ячеек таблицы. Параметром метода должна быть реализация интерфейсаTable.StyleProvider
. МетодgetStyleName()
этого интерфейса вызывается таблицей отдельно для каждой строки и для каждой ячейки. Если метод вызван для строки, то первый параметр содержит экземпляр сущности, отображаемый этой строкой, а второй параметрnull
. Если же метод вызван для ячейки, то второй параметр содержит имя атрибута, отображаемого этой ячейкой.Пример задания стилей:
@Inject protected Table customersTable; @Override public void init(Map<String, Object> params) { customersTable.setStyleProvider(new Table.StyleProvider() { @Nullable @Override public String getStyleName(Entity entity, @Nullable String property) { Customer customer = (Customer) entity; 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; } }); }
Далее нужно определить заданные для строк и ячеек стили в теме приложения. Подробная информация о создании темы находится вРаздел 4.5.7, «Создание темы приложения». Для веб-клиента новые стили определяются в файле
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 = componentsFactory.createComponent(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, оно выполняется.
-
Атрибуты table
:
allowPopupMenu | enable | multiselect | stylename |
columnControlVisible | height | presentations | visible |
description | id | reorderingAllowed | width |
editable | margin | sortable |
Элементы table
:
Атрибуты column:
caption | dateFormat | linkInvoke | optionsDatasource |
captionProperty | editable | linkScreen | resolution |
clickAction | id | linkScreenOpenType | visible |
collapsed | link | maxTextLength | width |
Элементы column:
Атрибуты rows: