The post is related to the masterdata synchronization.
I wanted to give end-users an explanation why they cannot change some of the fields in a synchronized records. I decided to create a generic way of alerting the end-user, like you see in the screenshot below, and also to lock any fields that is synchronized.
So if a record is originating from another master-company, then the following yellow text will be visible. Doing this on a single form is surely easy, but I wanted to create a generic solution that has Zero footprint, and NOT making any changes to any standard form.
Can it be done ? Yes π
So what I did, was to create a event handler on the info.formNotify():
Then the code looks like this (the code contains some ColSync* references, but you see the idea:
public static void colSyncEnableFields(XppPrePostArgs _args) { FormRun formRun; FormDesign formDesign; FormNotify event; FormNotifyEventArgs eventArgs; ColSyncCache colSyncCache; Common common; ColSyncLine colSyncLine; ColSyncTable colSyncTable; ColSyncDefinition colSyncDefinition; ColSyncDestinations colSyncDestinations; FormGroupControl actionBarGroup; FormActionPaneControl actionPane; FormGroupControl firstGroup; int defaultBackgroundColor; FormStaticTextControl actionBarMessageText; int i; #define.SyncActionBarGroup('SyncActionBarGroup') #define.SyncActionBarMessageText('SyncBarMessageText') event = _args.getArg('event'); eventArgs = _args.getArg('eventArgs'); switch (event) { case FormNotify::RecordChange: if ((eventArgs != null) && (eventArgs.formDataSource())) { formRun = _args.getArg('formRun'); colSyncCache = ColSyncCache::construct(); common = eventArgs.formDataSource().getFirst(true) ? eventArgs.formDataSource().getFirst(true) : eventArgs.formDataSource().cursor(); if (common.RecId && colSyncCache.isSyncEnabledDestination(common)) { formDesign = formrun.design(); for (i=1; i<=formDesign.controlCount(); i++) { if ((formDesign.controlNum(i).handle() == classNum(FormActionPaneControl))) { actionPane = formDesign.controlNum(i); break; } } formRun.lock(); if (actionPane != null) { for (i=1; i<=formDesign.controlCount(); i++) { if ((formDesign.controlNum(i).handle() == classNum(FormGroupControl) && formDesign.controlNum(i).name() == #SyncActionBarGroup )) { actionBarGroup = formDesign.controlNum(i); break; } } if (!actionBarGroup) actionBarGroup = formDesign.addControl(FormControlType::Group, #SyncActionBarGroup, actionPane); } // add directly to top of form design else { for (i=1; i<=formDesign.controlCount(); i++) { if ((formDesign.controlNum(i).handle() == classNum(FormGroupControl) && formDesign.controlNum(i).name() == #SyncActionBarGroup )) { actionBarGroup = formDesign.controlNum(i); break; } } if (!actionBarGroup) { // find the first group control on form (if one exists) for (i=1; i<=formDesign.controlCount(); i++) { if ((formDesign.controlNum(i).handle() == classNum(FormGroupControl))) { firstGroup = formDesign.controlNum(i); break; } } if(firstGroup) { actionBarGroup = firstGroup.addControl(FormControlType::Group, #SyncActionBarGroup); actionBarGroup.top(FormTop::Auto); } else { actionBarGroup = formDesign.addControl(FormControlType::Group,#SyncActionBarGroup); actionBarGroup.top(1, FormTop::Auto); } } } defaultBackgroundColor = formDesign.backgroundColor(); actionBarGroup.frameType(FormFrameType::None); actionBarGroup.height(27); actionBarGroup.hideIfEmpty(false); actionBarGroup.topMargin(1); actionBarGroup.bottomMargin(1); actionBarGroup.widthMode(FormWidth::ColumnWidth); actionBarGroup.colorScheme(FormColorScheme::RGB); actionBarGroup.verticalSpacingValue(0); if (System.Windows.SystemParameters::get_HighContrast()) { actionBarGroup.colorScheme(FormColorScheme::WindowsPalette); actionBarGroup.backgroundColor(WindowsPalette::TooltipBackground); } else { actionBarGroup.colorScheme(FormColorScheme::RGB); actionBarGroup.backgroundColor(WinAPI::RGB2int(255,255,153)); } // don't reserve space for details forms if (formDesign.style() == FormStyle::DetailsFormMaster || formDesign.style() == FormStyle::DetailsFormTransaction) { actionBarGroup.visible(false); } for (i=1; i<=actionBarGroup.controlCount(); i++) { if ((actionBarGroup.controlNum(i).handle() == classNum(FormStaticTextControl))) { actionBarMessageText = actionBarGroup.controlNum(i); if (actionBarMessageText && actionBarMessageText.name() == #SyncActionBarMessageText) break; } } if (!actionBarMessageText) { actionBarMessageText = actionBarGroup.addControl(FormControlType::StaticText, #SyncActionBarMessageText, actionBarGroup); } actionBarMessageText.backStyle(FormBackStyle::Opaque); actionBarMessageText.colorScheme(FormColorScheme::RGB); actionBarMessageText.backgroundColor(WinAPI::RGB2int(255,255,153)); actionBarMessageText.widthMode(FormWidth::ColumnWidth); actionBarMessageText.text(strFmt("@SYN112")); actionBarMessageText.visible(true); formRun.unLock(); while select SyncFieldId from colSyncLine group by SyncFieldId where colSyncLine.SyncTableId == eventArgs.formDataSource().table() && colSyncLine.SyncType == ColSyncType::SynchronizeField exists join colSyncTable where colSyncTable.SyncId == colSyncLine.SyncId && colSyncTable.SyncTableId == colSyncLine.SyncTableId && colSyncTable.SyncActive == NoYes::Yes exists join colSyncDefinition where colSyncDefinition.SyncId == colSyncLine.SyncId && colSyncDefinition.SyncActive == NoYes::Yes exists join colSyncDestinations where colSyncDestinations.SyncId == colSyncLine.SyncId && colSyncDestinations.ToDataAreaId == common.dataAreaId && colSyncDestinations.LockSyncFields == true { eventArgs.formDataSource().object(colSyncLine.SyncFieldId).allowEdit(false); } eventArgs.formDataSource().allowCreate(false); eventArgs.formDataSource().allowDelete(false); } else if (common.RecId && colSyncCache.isGlobalTableEnabled(common)) { eventArgs.formDataSource().allowCreate(false); eventArgs.formDataSource().allowEdit(false); eventArgs.formDataSource().allowDelete(false); } } break; } }