mardi 18 septembre 2012

How to override the event methods on dialog controls?


Overriding the event methods (e.g. modify, validate, selectionChange) on dialog controls is not as straight forward as it is on form controls, but the good news is that it is possible!
In order to override the event methods on dialog controls, the following needs to be done (for simplicity we assume that your class extends RunBase class) :
1) The method dialogPostRun() should be overridden and following two lines are added after the super() call:
_dialog.dialogForm().formRun().controlMethodOverload(true);
_dialog.dialogForm().formRun().controlMethodOverloadObject(this);

This will allow to call the event methods of your class.

2) The actual event methods should be added.
The format of the event method name is as follows: fld<ID>_1_<event name>

Please see the example below.
This method is called whenever a value of the dialog control with ID 900 is modified. In our case it is Employee ID field.

public boolean fld900_1_modified()
{
FormStringControl control = dialog.formRun().controlCallingMethod();
boolean isFieldModified;
;
isFieldModified = control.modified();
// every time the employee id is changed, update the employee name
if(isFieldModified)
{
dlgFldEmplName.value(EmplTable::find(control.text()).Name);
}
return isFieldModified;
}
You will also need to make sure that the control “Employee ID” gets the same control ID as used in the event method name (ID 900). This should be done at the time of adding the control to the dialog. Please see below:
protected Object dialog(DialogRunbase _dialog, boolean _forceOnClient)
{
;
dialog = super(_dialog, _forceOnClient);
// Add a new field by explicitly specifying the field id.
// This field id is used to create the field event methods (e.g. fld900_1_modified()).

dlgFldEmplId = new DialogField(dialog, typeid(EmplId), #dlgFlgEmplIdFieldNo);
dialog.addCtrlDialogField(dlgFldEmplId.name());
dlgFldEmplId.init(dialog);
dlgFldEmplId.label("@SYS81251");
dlgFldEmplId.helpText("@SYS81251");
dlgFldEmplId.value(emplId);

}
As you can see the macro #dlgFlgEmplIdFieldNo is used to assign the ID to the dialog control. The macro is defined in the classDeclaration and it equals 900.

Overriding method for a control in dialog (RunBase framework)

Scenario:Can we have an overridden method in a dialog class. I can not use form as a dialog. I have to add a method in the dialog class. Like modified method of an EDT.

Answer:Well it can be done. First you have to add a method dialogPostRun

public void dialogPostRun(DialogRunbase dialog)
{
;
dialog.dialogForm().formRun().controlMethodOverload(true);
dialog.dialogForm().formRun().controlMethodOverloadObject(this);
dialog.formRun().controlMethodOverload(true);
dialog.formRun().controlMethodOverloadObject(this);
super(dialog);
}

This method actually allows the dialog form to override control method at runtime. Now we need the name of the control at runtine that needs the overriden method. You can get that using

print dialogCustId.name();
pause;

where dialogCustId is the EDT. let say the name returned at runtime is Fld3_1.


Now if you have to override lookup method of the EDT you can write the method like this

void Fld3_1_lookup()
{
//override lookup method here
}

If you need to override modified method

boolean Fld3_1_modified()
{
}

.
The modified method can also be accessed by overriding

public void dialogSelectCtrl()
{
}

in the runbase class. Just call

dialog.allowUpdateOnSelectCtrl(true);

in the dialog method.

You can also create a dialog form and pass it as the parameter in the dialog method of runbase class. you can find an example in tutorial_runbase class and form.

Pass Query from dialog to Form and Filter records


Created a Runbase class which has dialog selection using QueryStr.
I need to pass this Query range selection to a form and need to filter records based on this query Selection. Call the form by passing the Query selection from the class
Args _args;
FormRun _formRun;
EmplId _empId;
;
_args = new Args(); // creating a object for args class
_args.name(formstr(xtgCummeInquiry)); // Form Menuitem
_args.caller(this); // Form Caller(Current Form is mentioned as this)
_args.object(CummeQueryRun.query());
_formRun = ClassFactory.formRunClass(_args);
//new FormRun(_args);
// Creating object for FormRun
_formRun.init(); // Form Initialization for Load
_formRun.run(); // Form Run for process
_formRun.wait(); // Form Wait for Display
and from the called form run method,assign the Query range value to the form datasource
public void run()
{
boolean ret;
Query q;
DictField dictField;
str fieldLabel;
Addressing PrintRange;
int i, j, rangeCount;
QueryBuildRange QBR;
QueryRun Qrun;
super();
if(element.args().caller())
{
CallerOBJ = element.args().caller();
Qrun = CallerObj.QueryRun();
q = QRun.query();
for(i = 1; i <= q.dataSourceCount(); i++)
{
rangeCount = q.dataSourceNo(i).rangeCount();
for(j = 1; j <= rangeCount; j++)
{
QBR = q.dataSourceNo(i).range(j);
dictField = new DictField(QBR.table(),fieldname2id(QBR.table(),QBR.name()));
fieldLabel = dictField.label();
if(QBR.value())
{
CummeTransTable_q.dataSourceTable(QBR.table()).addRange(fieldname2id(QBR.table(),QBR.name())).value(QBR.value());
}
}
}
}
CummeTransTable_ds.executeQuery();
}

finding all data sources in a form through code

static void AllDataSourcesInForm(Args _args)
{
    Args args = new Args();
    FormRun fr;
    FormBuildDataSource formBuildDataSource;
    counter i;
    ;
  
    args.name("CustTable");
    fr = ClassFactory.formRunClass(args);
    for(i=1 ; i<=fr.form().dataSourceCount();i++)
    {
        formBuildDataSource = fr.form().dataSource(i);
        info(new DictTable(formBuildDataSource.table()).name());
    }
}

Refreshing a Form with Multiple Root Data Sources


public void closeOk()
{
FormRun formRun;
List dsList;
ListEnumerator dsListEnumerator;
FormDataSource formDS;

super();

// Get an instance of the calling form.
formRun = element.args().caller();

// If the caller is a form, find and refresh the specified root data source.
if(formRun)
{
dsList = formRun.rootFormDataSources();

if(dsList && dsList.elements() > 0)
{
dsListEnumerator = dsList.getEnumerator();

while(dsListEnumerator.moveNext())
{
formDS = dsListEnumerator.current();
if(formDS.table() == tableNum(Table1))
{
formDS.research(true);
break;
}
}
}
}
}