My groupTable has a boolean column with generator which shows an icon label when the boolean value is true and I want to show the same icon in aggregated rows when at least one child row has true value. I created an AggregationStrategy class where tried to create the icon label but it appears that CUBA aggregation mechanism can work with simple types only (String, Long, Double etc.). I tried the class method to return a string wth “img” html tag ("<img src=’/VAADIN/themes/icons/someicon.png’>") but got the string in aggregation cell, not icon.
Is there a method to do what I want?
CUBA 6.10.9
Hello @evgenypopov
In fact there is a tricky way to do it. Let’s assume that we have the following entity.
// Simplified view
public class TestEntity extends StandardEntity {
protected String name;
protected Integer num;
protected Boolean truth = Boolean.FALSE;
}
Generate a generic browser and add few changes for table:
<groupTable id="testEntitiesTable"
aggregatable="true"
width="100%"
dataContainer="testEntitiesDc">
<actions>
...
</actions>
<columns>
<column id="name"/>
<!-- Generated column -->
<column id="truthTick"
caption="Truth"/>
<column id="num">
<aggregation type="SUM"/>
</column>
</columns>
<rowsCount/>
<buttonsPanel id="buttonsPanel"
alwaysVisible="true">
...
</buttonsPanel>
</groupTable>
Add simple column generator:
@Install(to = "testEntitiesTable.truthTick", subject = "columnGenerator")
private Component testEntitiesTableTruthTickColumnGenerator(TestEntity testEntity) {
Label<String> iconLabel = uiComponents.create(Label.TYPE_STRING);
if (Boolean.TRUE.equals(testEntity.getTruth())) {
iconLabel.setIconFromSet(CubaIcon.CHECK);
}
return iconLabel;
}
Now we’ll implement check icon for aggregation cell. The idea is based on ability to find element with not empty content via CSS selector, hide its content and add pseudo element with an icon.
First of all let’s add aggregation strategy for generated column:
@Subscribe
private void onInit(InitEvent event) {
// Setup custom aggregation
Table.Column<TestEntity> column = testEntitiesTable.getColumn("truthTick");
column.setAggregation(getAggregationInfo());
}
private AggregationInfo getAggregationInfo() {
AggregationStrategy<TestEntity, String> strategy =
new AggregationStrategy<TestEntity, String>() {
@Override
public String aggregate(Collection<TestEntity> propertyValues) {
boolean truth = propertyValues.stream()
.anyMatch(e -> Boolean.TRUE.equals(e.getTruth()));
// Return not empty value to filter cells in CSS
return truth ? "True" : null;
}
@Override
public Class<String> getResultClass() {
return String.class;
}
};
AggregationInfo aggregationInfo = new AggregationInfo();
aggregationInfo.setStrategy(strategy);
return aggregationInfo;
}
To avoid affecting other cells add style provider:
testEntitiesTable.setStyleProvider((entity, property) ->
"truthTick".equals(property) ? "truth" : null);
The last step is to extend hover
theme and add custom rules:
/* The selector matches all aggregation cells with marker class and not empty content */
.v-table-arow-row .v-table-cell-content.truth-ag .v-table-cell-wrapper:not(:empty) {
/* Hide marker value */
color: transparent;
/* Show an icon */
&::before {
content: "\f00c";
color: $v-font-color;
font-family: FontAwesome;
}
}
And final result:
Please consider demo project:
boolean-aggregation.zip (11.3 MB)
Regards,
Daniil
P.S.: sample is based on CUBA 7 API, but all functionality is also available in CUBA 6
Thanks Daniil, it works fine with simple aggregation but I have 2 grouping columns with partial aggregation ang got required icon in total aggregation row only and “True” strings instead of icons in partial aggregation cells of the boolean column.
I tried to find similar suitable styles for these cells but got no success. Would you help?
I found the style, it works for the partial group aggregation cells:
.v-table-table .v-table-cell-content.truth-ag .v-table-cell-wrapper:not(:empty)