4.5.2.1.25. Table
Компонент 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которого необходимо объявить используемый таблицей источник данных.Для строк можно настроить отображение заголовков - задать каждой строке свой значок в дополнительной колонке слева. Для этого в контроллере экрана необходимо реализовать интерфейс
ListComponent.IconProviderи установить его таблице:@Inject private Table<Customer> table; @Override public void init(Map<String, Object> params) { 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- обязательный элемент, определяет набор колонок таблицы.Каждая колонка описывается во вложенном элементе
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.
-
sortable− необязательный атрибут, позволяющий запретить сортировку колонки. Вступает в действие, если атрибут sortable всей таблицы установлен вtrue(что имеет место по умолчанию).
-
maxTextLength- необязательный атрибут, позволяет ограничивать количество символов в ячейке. При этом если разница между фактическим и допустимым количеством символов не превышает порог в 10 символов, "лишние" символы не скрываются. Для просмотра полной записи надо кликнуть на ее видимую часть. Пример колонки с ограничением в 5 символов:
-
link- установка атрибута вtrueпозволяет отобразить в ячейке таблицы ссылку на экран просмотра экземпляра сущности (поддерживается только для Web Client). Атрибутlink="true") может указываться и для колонок примитивных типов: в этом случае, при нажатии на ссылку будет открываться редактор основной сущности таблицы. Такой подход может применяться для упрощения навигации - пользователи смогут открывать редактор одним кликом по некоторому ключевому атрибуту.
-
linkScreen- позволяет указать идентификатор экрана, который будет открыт по нажатию на ссылку, включенную свойствомlink.
-
linkScreenOpenType- задает режим открытия экрана (THIS_TAB,NEW_TABилиDIALOG).
-
linkInvoke- позволяет заменить открытие окна на вызов метода контроллера.
-
captionProperty- имя атрибута сущности, который должен быть отображен в колонке вместо указанного в id. Например, если имеется связанная сущностьPriorityс атрибутамиnameиorderNo, можно определить следующую колонку:<column id="priority.orderNo" captionProperty="priority.name" caption="msg://priority" />В этом случае в колонке будет отображаться название приоритета, а сортировка колонки будет осуществляться по атрибуту
orderNo. -
Элемент
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.
Атрибуты table:
-
Атрибут
multiselectпозволяет задать режим множественного выделения строк в таблице. Еслиmultiselectравенtrue, то пользователь может выделить несколько строк с помощью клавиатуры или мыши, удерживая клавиши Ctrl или Shift. По умолчанию режим множественного выделения отключен.
-
Атрибут
sortableразрешает или запрещает сортировку в таблице. По умолчанию имеет значениеtrue. Если сортировка разрешена, то при нажатии на название колонки справа от названия появляется значок
/
. Сортировку некоторой отдельной колонки можно запретить с помощью атрибута sortable этой колонки.При включенной с помощью элемента
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. Если такой параметр не указан, то сортировка производится в памяти только в пределах текущей страницы.Если таблица соединена со вложенным источником данных, который содержит коллекцию связанных сущностей, то для того, чтобы таблицу можно было сортировать, атрибут-коллекция должен быть упорядоченного типа (
ListилиLinkedHashSet). Если атрибут имеет типSet, то атрибутsortableне оказывает влияния и пользователи не смогут сортировать таблицу.
-
Атрибут
presentationsуправляет механизмом представлений. Значение по умолчанию равноfalse. Когда значение атрибута равноtrue, то в верхнем правом углу таблицы появляется значок
. Механизм представлений реализован только для блока Web Client.
-
Установка атрибута
columnControlVisibleвfalseзапрещает пользователю скрывать колонки с помощью меню, выпадающего при нажатия на кнопку
в правой части шапки таблицы. Флажками в меню отмечаются отображаемые в данный момент колонки.
-
Установка атрибута
reorderingAllowedвfalseзапрещает пользователю менять местами колонки, перетаскивая их с помощью мыши.
-
Установка атрибута
columnHeaderVisibleвfalseскрывает заголовок таблицы.
-
При установленном в
falseатрибутеshowSelectionтекущая строка не имеет выделения.
-
Атрибут
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>Атрибут
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.Для редактируемой колонки, отображающей связанную сущность, можно дополнительно указать атрибуты 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; } }); }Далее нужно определить заданные для строк и ячеек стили в теме приложения. Подробная информация о создании темы находится в Создание темы приложения. Для веб-клиента новые стили определяются в файле
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
-
align - aggregatable - aggregationStyle - columnControlVisible - columnHeaderVisible - contextMenuEnabled - editable - enable - height - id - multiLineCells - multiselect - presentations - reorderingAllowed - showSelection - sortable - stylename - visible - width
- Элементы table
-
actions - buttonsPanel - columns - rows - rowsCount
- Атрибуты column
-
align - caption - captionProperty - collapsed - dateFormat - editable - id - link - linkInvoke - linkScreen - linkScreenOpenType - maxTextLength - optionsDatasource - resolution - sortable - visible - width
- Элементы column
- Атрибуты rows