use of com.vaadin.flow.data.renderer.TemplateRenderer in project flow-components by vaadin.
the class Grid method addColumn.
/**
* Adds a new text column to this {@link Grid} with a template renderer,
* sorting properties and column factory provided. The values inside the
* renderer are converted to JSON values by using
* {@link JsonSerializer#toJson(Object)}.
* <p>
* <em>NOTE:</em> You can add component columns easily using the
* {@link #addComponentColumn(ValueProvider)}, but using
* {@link ComponentRenderer} is not as efficient as the built in renderers
* or using {@link TemplateRenderer}.
* <p>
* This constructor attempts to automatically configure both in-memory and
* backend sorting using the given sorting properties and matching those
* with the property names used in the given renderer.
* <p>
* <strong>Note:</strong> if a property of the renderer that is used as a
* sorting property does not extend Comparable, no in-memory sorting is
* configured for it.
*
* <p>
* Every added column sends data to the client side regardless of its
* visibility state. Don't add a new column at all or use
* {@link Grid#removeColumn(Column)} to avoid sending extra data.
* </p>
*
* @see #addColumn(Renderer, String...)
* @see #removeColumn(Column)
*
* @param renderer
* the renderer used to create the grid cell structure
* @param columnFactory
* the method that creates a new column instance for this
* {@link Grid} instance.
* @param sortingProperties
* the sorting properties to use for this column
* @return the created column
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
protected <C extends Column<T>> C addColumn(Renderer<T> renderer, BiFunction<Renderer<T>, String, C> columnFactory, String... sortingProperties) {
C column = addColumn(renderer, columnFactory);
Map<String, ValueProvider<T, ?>> valueProviders = renderer.getValueProviders();
Set<String> valueProvidersKeySet = valueProviders.keySet();
List<String> matchingSortingProperties = Arrays.stream(sortingProperties).filter(valueProvidersKeySet::contains).collect(Collectors.toList());
column.setSortProperty(matchingSortingProperties.toArray(new String[matchingSortingProperties.size()]));
Comparator<T> combinedComparator = (a, b) -> 0;
Comparator nullsLastComparator = Comparator.nullsLast(Comparator.naturalOrder());
for (String sortProperty : matchingSortingProperties) {
ValueProvider<T, ?> provider = valueProviders.get(sortProperty);
combinedComparator = combinedComparator.thenComparing((a, b) -> {
Object aa = provider.apply(a);
if (!(aa instanceof Comparable)) {
return 0;
}
Object bb = provider.apply(b);
return nullsLastComparator.compare(aa, bb);
});
}
return column;
}
use of com.vaadin.flow.data.renderer.TemplateRenderer in project flow-components by vaadin.
the class GridViewSortingPage method createSorting.
private void createSorting() {
Div messageDiv = new Div();
Grid<Person> grid = new Grid<>();
grid.setItems(getItems());
grid.setSelectionMode(SelectionMode.NONE);
grid.addColumn(Person::getFirstName, "firstName").setHeader("Name");
grid.addColumn(Person::getAge, "age").setHeader("Age");
grid.addColumn(TemplateRenderer.<Person>of("<div>[[item.street]], number [[item.number]]<br><small>[[item.postalCode]]</small></div>").withProperty("street", person -> person.getAddress().getStreet()).withProperty("number", person -> person.getAddress().getNumber()).withProperty("postalCode", person -> person.getAddress().getPostalCode()), "street", "number").setHeader("Address");
Checkbox multiSort = new Checkbox("Multiple column sorting enabled");
multiSort.addValueChangeListener(event -> grid.setMultiSort(event.getValue()));
grid.addSortListener(event -> {
String currentSortOrder = grid.getDataCommunicator().getBackEndSorting().stream().map(querySortOrder -> String.format("{sort property: %s, direction: %s}", querySortOrder.getSorted(), querySortOrder.getDirection())).collect(Collectors.joining(", "));
messageDiv.setText(String.format("Current sort order: %s. Sort originates from the client: %s.", currentSortOrder, event.isFromClient()));
});
// you can set the sort order from server-side with the grid.sort method
NativeButton invertAllSortings = new NativeButton("Invert all sort directions", event -> {
List<GridSortOrder<Person>> orderList = grid.getSortOrder();
List<GridSortOrder<Person>> newOrderList = new ArrayList<>(orderList.size());
for (GridSortOrder<Person> sort : orderList) {
newOrderList.add(new GridSortOrder<>(sort.getSorted(), sort.getDirection().getOpposite()));
}
grid.sort(newOrderList);
});
NativeButton resetAllSortings = new NativeButton("Reset all sortings", event -> grid.sort(null));
grid.setId("grid-sortable-columns");
multiSort.setId("grid-multi-sort-toggle");
invertAllSortings.setId("grid-sortable-columns-invert-sortings");
resetAllSortings.setId("grid-sortable-columns-reset-sortings");
messageDiv.setId("grid-sortable-columns-message");
addCard("Sorting", "Grid with sortable columns", grid, multiSort, invertAllSortings, resetAllSortings, messageDiv);
}
use of com.vaadin.flow.data.renderer.TemplateRenderer in project flow-components by vaadin.
the class GridTestPage method createGridWithComponentRenderers.
private void createGridWithComponentRenderers() {
Grid<Item> grid = new Grid<>();
grid.setSelectionMode(Grid.SelectionMode.MULTI);
AtomicBoolean usingFirstList = new AtomicBoolean(true);
List<Item> firstList = generateItems(20, 0);
List<Item> secondList = generateItems(10, 20);
grid.setItems(firstList);
grid.addColumn(new ComponentRenderer<>(item -> {
Label label = new Label(item.getName());
label.setId("grid-with-component-renderers-item-name-" + item.getNumber());
return label;
})).setKey("name").setHeader("Name");
grid.addColumn(new ComponentRenderer<>(item -> {
Label label = new Label(String.valueOf(item.getNumber()));
label.setId("grid-with-component-renderers-item-number-" + item.getNumber());
return label;
})).setKey("number").setHeader("Number");
grid.addColumn(new ComponentRenderer<>(item -> {
NativeButton remove = new NativeButton("Remove", evt -> {
if (usingFirstList.get()) {
firstList.remove(item);
} else {
secondList.remove(item);
}
grid.getDataProvider().refreshAll();
});
remove.setId("grid-with-component-renderers-remove-" + item.getNumber());
return remove;
})).setKey("remove");
grid.addColumn(TemplateRenderer.<Item>of("hidden")).setHeader("hidden").setKey("hidden").setVisible(false);
grid.setId("grid-with-component-renderers");
grid.setWidth("500px");
grid.setHeight("500px");
NativeButton changeList = new NativeButton("Change list", evt -> {
if (usingFirstList.get()) {
grid.setItems(secondList);
} else {
grid.setItems(firstList);
}
usingFirstList.set(!usingFirstList.get());
});
changeList.setId("grid-with-component-renderers-change-list");
NativeButton toggleColumnOrdering = new NativeButton("Toggle column ordering", evt -> {
grid.setColumnReorderingAllowed(!grid.isColumnReorderingAllowed());
});
toggleColumnOrdering.setId("toggle-column-ordering");
NativeButton setReorderListener = new NativeButton("Set reorder listener", evt -> {
grid.addColumnReorderListener(e -> {
if (e.isFromClient()) {
List<Column<Item>> columnList = e.getColumns().stream().collect(Collectors.toList());
// Reorder columns in the list
Collections.swap(columnList, 1, 2);
grid.setColumnOrder(columnList);
}
});
});
setReorderListener.setId("set-reorder-listener");
Span currentColumnOrdering = new Span();
currentColumnOrdering.setId("current-column-ordering");
grid.addColumnReorderListener(e -> currentColumnOrdering.setText(e.getColumns().stream().map(Column::getKey).collect(Collectors.joining(", "))));
add(grid, changeList, toggleColumnOrdering, setReorderListener, currentColumnOrdering);
}
use of com.vaadin.flow.data.renderer.TemplateRenderer in project flow-components by vaadin.
the class IronListView method createDisabledStringsList.
private void createDisabledStringsList() {
IronList<String> list = new IronList<>();
list.setHeight("400px");
list.getStyle().set("border", "1px solid lightgray");
Div removalResult = new Div();
removalResult.setId("disabled-removal-result");
DataProvider<String, ?> dataProvider = DataProvider.fromCallbacks(query -> queryStringsFromDatabase(query), query -> countStringsFromDatabase(query));
list.setDataProvider(dataProvider);
// Disable the list so that scrolling still works but events are not
// handled
list.setEnabled(false);
/*
* The name of the event handlers defined at 'on-click' are used inside
* the 'withEventHandler' calls.
*/
list.setRenderer(TemplateRenderer.<String>of("<div style='display:flex; justify-content:space-between; padding:10px;'>" + "<div style='flex-grow:1'>[[item.name]]</div>" + "<div><button on-click='remove' style='color:red'>X</button></div>" + "<div>").withProperty("name", ValueProvider.identity()).withEventHandler("remove", item -> {
removalResult.setText(item);
}));
NativeButton switchEnabled = new NativeButton("Switch enabled state", event -> list.setEnabled(!list.isEnabled()));
list.setId("disabled-list-with-templates");
switchEnabled.setId("switch-enabled-state-string-list");
addCard("Using templates", "Using disabled list with templates", new Label("Rank up/down your favorite Lord of the Rings characters"), list, removalResult, switchEnabled);
}
use of com.vaadin.flow.data.renderer.TemplateRenderer in project flow-components by vaadin.
the class IronListView method createRankedListWithEventHandling.
private void createRankedListWithEventHandling() {
IronList<String> list = new IronList<>();
list.setHeight("400px");
list.getStyle().set("border", "1px solid lightgray");
List<String> items = getLordOfTheRingsCharacters();
list.setItems(items);
/*
* The name of the event handlers defined at 'on-click' are used inside
* the 'withEventHandler' calls.
*/
list.setRenderer(TemplateRenderer.<String>of("<div style='display:flex; justify-content:space-between; padding:10px;'>" + "<div style='flex-grow:1'>#[[item.rank]]: [[item.name]]</div>" + "<div><button on-click='up' hidden='[[item.upHidden]]'>↑</button>" + "<button on-click='down' hidden='[[item.downHidden]]'>↓</button>" + "<button on-click='remove' style='color:red'>X</button></div>" + "<div>").withProperty("name", ValueProvider.identity()).withProperty("rank", item -> items.indexOf(item) + 1).withProperty("upHidden", item -> items.indexOf(item) == 0).withProperty("downHidden", item -> items.indexOf(item) == items.size() - 1).withEventHandler("up", item -> {
int previousRank = items.indexOf(item);
if (previousRank == 0) {
return;
}
String previousItem = items.set(previousRank - 1, item);
items.set(previousRank, previousItem);
list.getDataCommunicator().reset();
}).withEventHandler("down", item -> {
int previousRank = items.indexOf(item);
if (previousRank == items.size() - 1) {
return;
}
String previousItem = items.set(previousRank + 1, item);
items.set(previousRank, previousItem);
list.getDataCommunicator().reset();
}).withEventHandler("remove", item -> {
items.remove(item);
list.getDataCommunicator().reset();
}));
list.setId("using-events-with-templates");
addCard("Using templates", "Using events with templates", new Label("Rank up/down your favorite Lord of the Rings characters"), list, new NativeButton("Reset", evt -> {
items.clear();
items.addAll(getLordOfTheRingsCharacters());
list.getDataCommunicator().reset();
}));
}
Aggregations