@Route(value = ContextFreeSearchView.NAME, layout = SampleApplicationLayout.class)
public class ContextFreeSearchView extends VerticalLayout implements AfterNavigationObserver {
Suche
Suche als eigene Seite
Bei der Suche auf einer eigenen Seite ist es erwünscht, dass die Suchparameter direkt in der URL wieder gespiegelt werden, damit die Suche auch direkt von einer anderen Seite erreichbar ist.
Der RoutingSearchController
bietet hierfür Funktionalitäten, die die Implementierung erleichtern.
SearchView
Da die Suchseite direkt per URL erreichbar sein muss, ist eine @Route
-Annotation notwendig. Außerdem muss das Interface BeforeEnterObserver
oder AfterNavigationObserver
implementiert werden, um die URL-Parameter zu verarbeiten.
Laut Dokumentation zum Vaadin Navigation Lifecycle wird die Initialisierung der UI eher im After-Navigation-Event vorgenommen. In diesem Event kann allerdings keine Umleitung auf eine andere Seite erfolgen. Soll bei genau einem Suchtreffer anstatt der Suchseite direkt das gefundene Objekt geöffnet werden, bietet sich das Before-Enter-Event an. |
Als Seiteninhalt muss ein SearchLayoutPmo
verwendet werden, welches über den SearchLayoutBuilder
erstellt wird. Die Erstellung vom SearchLayoutPmo
ist unabhängig von der Art der Suche, und kann im entsprechenden Abschnitt "Erstellen der Suchkomponente" nachgelesen werden.
private final BindingContext bindingContext = new BindingContext();
public ContextFreeSearchView() {
add(VaadinUiCreator.createComponent(createSearchLayoutPmo(), bindingContext));
setSizeFull();
}
In initialize
muss die Location
an den RoutingSearchController
weitergegeben werden. Dieser liest die Suchparameter aus der URL und führt ggfs. die Suche aus.
Um die gesetzten Parameter anzuzeigen, muss der BindingContext
, in dem das SearchLayoutPmo liegt, aktualisiert werden.
@Override
public void afterNavigation(AfterNavigationEvent event) {
searchController.initialize(event.getLocation());
bindingContext.modelChanged();
}
Dem verwendeten RoutingSearchController
muss der Wert der @Route
-Annotation mitgegeben werden.
return new RoutingSearchController<>(ContextFreeSearchView.NAME,
searchService::search,
new SampleSearchParametersMapper(),
SampleSearchResult::getMessages);
Query Parameter Mapping
Für den Suchparametertyp muss eine Implementierung von SearchParameterMapper
erstellt werden.
public class SampleSearchParametersMapper implements SearchParameterMapper<SampleSearchParameters> {
Darin befindet sich eine Methode zum Erzeugen eines Suchparameterobjektes aus Query Parametern:
public SampleSearchParameters toSearchParameters(Map<String, List<String>> queryParams) {
var searchParams = new SampleSearchParameters();
var parameters = ParamsUtil.flatten(queryParams);
searchParams.setPartnerNumber(parameters.get(PROPERTY_PARTNER_NUMBER));
...
Sowie eine Methode zum Erzeugen von Query Parametern aus einem Suchparameterobjekt:
public Map<String, List<String>> toQueryParameters(SampleSearchParameters searchParams) {
var queryParams = new LinkedHashMap<String, String>();
queryParams.put(PROPERTY_PARTNER_NUMBER, searchParams.getPartnerNumber());
...
Falls jeder Parameter nur einen Wert hat, kann über ParamsUtil.flatten
und ParamsUtil.flatten
eine Map<String, String>
statt einer Map<String, List<String>>
verwendet werden.
ParamsUtil
bietet ebenfalls ein paar format
und parse
Methoden.
queryParams.put(PROPERTY_DATE_OF_BIRTH, ParamsUtil.formatIsoDate(searchParams.getDateOfBirth()));
ParamsUtil.parseIsoDate(parameters.get(PROPERTY_DATE_OF_BIRTH))
.ifPresent(searchParams::setDateOfBirth);