‎2025 Aug 21 1:17 PM - edited ‎2025 Aug 22 6:23 AM
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.
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).
In ObjectPageControllerExtension, override the onAfterRendering method:
onAfterRendering: function () {
this.addSearchFieldToTable();
this.changeColumnLayout();
}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);
}
}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);
});
}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.
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).
Request clarification before answering.
.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
| User | Count |
|---|---|
| 9 | |
| 7 | |
| 6 | |
| 4 | |
| 3 | |
| 3 | |
| 3 | |
| 2 | |
| 2 | |
| 2 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.