I think I found a solution for this -
1. Created an extension for base enum - LogisticsLocationAddressActionButtons and added two new elements "CustomNew" and "CustomEdit".

2. Created a three display menu items -
a. TecLogisticsPostalAddressSingleFormPart which references LogisticsPostalAddressSingle form.
b. TecLogisticsPostalAddressNewBankAccountTabl, which is a copy of LogisticsPostalAddressNewBankAccountTabl menu item with enum parameter set to "CustomNew".

c. TecLogisticsPostalAddressEditBankAccountTab, which is a copy of LogisticsPostalAddressEditBankAccountTab menu item with enum parameter set to "CustomEdit".

3. Created an extension of BankAccountTable table and added a new field (TecLocation) with a foreign key relation to LogisticsLocation.
4. Created an extension of BankAccountTable form and added a new tab page with the form part menu item created earlier. We used the new field for the link.

5. Created an extension of class LogisticsLocationFormHandler and added the following methods -
a. parmIsCustomAddress- This method is for identifying is the class instance will be used for custom address.
b. callerWriteCustom - this method is for writing into the custom field of the existing table.
[ExtensionOf(classStr(LogisticsLocationFormHandler))]
final class TecLogisticsLocationFormHandler_Extension
{
public boolean isCustomAddress;
public boolean parmIsCustomAddress(boolean _isCustomAddress = isCustomAddress)
{
isCustomAddress = _isCustomAddress;
return isCustomAddress;
}
public void callerWriteCustom()
{
FormDataSource callerFormDataSource;
BankAccountTable bankAccountTable;
ttsbegin;
callerRecordMap = this.getCallerRecord();
if (callerRecordMap.TableId == tableNum(BankAccountTable))
{
bankAccountTable = callerRecordMap as BankAccountTable;
bankAccountTable.TecLocation = location;
bankAccountTable.write();
}
// reset the dirty state of the dataSource before calling research
if (FormDataUtil::isFormDataSource(callerRecordMap))
{
callerFormDataSource = FormDataUtil::getFormDataSource(callerRecordMap);
callerFormDataSource.forceWrite(false);
}
this.callerResearch();
ttscommit;
// set the form dataSource as dirty and refresh form's country/region code cache
if (callerFormDataSource)
{
callerFormDataSource.forceWrite(true);
callerFormDataSource.formRun().flushCountryRegionCodeCache();
}
}
}
6.Created an extension for form LogisticsPostalAddressSingle and added code to determine if the caller menu item is the new one we created and for setting the menu items created for New and Edit.
[ExtensionOf(formStr(LogisticsPostalAddressSingle))]
final class TecLogisticsPostalAddressSingle_Extension
{
public boolean isCustomAddress;
public boolean parmIsCustomAddress(boolean _isCustomAddress = isCustomAddress)
{
isCustomAddress = _isCustomAddress;
return isCustomAddress;
}
public void init()
{
if(this.args().menuItemName() == menuitemdisplaystr(TecLogisticsPostalAddressSingleFormPart))
{
this.parmIsCustomAddress(true);
}
next init();
if (this.args().dataset() == tableNum(BankAccountTable) && isCustomAddress)
{
newAddress.menuItemName(menuitemdisplaystr(TecLogisticsPostalAddressNewBankAccountTabl));
editAddress.menuItemName(menuitemdisplaystr(TecLogisticsPostalAddressEditBankAccountTab));
}
addressController.parmIsCustomAddress(isCustomAddress);
}
public void buildLogisticsPostalAddressQuery(QueryBuildDataSource _queryBuildDataSource)
{
next buildLogisticsPostalAddressQuery(_queryBuildDataSource);
if(this.parmIsCustomAddress())
{
_queryBuildDataSource.clearRanges();
if (this.args().dataset() == tableNum(BankAccountTable))
{
BankAccountTable callerRecord = this.args().record();
_queryBuildDataSource.addRange(fieldnum(LogisticsPostalAddress, Location)).value(SysQuery::value(callerRecord.TecLocation));
}
else
{
_queryBuildDataSource.addRange(fieldnum(LogisticsPostalAddress, Location)).value(SysQuery::valueEmptyString());
}
}
}
}
7. Created an extension of class LogisticsPostalAddressFormHandler to handle adding the custom address.
[ExtensionOf(classStr(LogisticsPostalAddressFormHandler))]
final class TecLogisticsPostalAddressFormHandler_Extension
{
protected static void logisticsPostaladdressFormOpen(Args _args, boolean _showForm, LogisticsPostalAddressFormHandler _addressController)
{
next logisticsPostaladdressFormOpen(_args, _showForm, _addressController);
switch (_args.parmEnum())
{
case LogisticsLocationAddressActionButtons::CustomNew :
case LogisticsLocationAddressActionButtons::CustomEdit :
LogisticsPostalAddressFormHandler::openCustomForm(_args, _showForm);
break;
}
}
public static void openCustomForm(Args _args, boolean _showForm = true)
{
Args args;
FormRun addressForm;
LogisticsPostalAddressFormHandler singleAddressCtrlr;
singleAddressCtrlr = _args.parmObject() as LogisticsPostalAddressFormHandler;
// can't be called without a controller
if (!singleAddressCtrlr)
{
throw error(Error::wrongUseOfFunction(funcname()));
}
singleAddressCtrlr.setOpenMode(_args.openMode());
args = new Args();
args.name(formstr(LogisticsPostalAddress));
args.record(_args.record());
args.openMode(_args.openMode());
args.parmObject(singleAddressCtrlr);
args.caller(_args.caller());
addressForm = classfactory.formRunClass(args);
if (addressForm)
{
addressForm.init();
if (_showForm)
{
addressForm.run();
addressForm.wait();
if (addressForm.closedOk())
{
// This will make sure that the main entity is updated with the postal address location
if (singleAddressCtrlr && args.openMode() != OpenMode::View)
{
singleAddressCtrlr.callerWriteCustom();
}
// Refresh the address display
if (args.record() && FormDataUtil::isFormDataSource(args.record()))
{
FormDataSource callerDatasource = args.record().dataSource() as FormDataSource;
callerDatasource.reread();
}
}
}
}
}
}
You can create new enum elements in the base enum extension for map and clear operations and add logic for those functions.