Hello Eva,
I have the same requirement and find next solution how to use multiSelectCtrl lookup inside Grid control and save data in table.
Maybe it would be helpful for someone.
1. Create your own class or modify standard like in the next example - http://dynamicaxassist.blogspot.com/2016/01/using-multi-select-lookup-on-string.html
I have created my own class copy of SysLookupMultiSelectCtrl with the next changes:
public boolean isOnGrid(FormStringControl _ctrl)
{
FormControl parentControl;
FormControl currentControl;
boolean retValue;
currentControl = _ctrl;
retValue = false;
while(currentControl.parentControl() && !retValue)
{
parentControl = currentControl.parentControl();
if(parentControl is FormGridControl)
{
retValue = true;
}
else
{
currentControl = currentControl.parentControl();
}
}
return retValue;
}
- add following code in init()
public void init()
{
frmRun.lock();
fsCtrlIds = frmRun.design().addControl(FormControlType::String, fsCtrlNames.name() + '_Ids');
fsCtrlIds.extendedDataType(fsCtrlNames.extendedDataType());
fsCtrlNamesTmp = frmRun.design().addControl(FormControlType::String, fsCtrlNames.name() + '_Tmp');
fsCtrlNamesTmp.extendedDataType(fsCtrlNames.extendedDataType());
// set the value in ctrlNames to the same as the one in the original ctrl. Required if data is loaded from SysLastValue.
fsCtrlNamesTmp.text(fsCtrlNames.valueStr());
if(this.isOnGrid(fsCtrlNames))
{
fsCtrlNames.registerOverrideMethod('modified', 'ctrlNames_textChange', this);
}
else
{
fsCtrlNames.registerOverrideMethod('textChange', 'ctrlNames_textChange', this);
}
fsCtrlNames.registerOverrideMethod('lookup', 'ctrlNames_lookup', this);
fsCtrlIds.visible(false);
fsCtrlNamesTmp.visible(false);
fsCtrlIds.enabled(false);
fsCtrlNamesTmp.enabled(false);
fsCtrlNames.mandatory(isMandatory);
fsCtrlNames.lookupButton(FormLookupButton::Always);
frmRun.resetSize();
frmRun.unLock();
}
- add following code in the ctrlNames_textChange()
public void ctrlNames_textChange(FormStringControl _fsCtrlNames)
{
FormDataSource fds;
Common anyBuffer;
_fsCtrlNames.text(fsCtrlNamesTmp.text());
fds = _fsCtrlNames.dataSourceObject();
if(fds)
{
anyBuffer = fds.cursor();
anyBuffer.(_fsCtrlNames.dataField()) = fsCtrlNamesTmp.text();
fds.refresh();
}
fsCtrlNames.modified();
}
2. Then declare in class declaration of your form your multiselect control(use your newly created class):
SysLookupMultiSelectCtrl msCtrl;
Set auto declaration property of the MsStringControl to Yes. Bound control to the datasource field.
In init method of your form write the following code after super():
msCtrl = SysLookupMultiSelectCtrl::construct(element, MsStringControl, querystr(AOTQuery));
Create following method in the form:
public void setCtrlLookupValues()
{
container ids;
container recIds;
int i;
for (i = 1; i <= conLen(str2con(YourTable.FieldLinkedToMsCtrl, ";")); i++)
{
recIds += LookupTable::find(conPeek(str2con(YourTable.FieldLinkedToMsCtrl, ";"), i)).RecId;
ids += conPeek(str2con(YourTable.FieldLinkedToMsCtrl, ";"), i);
}
msCtrl.set([recIds,ids]);
ids = conNull();
recIds = conNull();
}
This method is used to fetch the values from table to your multiselect control.
Call the method setCtrlLookupValues() in active method of your datasource:
public int active()
{
int ret;
ret = super();
element.setCtrlLookupValues();
return ret;
}
Override modified method of your string field namely MsStringControl add following code:
public boolean modified()
{
boolean ret;
ret = super();
YourTable.FieldLinkedToMsCtrl = this.text();
YourTable.write();
YourTable_ds.reread();
YourTable_ds.refresh();
return ret;
}