cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

Implementing UI5 Search Field for Virtual Elements

Ram-Gnanesh
Advisor
Advisor
1,249

Introduction

When working with Fiori Elements applications, the out-of-the-box search functionality usually triggers a backend OData filter request. This is great when all the fields you want to search on are persisted in the database.

But what happens when you need to search on a virtual/derived element (for example, a concatenated display text that doesn’t exist as a real DB field)?

In such cases, backend filtering is not possible. The request fails, or you end up with errors because the field isn’t filterable.

Recently, I faced exactly this challenge. The requirement was to allow the user to search inside a table column where the field was only derived at runtime.

Here’s how I solved it by replacing the default search with a custom search field in a UI5 Controller Extension.


Why UI5 Search Field?

  • Default FE search: Sends a filter request to the backend.

  • Problem: My search field was virtual → no DB persistence → backend rejects the filter.

  • Solution: Replace the default search with a sap.m.SearchField that applies filtering only on the client side (on already loaded table items).


Implementation Steps

1. Extend the Object Page Controller

In ObjectPageControllerExtension, override the onAfterRendering method:

onAfterRendering: function () { 
  this.addSearchFieldToTable();
  this.changeColumnLayout();
}

2. Custom Search Field

addSearchFieldToTable: function () {
    const sId = "ObjectPageSearchFieldId"; // Replace with actual ID
    const oOldSearchField = sap.ui.getCore().byId(sId);

    if (oOldSearchField) {
        // Remove default backend filter binding
        oOldSearchField.getFilter().destroy();

        // Add new SearchField with custom handler
        const oNewSearchField = new sap.m.SearchField({
            placeholder: "{i18n>searchPlaceholder}",
            search: this.onSearch.bind(this)
        });

        oOldSearchField.setFilter(oNewSearchField);
    }
}

3. Client-Side Filtering

onSearch: function (oEvent) {
    const sQuery = (oEvent.getParameter("query") || "").trim().toLowerCase();
    const oTable = sap.ui.getCore().byId("ObjectPageTableId"); // Replace with actual ID

    if (!oTable) return;

    // Reset visibility
    oTable.getItems().forEach(oItem => oItem.setVisible(true));

    // Empty query → show all
    if (!sQuery || sQuery === "*") return;

    // Filter items by virtual field
    oTable.getItems().forEach(oItem => {
        const oData = oItem.getBindingContext()?.getObject();
        const sVirtualText = oData?.VirtualConcatenatedText || "";
        const aParts = sVirtualText.split(",").map(a => a.trim().toLowerCase());

        const bMatch = aParts.some(a => a.includes(sQuery));
        oItem.setVisible(bMatch);
    });
}

Result

Users can now search by the virtual text field even though it’s not persisted in the database.

  • Filtering happens instantly on the UI without backend calls.

  • Backend remains clean since no invalid OData requests are sent.


Key Takeaways

  • Use client-side filtering when your search target is a virtual/derived element.

  • This pattern can be reused in scenarios where backend filtering isn’t possible (e.g., calculated fields, concatenated strings, or UI-only attributes).

 

Accepted Solutions (1)

Accepted Solutions (1)

RaminS
Active Participant
0 Likes

.

Ram-Gnanesh
Advisor
Advisor
Thank you for pointing this out — you are absolutely right that, in general, filtering, sorting, and pagination should always be pushed down to the backend. The Fiori framework and SADL are designed exactly for that purpose, and client-side filtering can indeed lead to misleading results when working with large datasets. In my scenario, however, the requirement was a bit different: the field in question is a virtual/derived element that does not exist in the database and is therefore not filterable through OData. Because of that limitation, backend filtering isn’t an option in this case. The table in which this requirement applies also has a relatively small result set (object-page level, scoped context), which makes client-side filtering practical and safe. That said, I fully agree that this approach should only be considered for small datasets and when backend filtering is not possible. For larger datasets, backend-driven filtering remains the best practice.

Answers (0)