Extending the Content Gate Connector

It is possible to make a customization to the Content Gate button and it's logic. In the following examples the possibilities are explained.

The following options of customization are available:

###Example 1

  • Override the hiding of the new buttons in the DocuView (paperclip)
  • Override the default handling when clicking on the default Content Gate button.

###Example 2

  • Override (hide) the default Content Gate button
  • Add a custom button for opening Content Gate (with a custom action).

###Example 3

  • This example shows another integration method using the standard Content Gate button to show the content for a related entity
  • The related entity is not a form data source
  • The content gate button will be enabled/disabled according the availability of the related entity
  • This example does not have a dependency on the actual content gate model itself (AXTcg), only on the Content Gate foundation model

###Example 4

  • This example shows how to overrule the selection of the data entity when resolving the Content Gate url for a selected record by subscribing to a delegate.

Example 1

/// <summary>
/// This is an example extension class for the ProjTable form. 
/// In this example the default Content Gate button action is overriden.
/// Note that this example only has a dependency on the Content Gate Foundation model (no dependency on the actual content gate model itself)
/// </summary>
[ExtensionOf(formStr(ProjTable))]
final public class AXTcgExamples_Form_ProjTable_Extension
{
    /// <summary>
    /// In this example the default Content Gate button is overridden for the ProjTable form and the hide attachment types is also overridden
    /// </summary>
    public void run()
    {
        next run();
        
        AXTcgf_IFormButtonController contentGateFormButtonController = AXTcgf_ContentGateStub::getFormButtonController(this);
        FormFunctionButtonControl cgButton = contentGateFormButtonController != null ? contentGateFormButtonController.getContentGateButtonControl() : null;        
        if (cgButton != null)
        {
            //override the button with a custom method
            cgButton.registerOverrideMethod(methodStr(FormFunctionButtonControl, clicked), methodStr(AXTcgExamples_Form_ProjTable_Extension, AXTcgExamples_ButtonOverrideClick), this);
        }
        // by default all the attachment types (except note) are hidden. You can override this by the following statement
        AXTcgf_IFormButtonVisibilityController contentGateFormButtonVisibilityController = AXTcgf_ContentGateStub::getFormButtonVisibilityController(this);
        if (contentGateFormButtonVisibilityController)
        {
            contentGateFormButtonVisibilityController.setHideNewButtonsDocuView(false);
        }
    }

    /// <summary>
    /// Custom click method which is used to override the default method. In this example the customer linked to the project is
    /// opened in Content Gate instead of the project.
    /// </summary>
    /// <param name="_formButtonControl">The overridden button control</param>
    public void AXTcgExamples_ButtonOverrideClick(FormFunctionButtonControl _formButtonControl)
    {
        ProjTable project = this.dataSource(1).cursor();
        CustTable customer = CustTable::findByCompany(project.DataAreaId, project.CustAccount);
        if (_formButtonControl && customer)
        {
            Args args = new Args();
            args.record(customer);
            _formButtonControl.menufunction().run(args);
        }
    }

}

In this example the default Content Gate button is overridden by a custom method. You can access the default button from within a form extension by using this logic:

    AXTcgf_IFormButtonController contentGateFormButtonController = AXTcgf_ContentGateStub::getFormButtonController(this);
    FormFunctionButtonControl cgButton = contentGateFormButtonController != null ? contentGateFormButtonController.getContentGateButtonControl() : null;        

Thereafter you can register a custom method to the button:

    cgButton.registerOverrideMethod(methodStr(FormFunctionButtonControl, clicked), methodStr(AXTcgExamples_Form_ProjTable_Extension, AXTcgExamples_ButtonOverrideClick), this);        

In this case not the project is opened in Content Gate but the related Customer. Also are the add buttons in the Docu view made visible. By default these are hidden when the Content Gate button is shown on the form. But it is possible to override this, by using the following logic:

    AXTcgf_IFormButtonVisibilityController contentGateFormButtonVisibilityController = AXTcgf_ContentGateStub::getFormButtonVisibilityController(this);
    if (contentGateFormButtonVisibilityController)
    {
        contentGateFormButtonVisibilityController.setHideNewButtonsDocuView(false);
    }

image.png

The buttons marked red are normally hidden (when the CG button is visible), but in this example they are made visible

Example 2

/// <summary>
/// This is an example extension class for the VendTable form. 
/// In this example the default Content Gate button is hidden and a custom button is added to the form. 
/// Also the record which will be openen in Content Gate is changed from VendTable to PurchTable.
/// </summary>
[ExtensionOf(formStr(VendTable))]
final public class AXTcgExamples_Form_VendTable_Extension
{
    /// <summary>
    /// In this example the default Content Gate button is hidden for the VendTable form.
    /// Note: A new button called AXTcgExamples_CGButton (with property AutoDeclaration set to true) is added in the form extension
    /// </summary>
    public void init()
    {
        AXTcgf_IFormButtonVisibilityController contentGateFormButtonVisibilityController = AXTcgf_ContentGateStub::getFormButtonVisibilityController(this);
        if (contentGateFormButtonVisibilityController)
        {
            contentGateFormButtonVisibilityController.setHideContentGateButton(true);
        }        
        next init();
        if (AXTcgExamples_CGButton)
        {
            AXTcgExamples_CGButton.registerOverrideMethod(methodStr(FormButtonControl, clicked), formmethodStr(VendTable, AXTcgExamples_CGButton_OnClicked), this);
        }
    }

    /// <summary>
    /// In this example there is added a custom Content Gate button and this will not open a vendtable record but instead it will open
    /// a random purchtable record.
    /// </summary>
    /// <param name = "_sender">The sender</param>
    public void AXTcgExamples_CGButton_OnClicked(FormButtonControl _sender) 
    {
        PurchTable purch;
        select firstonly purch where purch.OrderAccount == VendTable.AccountNum;

        // set the new record and caller
        Args args = new Args();
        args.record(purch);
        args.caller(this);

        //call the menu function
        new Menufunction(menuItemActionStr(AXTcg_OpenContentGate), MenuItemType::Action).run(args);
    }

}

In this example the default Content Gate button is hidden by using this logic:

    AXTcgf_IFormButtonVisibilityController contentGateFormButtonVisibilityController = AXTcgf_ContentGateStub::getFormButtonVisibilityController(this);
    if (contentGateFormButtonVisibilityController)
    {
        contentGateFormButtonVisibilityController.setHideContentGateButton(true);
    }        

You can hide or show the Content Gate button anytime, by calling the statement above.

On the form a custom button is added (named AXTcg_Examples_CGButton and property AutoDeclaration set to true) and there is a custom clicked event method attached to it. In this event method the first purchase order from the vendor is taken and opened in Content Gate instead of the Vendor itself.

Example 3

/// <summary>
/// This is an example extension class for the PurchTable form. 
/// This example shows another integration method using the standard Content Gate button to show the content for a related entity.
/// Note:
///  = The related entity is not a form data source
///  = The content gate button will be enabled/disabled according the availability  of the related entity
///  = This example does not have a dependency on the actual content gate model itself (AXTcg), only on the Content Gate foundation model
/// </summary>
[ExtensionOf(formStr(PurchTable))]
final public class AXTcgExamples_Form_PurchTable_Extension
{
    private AXTcgf_IFormButtonController AXTcgExamples_contentGateFormButtonController;
    
    /// <summary>
    /// CoC. Initialize the form
    /// </summary>
    public void init()
    {
        next init();
        // Get the content gate form button controller for the form
        AXTcgExamples_contentGateFormButtonController = AXTcgf_ContentGateStub::getFormButtonController(this);
        if (AXTcgExamples_contentGateFormButtonController)
        {
            // Add supported record types for content gate (this overrides the form data source)
            this.AXTcgExamples_contentGateAddSource(tableNum(ProjTable), true);
            // ... and add any other record types you want to enable content gate on

            // Disable the content gate button by default
            AXTcgExamples_contentGateFormButtonController.enableButtonForSource(null);
        }
    }

    /// <summary>
    /// Add a source for the content gate integration
    /// </summary>
    /// <param name = "_tableId">The source table</param>
    private void AXTcgExamples_contentGateAddSource(TableId _tableId, boolean _warnOnFail = false) 
    {
        if (AXTcgExamples_contentGateFormButtonController && _tableId && AXTcgExamples_contentGateFormButtonController.canAddForSource(_tableId))
        {
            if (!AXTcgExamples_contentGateFormButtonController.addForSource(_tableId) && _warnOnFail)
            {
                warning(strFmt("ContentGate integration for %1 not available", tableId2Name(_tableId)));
            }
        }
    }

    /// <summary>
    /// Event handler for the OnActivated event of the purchtable datasource
    /// </summary>
    /// <param name="_sender">The sender</param>
    /// <param name="_e">The event args</param>
    [FormDataSourceEventHandler(formDataSourceStr(PurchTable, PurchTable), FormDataSourceEventType::Activated)]
    public void PurchTable_OnActivated(FormDataSource _sender, FormDataSourceEventArgs _e)
    {
        if (AXTcgExamples_contentGateFormButtonController)
        {
            // Call the AXTcgf_IFormButtonController.enableButtonForSource() with the record as desired (must be one of the added record types)
            // Here we will use the associated project

            // Enable the content gate button if the purchase order has a project. 
            // This will automatically be the record that will be used when the content gate button is clicked
            AXTcgExamples_contentGateFormButtonController.enableButtonForSource(PurchTable.projTable());
        }
    }

}

This example shows how you can override the standard behavior of the Content Gate button (based on the main form data source) and replace it with the content gate entities of your choice.

    // Get the content gate form button controller for the form
    AXTcgExamples_contentGateFormButtonController = AXTcgf_ContentGateStub::getFormButtonController(this);
    if (AXTcgExamples_contentGateFormButtonController)
    {
        // Add supported record types for content gate (this overrides the form data source)
        this.AXTcgExamples_contentGateAddSource(tableNum(ProjTable), true);
        // ... and add any other record types you want to enable content gate on

        // Disable the content gate button by default
        AXTcgExamples_contentGateFormButtonController.enableButtonForSource(null);
    }
    

The standard Content Gate button can be enabled / disabled depending on the availability of an entity record. This example enables the button from within an OnActivated event handler of the PurchTable data source in case a project exists for the selected purchase order.
Note that last record supplied with the AXTcgf_IFormButtonController.enableButtonForSource() call will automatically be used the next time the content gate button is clicked.

        // Call the AXTcgf_IFormButtonController.enableButtonForSource() with the record as desired (must be one of the added record types)
        // Here we will use the associated project

        // Enable the content gate button if the purchase order has a project. 
        // This will automatically be the record that will be used when the content gate button is clicked
        AXTcgExamples_contentGateFormButtonController.enableButtonForSource(PurchTable.projTable());

Example 4

This example shows how to override the standard behavior of the main table selection when resolving the Content Gate url for a record. This can be done by subscribing to the OnGetEntityRangeInfo delegate.

In this case there are two data entities which have the same main table (ProjTable). It is possible to set a range so when the url is being resolved, this range is applied on the main table and the correct data entity is selected. Normal behavior would be that just the first entity found would be selected.

In this scenario we want to resolve the CDSProjects (ProjCDSProjectEntity) entity when a project has no parent project and the Projects (ProjectEntity) entity when the project has a parent project.

This delegate will be executed when clicking the Send Configuration button in the Content Gate admin section. So after implementing this code, a 'send configuration' is always needed.

internal final class AXTcgExamples_Class_DataEntityResolver
{
    /// <summary>
    /// subscribe to the delegate OnGetEntityRangeInfo.
    /// </summary>
    /// <param name="_entityName">The name of the entity.</param>
    /// <param name="_resultArgs">The result of the executed delegate.</param>
    [SubscribesTo(classStr(AXTcg_DataEntityResolver), delegateStr(AXTcg_DataEntityResolver, OnGetEntityRangeInfo))]
    public static void AXTcg_DataEntityResolver_OnGetEntityRangeInfo(str _entityName, EventHandlerResult _resultArgs)
    {
        container result = conNull();

        if (_entityName)
        {
            if (_entityName == 'ProjectEntity')
            {
                result += [[fieldName2Id(tableName2Id('ProjTable'), 'ParentId'), sysquery::valueEmptyString()]];
                _resultArgs.result(result);
            }
            else if (_entityName == 'ProjCDSProjectEntity')
            {
                result += [[fieldName2Id(tableName2Id('ProjTable'), 'ParentId'), sysquery::valueNotEmptyString()]];
                _resultArgs.result(result);
            } 
        }
    }

}