Skip to main content
Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Unanswered

MultiSelect Lookup Issue: Selected items not retained + dependent lookup not updating (D365FO)

(3) ShareShare
ReportReport
Posted on by 590

Hi all,

I'm using SysLookupMultiSelectGrid and SysLookupMultiSelectCtrl in a UIBuilder for a report (Consumption Report) where users select Parent Items and then Child Items based on that.

Issues:

  • SysLookupMultiSelectGrid always highlights the first record on reopen, even when different items were selected earlier.
  • SysLookupMultiSelectCtrl works for Parent selection but Child Item lookup doesn't trigger based on parent selection. It stays blank.

What I Expect:

  • Keep only selected items highlighted in the Parent multiselect.
  • Refresh the Child Item lookup dynamically based on selected parents.

Any help on dynamically refreshing child lookups or fixing the default focus behavior is appreciated.

 

Tagging experts:
@Martin Dráb @André Arnaud de Calavon @nmaenpaa @Jonas "Jones" Melgaard

Categories:
  • Martin Dráb Profile Picture
    234,712 Most Valuable Professional on at
    MultiSelect Lookup Issue: Selected items not retained + dependent lookup not updating (D365FO)
    It does work in regular forms; you can find many examples in the standard application. Maybe dialogs are special, but maybe you just have a bug somewhere. Can you please prepare a minimal working example (without any unrelated code or custom objects) so we can test the code without duplicated effort of writing it on our own?
     
    Also, what happens if you create a new object and assign it to ctrlMainItem variable, instead of just callig set() of the existing object?
  • Saalim Ansari Profile Picture
    590 on at
    MultiSelect Lookup Issue: Selected items not retained + dependent lookup not updating (D365FO)

    You're right that set() works for setting the selected values, but I noticed that it's only effective the first time when called from postRun(). Since postRun() runs only once when the dialog opens, the values are set initially.

     

    However, when I modify the item again, the SysLookupMultiSelectCtrl doesn’t update automatically — calling set() again in those cases has no effect

  • Martin Dráb Profile Picture
    234,712 Most Valuable Professional on at
    MultiSelect Lookup Issue: Selected items not retained + dependent lookup not updating (D365FO)
    I guess you just need to call set() with different values to change the selected values. Try it and you'll see if it works.
  • Saalim Ansari Profile Picture
    590 on at
    MultiSelect Lookup Issue: Selected items not retained + dependent lookup not updating (D365FO)
    Update Code:
    How can we override or reinitialize the SysLookupMultiSelectCtrl values at runtime based on the latest selection?
     
    class XXX_MilkConsumptionReportUIBuilder extends SysOperationAutomaticUIBuilder
    {
        SysListPanel                    sysListPanel;
        DialogField                     dialogMainItemId;
        DialogField                     dialogBomItemId;
        DialogField                     dialogActivationDate;
        SysLookupMultiSelectCtrl       ctrlMainItem;
    
        protected DialogField addDialogField(IdentifierName _methodName, Object _dataContract = this.dataContractObject())
        {
            DialogField ret;
    
            switch (_methodName)
            {
                case methodStr(XXX_MilkConsumptionReportContract, parmMainItemId):
                    dialogMainItemId = this.dialog().addField(extendedTypeStr(ItemId), extendedTypeStr(Name));
                    ret = dialogMainItemId;
                    break;
    
                default:
                    ret = super(_methodName, _dataContract);
                    break;
            }
    
            return ret;
        }
    
        public void postRun()
        {
            Query queryMainItem = XXX_MilkConsumptionReportUIBuilder::companyInfoQuery();
            super();
    
            ctrlMainItem = SysLookupMultiSelectCtrl::constructWithQuery(
                this.dialog().formRun(),
                dialogMainItemId.control(),
                queryMainItem
            );
    
            ctrlMainItem.setMandatory(true);
            ctrlMainItem.set(this.fetchSelectedMainItems(queryMainItem));
        }
    
        private static Query companyInfoQuery()
        {
            Query query = new Query();
    
            QueryBuildDataSource qbdsInventTable = query.addDataSource(tableNum(InventTable));
            QueryBuildDataSource qbdsEcoresProductTranslation = qbdsInventTable.addDataSource(tableNum(EcoResProductTranslation));
    
            qbdsEcoresProductTranslation.addLink(fieldNum(InventTable, Product), fieldNum(EcoResProductTranslation, Product));
    
            qbdsInventTable.fields().addField(fieldNum(InventTable, ItemId));
            qbdsEcoresProductTranslation.fields().addField(fieldNum(EcoResProductTranslation, Name));
    
            return query;
        }
    
        public void getFromDialog()
        {
            super();
    
            XXX_MilkConsumptionReportContract contract = this.dataContractObject();
            contract.parmMainItemId(con2List(ctrlMainItem.getSelectedFieldValues()));
        }
    
        private container fetchSelectedMainItems(Query _query)
        {
            QueryRun queryRun = new QueryRun(_query);
    
            XXX_MilkConsumptionReportContract contract = this.dataContractInfo().dataContractObject();
    
            container conRecIds;
            container conItemIds;
            container conMainIds = list2Con(contract.parmMainItemId());
    
            while (queryRun.next())
            {
                InventTable itemView = queryRun.get(tableNum(InventTable));
    
                if (conFind(conMainIds, itemView.ItemId))
                {
                    conRecIds  += itemView.RecId;
                    conItemIds += itemView.ItemId;
                }
            }
    
            info(strFmt("%1, %2", conRecIds, conItemIds));
            return [conRecIds, conItemIds];
        }
    }
    
     
  • Saalim Ansari Profile Picture
    590 on at
    MultiSelect Lookup Issue: Selected items not retained + dependent lookup not updating (D365FO)

    Thank you for the detailed explanation. I tried the suggested approach, and it works correctly when the data is already fetched — I’m able to get the correct infos for items that are already present.

    However, when I modify the main item, the selected data doesn’t get updated or fetched accordingly. Is there any additional logic I need to handle for dynamic updates after modifying the main item?

     
  • Martin Dráb Profile Picture
    234,712 Most Valuable Professional on at
    MultiSelect Lookup Issue: Selected items not retained + dependent lookup not updating (D365FO)
    As I understand, you want the control to show certain values already selected. That's what set() method is for.
     
    I strongly encourage you to look at the example I gave you before (and don't forgert that you can use Find references to locate all other examples in the application). ERMultiselectParameterUIBuilder.initMultiselectControl() creates an instance of SysLookupMultiSelectCtrl and passes the values to be selected to set(). But what it receives from the data contract class is a container of textual values, while SysLookupMultiSelectCtrl requires two containers: one with RecIds and one with actual values. Therefore initMultiselectControl() finds RecIds for the values before calling set(). Whether you need to do the same or not depends on what data you have as the input, e.g. how you store selected values in xxx_MilkConsumptionReportContract.
  • Saalim Ansari Profile Picture
    590 on at
    MultiSelect Lookup Issue: Selected items not retained + dependent lookup not updating (D365FO)
    Thanks for pointing out the missing set() call—could you please explain a bit more about where exactly we should use the set() method when working with SysLookupMultiSelectCtrl in a report dialog, and why it's important?
     
    Specifically, does it need to be used right after constructWithQuery(), or in a modified event, and how does it help ensure the selected values are retained or displayed correctly during re-selection? This will help us understand its proper usage and avoid similar issues in future implementations.
     
    Thanks again!
  • Martin Dráb Profile Picture
    234,712 Most Valuable Professional on at
    MultiSelect Lookup Issue: Selected items not retained + dependent lookup not updating (D365FO)
    You don't call set() at all. That looks like the problem to me.
  • Saalim Ansari Profile Picture
    590 on at
    MultiSelect Lookup Issue: Selected items not retained + dependent lookup not updating (D365FO)
    Hello @Martin,
     
    Here is my complete code.
     
    internal final class xxx_milkconsumptionreportuibuilder extends srsreportdatacontractuibuilder
    {
        xxx_milkconsumptionreportcontract     contract;
        dialogfield                           dialogmainitemid;
        dialogfield                           dialogbomitemid;
        systablelookup                        sys;
        container 			          mainidselectedfields;
        list 			          mainidlist =  new list(types::string);
        
        public void build()
        {
            contract             = this.datacontractobject();
            dialogmainitemid     = this.adddialogfield(methodstr(xxx_milkconsumptionreportcontract, parmmainitemid), contract);
            dialogbomitemid      = this.adddialogfield(methodstr(xxx_milkconsumptionreportcontract, parmbomitemid), contract);
        }
        
        public void postbuild()
        {
            super();
            contract             = this.datacontractobject();
            dialogmainitemid     = this.bindinfo().getdialogfield(contract, methodstr(xxx_milkconsumptionreportcontract, parmmainitemid));
            dialogbomitemid      = this.bindinfo().getdialogfield(contract, methodstr(xxx_milkconsumptionreportcontract, parmbomitemid));
            dialogmainitemid.lookupbutton(formlookupbutton::always);
            dialogbomitemid.lookupbutton(formlookupbutton::always);
        }
    
        public void mainitemidlookup()
        {
            query query = new query();
            querybuilddatasource qbdsinventtable = query.adddatasource(tablenum(inventtable));
            querybuilddatasource qbdsecoresproducttranslation = qbdsinventtable.adddatasource(tablenum(ecoresproducttranslation));
            qbdsecoresproducttranslation.addlink(fieldnum(inventtable, product), fieldnum(ecoresproducttranslation, product));
            qbdsinventtable.fields().addfield(fieldnum(inventtable, itemid));
            qbdsecoresproducttranslation.fields().addfield(fieldnum(ecoresproducttranslation, name));
    
            container selectedfields = [tablenum(inventtable), fieldnum(inventtable, itemid)];
            syslookupmultiselectctrl multiselectctrl = syslookupmultiselectctrl::constructwithquery(this.dialog().dialogform().formrun(), dialogmainitemid.control(), query, false, selectedfields);
            container selectedvalues = multiselectctrl.get();
    
            for (int i = 1; i <= conlen(selectedvalues); i++)
            {
                mainidlist.addend(conpeek(selectedvalues, i));
            }
            info(strfmt("%1,%2", con2str(selectedvalues), mainidlist.getenumerator()));
        }
    
        private void bomitemidlookup()
        {
            xxx_cuonsumptionreportloweritemlookup lowerlookuptemp;
            delete_from lowerlookuptemp;
            
            listenumerator le = mainidlist.getenumerator();
            while (le.movenext())
            {
                this.itemexplode(le.current());
            }
    
            query query = new query();
            querybuilddatasource qbds = query.adddatasource(tablenum(xxx_cuonsumptionreportloweritemlookup));
    
            qbds.fields().addfield(fieldnum(xxx_cuonsumptionreportloweritemlookup, combinationfield));
            qbds.fields().addfield(fieldnum(xxx_cuonsumptionreportloweritemlookup, itemname));
            container selectedfields = [tablenum(xxx_milkconsumptionreporttemp), fieldnum(xxx_cuonsumptionreportloweritemlookup, combinationfield)];
    
            syslookupmultiselectctrl::constructwithquery(this.dialog().dialogform().formrun(), dialogbomitemid.control(), query, false, selectedfields);
        }
    
        private boolean haschild(itemid _itemid)
        {
            bomversion bomversion;
    
            select firstonly * from bomversion
                where bomversion.itemid == _itemid
                    && bomversion.active
                    && bomversion.fromdate <= systemdateget()
                    && (!bomversion.todate || bomversion.todate >= systemdateget());
    
            return (bomversion.recid != 0);
        }
    
        public void itemexplode(itemid _itemid)
        {
            bomversion  bomversion;
            bom         bom;
            inventtable inventtable;
    
            select firstonly * from bomversion
                where bomversion.itemid == _itemid
                    && bomversion.active
                    && bomversion.fromdate <= systemdateget()
                    && (!bomversion.todate || bomversion.todate >= systemdateget());
    
            if (!bomversion)
                return;
    
            while select * from bom
                where bom.bomid == bomversion.bomid
                join inventtable
                    where inventtable.itemid == bom.itemid
            {
                xxx_cuonsumptionreportloweritemlookup lowerlookuptemp;
    
                lowerlookuptemp.clear();
                lowerlookuptemp.combinationfield = strfmt("%1 - %2", bom.itemid, _itemid);
                lowerlookuptemp.itemid = bom.itemid;
                lowerlookuptemp.itemname = inventtable.itemname();
                lowerlookuptemp.mainitemid = _itemid;
                lowerlookuptemp.insert();
    
                if (this.haschild(bom.itemid))
                {
                    this.itemexplode(bom.itemid);
                }
            }
        }
    
        public void postrun()
        {
            this.mainitemidlookup();
            this.bomitemidlookup();
            contract = this.datacontractobject();
        }
    }
    
     
  • Martin Dráb Profile Picture
    234,712 Most Valuable Professional on at
    MultiSelect Lookup Issue: Selected items not retained + dependent lookup not updating (D365FO)
    Are you sure you're passing correct values to SysLookupMultiSelectCtrl.set()? You can see an example in ERMultiselectParameterUIBuilder.initMultiselectControl(), for instance.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

News and Announcements

Now Available: 2025 Release Wave 2

Quick Links

Ramesh Kumar – Community Spotlight

We are honored to recognize Ramesh Kumar as our July 2025 Community…

Congratulations to the June Top 10 Community Leaders!

These are the community rock stars!

Announcing the Engage with the Community forum!

This forum is your space to connect, share, and grow!

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
Abhilash Warrier Profile Picture

Abhilash Warrier 565

#2
Martin Dráb Profile Picture

Martin Dráb 536 Most Valuable Professional

#3
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 402 Super User 2025 Season 1

Product updates

Dynamics 365 release plans