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.
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.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
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
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];
}
}
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?
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?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.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();
}
}
Abhilash Warrier
565
Martin Dráb
536
Most Valuable Professional
André Arnaud de Cal...
402
Super User 2025 Season 1