Previously, I explained how to use View Details to navigate to a related form. After that, I explained how override this functionality to navigate to a different form by overriding the D365 jumpRef method. Lastly, I will explain how to override the JumpRef on a base Microsoft form.
Why Are Base Microsoft Forms Different?
Unlike a custom form you created, you cannot simply override the jumpRef the method directly on the form. This is because the code part of a base Microsoft form is locked.
Therefore, you must use chain of command or an event handler class to add code to the form. And then you must add code to let the form know which method to use.
Overview
In order to override the JumpRef on a base D365 form control there are three steps. I will list the high level steps, then go over each steps in detail.
- First, on the base D365 form, locate the form control that you want to override the JumpRef on. Then, write down the name of the control.
- Secondly, create a new chain of command or handler class to implement the new JumpRef method.
- Thirdly, create a chain of command or handler class to add code that will run after the form is initialized. The code in this method will tell the form to use the JumpRef method you created in step two.
Record The Form Control Name
In order to later write a jumpRef method, we need to know the name of the form control.
To demonstrate how to override the jumpRef on a D365, I am going to create an example. You likely already have a form control that you need to override. But if not, the below example will create this scenario.
In this example, we will add a default store ID to the customer record. And override the jumpRef, so this form control will take the user to a different form.
Create A Visual Studio Project
First, create a D365 project in Visual Studio. Make sure the synchronize on database property is set to true on the project. And set the model of the project to your custom model.
Create A Custom Field On A Base Table
Second, create an extension of the the CustTable table. To do so, search the Application Explorer for ‘CustTable’. Then, right click on the CustTable object under ‘Tables‘ and select ‘Create extension‘. Double click on the created object to open it up.
Third, right-click on the Fields node of your extension object, and select New>String.
Set the name of the field to ‘tutStoreID’. ‘tut’ is short for tutorial. Next, set the Extended Data to ‘RetailStoreId’.
Extend A Base Form
Fourth, create an extension of the the CustTable form. To do so, search the Application Explorer for ‘CustTable’. Then, right click on the CustTable object under ‘Form‘ and select ‘Create extension‘. Double click on the created object to open it up.
Lastly, write down the name of the form control. In this case the name is ‘CustTable_tutStoreId’. Now, build your solution.
Remember, the jumpRef of an existing form control can be overridden as well. I just chose to add a new custom form Control for this example.
Try It Out
To see the new field, go to Accounts Receivable>Customers>All customers. Then, click on a customer in the grid. Notice the ‘Store number‘ field that is now shown under the General fast tab.
Note, the Extended Data Type ‘RetailStoreID‘ already has a relation on it. This will cause the the ‘lookup’ to show stores in the RetailStoreTable. You can also click on the blue text to navigate to the store setup form. However, for this example, we can change how the jumpRef works.
Create A Separate Class
On a custom form, we can just override the jumpRef on the form control. However, on a base Microsoft form, we are not allowed to modify the base form’s code directly. Therefore, we need to create a separate class to store this code. And then link this code back to the form.
There are two ways to do this in D365. We can either do this using Chain of Command. Or we can use an Event Handler. I prefer to use Chain of Command. However, I will show both ways of doing this.
Chain Of Command Example
First, we need to create a new Chain of Command class for our form.
Right click on the project, and select Add>New Item.
Select the ‘Class‘ object type, and then provide a name. I named my class ‘tutCustTable_Form_Extension‘. Then, click the ‘Add button’.
Add JumpRef method
Modify the code in the editor to have the following code:
[ExtensionOf(formStr(CustTable))]
final class tutCustTable_Form_Extension
{
public void tutStoreIdJumpRef(FormControl _formControl)
{
Args args = new Args();
MenuFunction menuFunction;
RetailStoreTable retailStoreTable;
retailStoreTable = RetailStoreTable::find(_formControl.valueStr());
args.record(retailStoreTable);
menuFunction = new MenuFunction(menuitemdisplaystr(RetailStoreHours),MenuItemType::Display);
menuFunction.run(args);
}
}
The code “[ExtensionOf(formStr(CustTable))]” above the class declaration tells the system that this class is extending the code that already exists on the CustTable form.
Next, the method “tutStoreIdJumpRef’ implements the jumpRef method. See my article on How To Override The D365 JumpRef for an explanation of this code. There are a few things I want to point out.
First, this method can be named whatever you choose. But we need to remember it for the next step.
Second, this method requires us to pass in the _formControl parameter so that we can use the value currently in that control to filter the calling form.
Thirdly, in this example, I am calling the form ‘RetailStoreHours‘. Typically, this field should call ‘RetailStoreTable‘. But I am changing this to demonstrate what overriding the jumpRef can do.
Register Override Method
Now that we have written the new jumpRef method, we need to tell the system to run this method instead of the existing method. First, add the code below to the same Chain of Command class. Then I will explain.
public void init()
{
FormStringControl formStringControl;
next init();
formStringControl = this.design().controlName(formControlStr(CustTable, CustTable_tutStoreId));
formStringControl.registerOverrideMethod(methodStr(FormStringControl, jumpRef)
, methodStr(tutCustTable_Form_Extension, tutStoreIdJumpRef));
}
To do this, we need to do three things:
First, we need to use the name of the form and the form control to store that object into a variable in code.
formStringControl = this.design().controlName(formControlStr(CustTable, CustTable_tutStoreId)
Secondly, we need to call the ‘registerOverrideMethod‘ on the form control to tell the system to use the our method named ‘tutStoreIdJumpRef‘ on our class named ‘tutCustTable_Form_Extension‘ instead of the existing method named ‘jumpRef‘.
formStringControl.registerOverrideMethod(methodStr(FormStringControl, jumpRef)
, methodStr(tutCustTable_Form_Extension, tutStoreIdJumpRef));
Thirdly, these two lines of code need to be added to an overridden ‘init‘ method. The ‘init‘ method is called when the form first opens. And after all of the form controls are created, our code will change how this form control works. We are done.
Event Handler Example
You can also override the jumpRef method by writing Event Handler code. The only real difference is the attributes written in the class. And the ‘sender’ parameter is passed into the eventHandler method, instead of using the ‘this’ variable that is used in Chain of Command. See the following example code:
class tutCustTable_Form_Handler
{
[FormEventHandler(formStr(CustTable), FormEventType::Initialized)]
public static void CustTable_OnInitialized(xFormRun sender, FormEventArgs e)
{
FormStringControl control = sender.design().controlName(formControlStr(CustTable, CustTable_tutStoreId));
control.registerOverrideMethod(methodStr(FormStringControl, jumpRef), methodStr(tutCustTable_Form_Handler, tutStoreIdJumpRef), sender);
}
public void tutStoreIdJumpRef(FormControl _formControl)
{
Args args = new Args();
MenuFunction menuFunction;
RetailStoreTable retailStoreTable;
retailStoreTable = RetailStoreTable::find(_formControl.valueStr());
args.record(retailStoreTable);
menuFunction = new MenuFunction(menuitemdisplaystr(RetailStoreHours),MenuItemType::Display);
menuFunction.run(args);
}
}
Conclusion
This this tutorial, you learned how to use registerOverrideMethod in the ‘init‘ method to replace the existing code in the jumpRef method with new code. This is needed when overriding the jumpRef method on a base Microsoft form, because the code on the form cannot be modified directly.
In my case, after I set the field’s ‘Extended Data Type’ property to ‘RetailStoreId’, the property ‘Ignore EDTRelation’ was set to ‘Yes’ by default, and I had to change it to ‘False’ to have this field lookupable on the form.
Hi Peter.
Your Event Handler Example didn’t work for me. View Details cause an error.
I had to modify it to make it work.
Hmm. Ok. I can look into that. What change did you need to make in order for it to work?
Hi Peter.
I changed the third parameter in the method ‘registerOverrideMethod’ from ‘sender’ to the instance of ‘tutCustTable_Form_Handler’ class.
And so it started working.
This is my version of the class:
class tutCustTable_Form_Handler
{
[FormEventHandler(formStr(CustTable), FormEventType::Initialized)]
public static void CustTable_OnInitialized(xFormRun sender, FormEventArgs e)
{
var tutCustTable_Form_Handler = new tutCustTable_Form_Handler();
FormStringControl control = sender.design().controlName(formControlStr(CustTable, CustTable_tutStoreId));
control.registerOverrideMethod(methodStr(FormStringControl, jumpRef),
methodStr(tutCustTable_Form_Handler, tutStoreIdJumpRef),
tutCustTable_Form_Handler
);
}
public void tutStoreIdJumpRef(FormControl _formControl)
{
Args args = new Args();
MenuFunction menuFunction;
RetailStoreTable retailStoreTable;
retailStoreTable = RetailStoreTable::find(_formControl.valueStr());
args.record(retailStoreTable);
menuFunction = new MenuFunction(menuitemdisplaystr(RetailStoreHours), MenuItemType::Display);
menuFunction.run(args);
}
}
Thanks, MIKHAIL POLIAKOV both of your inputs were helpful.
Peter, you should incorporate these steps into this tutorial because people rarely look into the comments section for suggestions.
Agreed. I will look into to making updates shortly. Thanks.