Hi Martin,
I have a menu item that runs directly from the controller -- so for this one, the business logic is in the controller.
However, for the other one. I have a button that when it's clicked i need to pass selected records then call the action menu item, if i'm not going to do it in the clicked method
then how i'm going to pass selected records from controller? (cause u said to remove business logic)
and can you please explain what do you mean by this "
Then I would throw away the hard-coded menu item name and simply check if a record was provided in Args."
I'll try to post the code again. As editing the code from the post is still appearing in a wrong way
[Form] public class Table1Form extends FormRun {
[Control("MenuFunctionButton")]
class Controller1
{
public void clicked()
{
Table1 table1;
container container1;
Args args = new Args();
MultiSelectionHelper selectionHelper = MultiSelectionHelper::construct();
selectionHelper.parmDataSource(Table1_ds);
table1 = selectionHelper.getFirst();
while (table1)
{
container1 += table1.RecId;
table1 = selectionHelper.getNext();
}
if (conLen(container1))
{
args.caller(element);
args.parm(con2str(container1));
new MenuFunction(menuitemActionstr(Controller1), MenuItemType::Action).run(args);
}
}
}
}
Here's the controller --
how can i enhance the main method to support both running it from the menu item directly, or by passing selected records?
class Controller1 extends SysOperationServiceController
{
Public ClassDescription defaultCaption()
{
return "caption";
}
protected void new()
{
super(classStr(Service1), methodStr(Service1, run), SysOperationExecutionMode::Synchronous);
}
public static Controller1 construct()
{
Controller1 controller;
controller = new Controller1();
return controller;
}
public static void main(Args _args) {
Controller1 controller;
Contract1 contract;
controller = Controller1::construct();
controller.parmArgs(_args);
contract = controller.getDataContractObject();
contract.parmCallerName(_args.callerName());
contract.parmContainerStr(_args.parm());
controller.startOperation();
}
}
Here's the contract class
​
[DataContractAttribute]
class Contract1
{ str callerName;
str packedQuery;
str ContainerStr;
public str parmCallerName(str _callerName = callerName)
{ callerName = _callerName;
return callerName;
}
public str parmContainerStr(str _containerStr = containerStr)
{
containerStr = _containerStr;
return containerStr;
}
[ DataMemberAttribute,
AifQueryTypeAttribute('_packedQuery', queryStr(Query1))]
public str parmQuery(str _packedQuery = packedQuery)
{
packedQuery = _packedQuery;
return packedQuery;
}
public void setQuery(Query _query)
{
packedQuery = SysOperationHelper :: base64Encode(_query.pack());
}
public Query getQuery()
{
return new Query(SysOperationHelper :: base64Decode(packedQuery));
}
}
​
Here's the service class:
class Service1 extends SysOperationServiceBase
{
Table1 table1, parmTable1;
Table2 table2;
System.ArgumentException ex;
Query query;
QueryRun queryRun;
str callerName;
QueryBuildDataSource qbds;
QuerybuildRange qbr;
Str parmContainerStr;
public void run(Contract1 _contract)
{
this.getParamFromContract(_contract);
this.setQueryRanges();
queryRun = new QueryRun(query);
while(queryRun.next())
{
table2 = queryRun.get(tableNum(table2));
table1 = queryRun.get(tableNum(table1));
if(table1)
{
try
{
ttsbegin;
//logic
ttscommit;
}
catch (Exception::Error)
{
ttsabort;
}
}
}
}
public void getParamFromContract(Contract1 _contract)
{
query = _contract.getQuery();
callerName =_contract.parmCallerName();
parmContainerStr = _contract.parmContainerStr();
}
public void setQueryRanges()
{
if(callerName == menuItemDisplayStr(Table1) && parmContainerStr)
{
qbds = query.dataSourceName('Table1');
qbr = qbds.addRange(fieldNum(Table1, RecId));
qbr.value(parmContainerStr);
}
}
private static ClassDescription description()
{ return "description";
}
}