Skip to content

sap.m.SelectDialog with OData V4 + $apply groupby selects wrong item after search/filter #4402

@evapoorada

Description

@evapoorada

What is the issue and how can we reproduce it?

Bug Report: sap.m.SelectDialog with OData V4 + $apply groupby returns wrong item via selectedContexts after search/filter

Description

When using sap.m.SelectDialog bound to an OData V4 model with
$apply: 'groupby((PropertyName))' in the binding parameters, filtering
the dialog via the search field and then selecting an item causes
selectedContexts to return the wrong binding context.

The returned context path (e.g. /EntitySet/0) corresponds to the item
at that index in the original unfiltered collection, NOT the item at
that index in the filtered results. This means the confirmed item is
completely different from what the user selected.


Steps to Reproduce

  1. Bind a SelectDialog to an OData V4 model using $apply groupby:
<SelectDialog
    multiSelect="true"
    items="{
        path: '/EntitySet',
        parameters: {
            $apply: 'groupby((SomeProperty))'
        }
    }"
    search=".onSearch"
    liveChange=".onSearch"
    confirm=".onConfirm"
    rememberSelections="true">
    <StandardListItem title="{SomeProperty}" type="Active" />
</SelectDialog>
  1. Search/filter handler:
onSearch: function (oEvt) {
    var sValue = oEvt.getParameter("value");
    var oFilter = sValue
        ? new Filter("SomeProperty", FilterOperator.Contains, sValue)
        : [];
    oEvt.getParameter("itemsBinding").filter(oFilter);
},

onConfirm: function (oEvt) {
    var aContexts = oEvt.getParameter("selectedContexts");
    aContexts.forEach(function(oCtx) {
        // oCtx.sPath is e.g. "/EntitySet/0"
        // but /0 is the first item of the ORIGINAL unfiltered list,
        // NOT the first item of the filtered results!
        console.log(oCtx.sPath);       // "/EntitySet/0"  ← WRONG index
        console.log(oCtx.getObject()); // returns wrong item
    });
}
  1. Open the dialog.
  2. Type in the search field so only 1 or a few results remain visible.
  3. Select the visible item (e.g. the first and only result after filtering).
  4. Confirm the dialog.

Expected Behavior

selectedContexts should return the context of the actually selected
visible item
after filtering — for example, if the user selected the
only visible result after filtering, the context should point to that
specific entity, regardless of its position in the original unfiltered
collection.


Actual Behavior

selectedContexts returns a context whose sPath is re-indexed based
on the filtered result position (e.g. /EntitySet/0 because it is
the first visible item after filtering), but the OData V4 model resolves
/EntitySet/0 against the original unfiltered collection — returning
the first item of the full dataset instead of the selected filtered item.

Concrete example:

Position in original list Value
/EntitySet/0 Alice
/EntitySet/1 Bob
/EntitySet/2 Charlie

User searches for Charlie → only Charlie is visible (position 0 in filtered view).
User selects Charlie.
selectedContexts[0].sPath/EntitySet/0
selectedContexts[0].getObject().SomeProperty"Alice" ❌ (wrong!)


Root Cause

$apply: 'groupby(...)' on an OData V4 binding produces aggregated
contexts
. When SelectDialog applies an additional client-side search
filter on top, the visible items are re-indexed starting from 0. The
context paths returned in selectedContexts reflect this re-indexed
position, but the OData V4 model resolves them against the full original
dataset — causing an index mismatch and returning the wrong entity.


Workaround

Fetch data manually via requestContexts(), deduplicate in the
controller, and bind the dialog to a local JSONModel instead:

onOpenDialog: function () {
    var oListBinding = this.getView().getModel().bindList("/EntitySet");
    oListBinding.requestContexts(0, Infinity).then(function (aContexts) {
        var aSeen = new Set();
        var aUnique = [];
        aContexts.forEach(function (oCtx) {
            var sVal = oCtx.getObject().SomeProperty;
            if (!aSeen.has(sVal)) {
                aSeen.add(sVal);
                aUnique.push({ SomeProperty: sVal });
            }
        });
        var oLocalModel = new JSONModel({ items: aUnique });
        this._oDialog.setModel(oLocalModel, "localModel");
        this._oDialog.open();
    }.bind(this));
},

onConfirm: function (oEvt) {
    // Now works correctly — JSONModel paths are stable
    var aContexts = oEvt.getParameter("selectedContexts");
    aContexts.forEach(function (oCtx) {
        console.log(oCtx.getObject().SomeProperty); // ✅ correct item
    });
}

Environment

SAPUI5 Version 1.140.0
OData Version V4
Browser Chrome 145
OS Windows 11

Which OpenUI5 version is your project targeting?

1.140.0

Is the issue device- or browser-specific?

No

Confirmation

  • I have searched the existing issues and reviewed the relevant documentation as well as the API reference.
  • I am not disclosing any internal or sensitive information.

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions