EVENT HANDLERS IN D365
With D365 event handlers play very important and hence we need to know how and when to use them to maximum benefit.
Below are some of the codes which uses event handlers in different situation and how the form source are cached.These code needs to be return in a new class with final.
eg.
final
class
HcmPos_Extension
{
}
if you decorate your class with the [ExtensionOf(formStr(HcmPosition ))] then you can also write the code for the table extensions
in the same class.
So let us consider the form HcmPosition .
In order to create an event handler for a method just right click and copy the event handler as shown below.
1)
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
[FormEventHandler(formStr(HcmPosition), FormEventType::Initialized)]
public static void HcmPosition_OnInitialized(xFormRun sender, FormEventArgs e)
{
FormDataSource hcmposition_ds = sender.dataSource(formDataSourceStr(HcmPosition, HcmPosition));
//you can also directly specify the datasource name - > //sender.dataSource('HcmPosition');
}
As shown in the above example you can get the datasource and do further coding as per the requirement.
[FormEventHandler(formStr(HcmPositionMassUpdate), FormEventType::Initialized)]
public static void HcmPositionMassUpdate_OnInitialized(xFormRun _sender, FormEventArgs _e)
{
// Initialize the instance of this form extension handler now that the controls exist
FormRun positionMassUpdateForm = _sender as FormRun;
HcmPositionMassUpdateFormEventHandler extensionInstance = positionMassUpdateForm.getExtensionInstance(classStr(HcmPositionMassUpdateFormEventHandler));
extensionInstance.init();
}
2) how to get the current selected record in the event handler when clicked on some button.
Below code will give you the selected record in the hcmposition variable.
You can get the form run also.
[FormControlEventHandler(formControlStr(HcmPosition, HcmPositionNewPosition), FormControlEventType::Clicked)]
public static void HcmPositionNewPosition_OnClicked(FormControl sender, FormControlEventArgs e)
{
HcmPosition hcmposition = sender.formRun().dataSource(1).cursor();//hcmposition is the //primary datasource.
FormButtonControl callerButton = sender as FormButtonControl; //Retrieves the button
FormRun form = sender.formRun(); //Gets the formRun
In case you want to select any other datasource you can do the following
FormDataSource hcmWorker_ds = form.dataSource(formDataSourceStr(HcmWorker, HcmWorker)) as FormDataSource;
FormDataSource HcmPositionDetail_ds= form.dataSource(formDataSourceStr(HcmWorker, HcmPositionDetail)) as FormDataSource;
HcmWorker hcmWorker = hcmWorker_ds.cursor();
//Set up args with all of the information you've retrieved
}
3) In order to get the formrun use the below
FormRun formRun = sender.formRun() as FormRun;
4) In order to validate a std field you will have to use the below code.
/// <summary>
/// Event handler for the validated event on the BudgetPurposeType field on the HcmTmpBudgetPurposeType data source on the HcmPositionMassUpdate form.
/// </summary>
/// <param name="_sender">The form control raising the event.</param>
/// <param name="_e">Args for the event.</param>
[FormDataFieldEventHandler(formDataFieldStr(HcmPositionMassUpdate, HcmTmpBudgetPurposeType, BudgetPurposeType), FormDataFieldEventType::Validated)]
public static void BudgetPurposeType_OnValidated(FormDataObject _sender, FormDataFieldEventArgs _e)
{
HcmTmpBudgetPurposeType tmpBudgetPurposeTypeLocal;
HcmTmpBudgetPurposeType hcmTmpBudgetPurposeType = _sender.datasource().cursor();
// Validate for duplicates.
tmpBudgetPurposeTypeLocal.setTmpData(hcmTmpBudgetPurposeType);
select firstonly RecId from tmpBudgetPurposeTypeLocal
where tmpBudgetPurposeTypeLocal.BudgetPurposeType == hcmTmpBudgetPurposeType.BudgetPurposeType
&& tmpBudgetPurposeTypeLocal.LegalEntity == hcmTmpBudgetPurposeType.LegalEntity;
if (tmpBudgetPurposeTypeLocal.RecId)
{
throw error("@Workforce:TheBudgetPurposeTypeIsAlreadyInUse");
}
}
3) Similarly if you want to write code on form modified or active on initialize you can use the below code
Sales Table Form --> Events --> OnActivated
////</summary>
////<param name="sender"></param>
////<param name="e"></param>
[FormDataSourceEventHandler(formDataSourceStr(SalesTable, SalesTable), FormDataSourceEventType::Activated)]
public static void SalesTable_OnActivated(FormDataSource sender, FormDataSourceEventArgs e)
{
boolean allowEdit = true;
SalesTable SalesTable = sender.cursor();
FormDataSource salesTable_ds = sender.formRun().dataSource("SalesTable");
FormRun element = sender.formRun();
FormControl ShippingDateRequested = element.design(0).controlName("Delivery_ShippingDateRequested");
if (ShippingDateRequested == datenull())
{
ShippingDateRequested.enabled(false);
}
else
{
ShippingDateRequested.enabled(true);
}
}
similarly you can write pre and post event handlers as below for different tables.
[PostHandlerFor(tableStr(InventTrans), tableMethodStr(InventTrans, AmountMst))]
public static void InventTrans_Post_anyValidateMethod(XppPrePostArgs args)
{
boolean ret = args.getReturnValue();
InventTrans InventTrans = args.getThis() as InventTrans;
if (InventJournalName::find(InventTrans.Qty > 0 && InventTrans.CostPrice == 0)
{
ret = checkFailed(strFmt("Cost Price is 0 for Line %1",InventTrans.LineNum));
}
args.setReturnValue(ret);
}
Below code executes after the standardd init method of the formMethodStr(HcmPositionMassUpdate, init)
if you wan to do somthing befoore the code execution write a pre event handler
/// <summary>
/// Post-event handler for the init method of the HcmPositionMassUpdate form.
/// </summary>
/// <param name="_args">Args for the event.</param>
[PostHandlerFor(formStr(HcmPositionMassUpdate), formMethodStr(HcmPositionMassUpdate, init))]
public static void HcmPositionMassUpdate_Post_init(XppPrePostArgs _args)
{
FormRun positionMassUpdateForm = _args.getThis();
HcmPositionMassUpdateBase positionMassUpdateBase = positionMassUpdateForm.parmPositionMassUpdateBase();
Args args = positionMassUpdateBase.parmFormArgs();
if (args.record() && args.record().TableId == tableNum(HcmPositionForecastScenario))
{
HcmPositionMassUpdateFormEventHandler::disableFinancialDimensionTab(args, positionMassUpdateForm);
}
}
[DataEventHandler(tableStr(HcmPositionWorkerAssignment), DataEventType::Deleted)]
public static void HcmPositionWorkerAssignment_onDeleted(Common _sender, DataEventArgs _e)
{
HcmWorkerHelper::getDepartmentRecIdsCacheClear();
}
[DataEventHandler(tableStr(HcmPositionWorkerAssignment), DataEventType::Inserted)]
public static void HcmPositionWorkerAssignment_onInserted(Common _sender, DataEventArgs _e)
{
HcmPositionWorkerAssignment positionWorkerAssignment = _sender as HcmPositionWorkerAssignment;
PayrollWorkerTaxRegion::refreshTaxRegionsForWorkerAtPosition(positionWorkerAssignment.Worker, positionWorkerAssignment.Position);
}
In case there are some changes which needs to be done in a standard method in between the code.
/// <summary>
/// </summary>
public void initForm()
{
next initForm();
//do something here.
}
Thanks,
Vikas Mehta.