ui5-typescript-walkthrough

Step 23: Filtering

In this step, we add a search field for our product list and define a filter that represents the search term. When searching, the list is automatically updated to show only the items that match the search term.

 


Preview

A search field is displayed above the list

You can access the live preview by clicking on this link: 🔗 Live Preview of Step 23.


Coding

You can download the solution for this step here: [📥 Download step 23](https://sap-samples.github.io/ui5-typescript-walkthrough/ui5-typescript-walkthrough-step-23.zip).
You can download the solution for this step here: [📥 Download step 23](https://sap-samples.github.io/ui5-typescript-walkthrough/ui5-typescript-walkthrough-step-23-js.zip).

webapp/controller/InvoiceList.controller.?s

We will implement a new onFilterInvoices event handler function to our controller. This function will enable users to filter the invoice list based on a search term entered in a sap/m/SearchField control.

In the in the event handler, we create a filter object for the search term with filter operator Contains that targets the ProductName property of the invoice data.

If the query is empty, we filter the binding with an empty array. This will make sure that we see all list elements again.

Finally we apply the filter to the items binding of the invoice list in our view, updating the displayed items.

import Controller from "sap/ui/core/mvc/Controller";
import JSONModel from "sap/ui/model/json/JSONModel";
import formatter from "../model/formatter";
import { SearchField$SearchEvent } from "sap/m/SearchField";
import Filter from "sap/ui/model/Filter";
import FilterOperator from "sap/ui/model/FilterOperator";
import ListBinding from "sap/ui/model/ListBinding";

/**
 * @namespace ui5.walkthrough.controller
 */
export default class App extends Controller {
    public formatter = formatter;

    onInit(): void {
        const viewModel = new JSONModel({
            currency: "EUR"
        });
        this.getView()?.setModel(viewModel, "view");        
    }

    onFilterInvoices(event: SearchField$SearchEvent): void {
        // build filter array
        const filter = [];
        const query = event.getParameter("query");
        if (query) {
            filter.push(new Filter("ProductName", FilterOperator.Contains, query));
        }

        // filter binding
        const list = this.byId("invoiceList");
        const binding = list?.getBinding("items") as ListBinding;
        binding?.filter(filter);
    }
};

sap.ui.define(["sap/ui/core/mvc/Controller", "sap/ui/model/json/JSONModel", "sap/ui/model/Filter", "sap/ui/model/FilterOperator"], function (Controller, JSONModel, Filter, FilterOperator) {
  "use strict";

  const App = Controller.extend("ui5.walkthrough.controller.App", {
    onInit() {
      const viewModel = new JSONModel({
        currency: "EUR"
      });
      this.getView()?.setModel(viewModel, "view");
    },
    onFilterInvoices(event) {
      // build filter array
      const filter = [];
      const query = event.getParameter("query");
      if (query) {
        filter.push(new Filter("ProductName", FilterOperator.Contains, query));
      }

      // filter binding
      const list = this.byId("invoiceList");
      const binding = list?.getBinding("items");
      binding?.filter(filter);
    }
  });
  ;
  return App;
});

  The onFilterInvoices function is triggered by a SearchField$SearchEvent(an event generated by the search field when the user enters a search term and presses Enter or clicks the search icon). Event handlers always receive an event argument. This argument provides access to the event’s specific parameters.

We use event.getParameter("query") to extract the text entered by the user in the search field. The "query" parameter is a standard property of the SearchField$SearchEvent.

If the query is not empty, we create a new sap/ui/model/Filter object. This filter object is configured as follows:

The byId method is a helper function provided by the sap/ui/core/mvc/Controller class. It allows you to retrieve a control instance by its ID. Because the control ID is automatically prefixed with the view ID at runtime, we need to use byId to get a reference to the list control that’s defined in the view.

list?.getBinding("items") gets the binding object for the items aggregation of the sap/m/List. The items aggregation is the one bound to the list items.

binding?.filter(filter) applies the filter (which is an array, even if it only contains one filter) to the list binding. This triggers the list to update its display, showing only the items that match the filter criteria. If the filter array is empty (because the query was empty), the binding?.filter(filter) call will effectively clear any existing filters, displaying all the items in the list again.

webapp/view/InvoiceList.view.xml

First we specify the ID “invoiceList” to the list control, so the event handler function onFilterInvoices we added to the controller of the invoice list view can identify the list when triggered.

In addition, we remove the headerText property in the list control and use headerToolbar aggregation with the sap.m.Toolbar assigned to it instead. A toolbar control is way more flexible and can be adjusted as you like. To the toolbar control we add a sap.m.Title displaying the title in the text attribute, a spacer, and the sap.m.SearchField with the width property set to 50% and the filter event handler function we defined in the controller assigned to the search event.

<mvc:View
   controllerName="ui5.walkthrough.controller.InvoiceList"
   xmlns="sap.m"
   xmlns:mvc="sap.ui.core.mvc">
   <List
      id="invoiceList"
      class="sapUiResponsiveMargin"
      width="auto"
      items="{invoice>/Invoices}" >
      <headerToolbar>
         <Toolbar>
            <Title text="{i18n>invoiceListTitle}"/>
            <ToolbarSpacer/>
            <SearchField width="50%" search=".onFilterInvoices"/>
         </Toolbar>
      </headerToolbar>
      <items>
         ...
      </items>
   </List>
</mvc:View>

  The search field is part of the list header and therefore, each change on the list binding will trigger a rerendering of the whole list, including the search field.

 


Next:Step 24: Sorting and Grouping

Previous:Step 22: Custom Formatters


Related Information

API Reference: sap.m.SearchField

API Reference: sap.ui.model.Filter

API Reference: sap.ui.model.FilterOperator