Using Search in UI

Visual Components

The Search add-on provides two UI components: SearchField and FullTextFilter. To enable using these components in screens, declare the search namespace in the root element in the screen XML descriptor:

<window xmlns="http://jmix.io/schema/ui/window"
        xmlns:search="http://jmix.io/schema/search/ui"
        caption="msg://searchScreen.caption">

SearchField

The SearchField component provides an input field with a button that runs searching.

An example of using SearchField in a screen:

<layout>
    <search:searchField id="mySearchField"/>
</layout>

SearchField attributes:

  • searchStrategy - a search strategy used for searching. If the strategy is not defined, then a default strategy is used.

  • entities - searching will be performed within the specified entities. Multiple entities can be specified as a comma-separated list:

    <search:searchField id="mySearchField" entities="search_Customer,search_Order"/>

By default, searchField opens the built-in SearchResultsView. This view does the querying search engine itself and displays a list of results either inside the navigational screen or in newly opened dialog depending on openMode UI element attribute. To change this behavior, you can set SearchCompletedHandler as follows:

@ViewComponent
SearchField mySearchField;

@Autowired
DialogWindows dialogWindows;

@Install(to = "mySearchField", subject = "searchCompletedHandler")
public void mySearchFieldSearchCompletedHandler(
        SearchField.SearchCompletedEvent event) {
    SearchResult searchResult = event.getSearchResult();
    DialogWindow<SearchResultsView> searchResultsDialog =
            dialogWindows.view(UiComponentUtils.getView(this),
                            SearchResultsView.class)
                    .build();
    SearchResultsView view = searchResultsDialog.getView();
    view.initView(new SearchFieldContext(mySearchField));
    searchResultsDialog.open();
}

Alternatively, you can use the setSearchCompletedHandler() method of the component.

FullTextFilter

The FullTextFilter component works like propertyFilter.

An example of using fullTextFilter in the screen:

<layout expand="ordersTable" spacing="true">
    <search:fullTextFilter dataLoader="ordersDl"/>
    <!-- ... -->
</layout>

FullTextFilter attributes:

  • dataLoader - a DataLoader that must be filtered.

  • searchStrategy - a search strategy used for searching. If the strategy is not defined, then a default strategy is used.

  • autoApply - set to true if the filter component should be automatically applied to the DataLoader when the component value is changed.

FullTextFilter works as follows: it finds identifiers of entities by the full-text search, and then adds a condition with these identifiers to the data loader. As a result, Table or DataGrid connected to the same data loader will show only records that match the full-text search criteria, combined with other filters, if any.

Search Strategies

A search strategy defines how the search term is handled.

The SearchField and FullTextFilter components support the following search strategies:

  • anyTermAnyField - a document matches if it contains at least one of input words in any indexed field.

  • allTermsAnyField - a document matches if it contains all input words in any field in any order. This strategy is set by default.

  • allTermsSingleField - a document matches if it has at least one field that contains all input words in any order.

  • phrase - a document matches if it has at least one field that contains all input words in the provided order.

You can set the proper strategy by using the strategy attribute, for example:

<search:searchField id="mySearchField" strategy="allTermsAnyField"/>

To override the default strategy, add the following property to your application.properties file:

jmix.search.default-search-strategy = allTermsSingleField

Also, you can create your own search strategy. For that purpose, you need to create a new bean extending io.jmix.search.searching.SearchStrategy class and implementing two methods:

  • String getName() - should return a unique strategy name.

  • void configureRequest(SearchRequest searchRequest, SearchContext searchContext) - should configure the incoming SearchRequest as needed.

After that, you can set your strategy to the SearchField or FullTextFilter component by the strategy name.

Full-text Search Condition in Filter Component

When the Search add-on is added to the project, a new condition appears in the Add condition window of the Filter component:

Add Condition to Filter

In the Full-text filter condition editor window you can specify a caption for the full-text filter and select a search strategy. If no search strategy is selected, then the default one is used.

Condition Editor

Records in the list component associated with the filter will be filtered based on the full-text search result.

Using Search API in Screens

You can use Search API in screen controllers. Let’s look at the example:

@Autowired
private EntitySearcher entitySearcher;

@Autowired
private SearchResultProcessor searchResultProcessor;

@Subscribe("searchBtn") (1)
public void onSearchBtnClick(Button.ClickEvent event) {
    SearchContext searchContext = new SearchContext("silver") (2)
            .setSize(20) (3)
            .setEntities("search_Order"); (4)
    SearchResult searchResult = entitySearcher.search(searchContext); (5)
    Collection<Object> instances =
            searchResultProcessor.loadEntityInstances(searchResult); (6)
    // ...
}
1 API is called from the screen when clicking on a button.
2 Defining the search string is mandatory: here, the query will look through all fields marked for indexing that contain the "silver" string.
3 Adds the conditions for the query: firstly, the max amount of records in the result set. Default value is 10.
4 Next, the list of entities to search within. By default, all indexed entities are included.
5 The EntitySearcher service is used to start searching.
6 SearchResultProcessor is used for fetching entities from the search result.