How to implement dynamic initial values

When creating new records from a Frontend (either GUI for .NET or Angular), the fields of the new record are initialized with the initial values of the ProDataset temp-table fields (INITIAL phrase in the FIELD definition).

Customers may require a more dynamic approach to initialize the fields of a new record.

The Consultingwerk.OERA.BusinessEntity class provides an invokable method called GetInitialValues():

    /**
     * Purpose: Returns a dataset with one record containing the initial values
     * Notes:   Can be overridden in Business Entity implementations to provide
     *          dynamic initial values. The base class implementation will return
     *          the buffer fields initial values. The parameter object's TableNames
     *          is a comma-delimited list. The parameter object's ForeignKeyFields
     *          property is a character array (one element per table) of comma delimited
     *          lists of the provided foreign field names. The foreing field values is a
     *          character array (one element per table) of CHR(1) delimited field
     *          values
     * @param phDataset Used to return the dataset
     * @param poParameter The GetInitialValuesParameter instance with the parameters for this call
     */
    METHOD PUBLIC VOID GetInitialValues (INPUT-OUTPUT DATASET-HANDLE phDataset,
                                         poParameter AS GetInitialValuesParameter):

This method can be invoked from a client to receive a ProDataset with initial values. The ProDataset will contain a single record in every requested temp-table (poParameter:TableNames property of the parameter object) .

Developers can override this method in a specific Business Entity. It's recommended to call the SUPER:GetInitialValues method to initialize the template records in this ProDataset. 

Then developers can modify the values after the SUPER:GetInitialValues call to implement the dynamic initial values. 

CustomerBusinessEntity:GetInitialValues() method
    /**
     * Purpose: Returns a dataset with one record containing the initial values
     * Notes:
     * @param phDataset INPUT-OUTPUT DATASET-HANDLE
     * @param poParameter The GetInitialValuesParameter instance with the parameters for this call
     */
    METHOD PUBLIC OVERRIDE VOID GetInitialValues (INPUT-OUTPUT DATASET-HANDLE phDataset,
                                                  poParameter AS GetInitialValuesParameter):

        SUPER:GetInitialValues (INPUT-OUTPUT DATASET dsCustomer,
                                poParameter) .

        IF CAN-FIND (FIRST eCustomer) THEN DO:
            FIND FIRST eCustomer .

            /* Assign required initial values */
            ASSIGN eCustomer.Name        = "New customer":U
                   eCustomer.CreditLimit = 42 .

        END.

        FIND FIRST eCustomer NO-ERROR .

        ASSIGN phDataset = DATASET dsCustomer:HANDLE .

    END METHOD.

Step-by-step guide

To use the GetInitialValues method to initialize a new record in GUI for .NET, implement the following code in the DatasetController (e.g. CustomerDatasetController)

  1. Subscribe to the BeforeCreateRecord event of the SmartBusinessEntityAdapter or SmartDatasetChildAdapter from the common base class SmartDatasetAdapter

        METHOD PUBLIC VOID RegisterConsumer (poConsumer AS Progress.Lang.Object):
    
            IF TYPE-OF (poConsumer, SmartDatasetAdapter) THEN DO:
    
                CAST (poConsumer, SmartDatasetAdapter):BeforeCreateRecord:Subscribe (BeforeCreateRecordHandler) .
    
            END.
    
        END METHOD.
  2. In the event handler, invoke the GetInitialValues method of the CustomerBusinessEntity and BUFFER-COPY from the received template record into the new record.

        METHOD PRIVATE VOID BeforeCreateRecordHandler (sender AS System.Object,
                                                       e AS BeforeCreateRecordEventArgs):
    
            DEFINE VARIABLE oAdapter        AS SmartBusinessEntityAdapter NO-UNDO .
            DEFINE VARIABLE hDataset        AS HANDLE                     NO-UNDO .
            DEFINE VARIABLE hTemplateBuffer AS HANDLE                     NO-UNDO .
            DEFINE VARIABLE oParameter      AS GetInitialValuesParameter  NO-UNDO .
    
            oAdapter = SmartBusinessEntityAdapter:FromDatasetController(THIS-OBJECT) .
    
            oParameter = NEW GetInitialValuesParameter () .
            oParameter:TableNames = e:TableName .
    
            oAdapter:InvokeMethod ("GetInitialValues":U,
                                   INPUT-OUTPUT DATASET-HANDLE hDataset,
                                   oParameter) .
    
            hTemplateBuffer = hDataset:GET-BUFFER-HANDLE (e:TableName) .
    
            hTemplateBuffer:FIND-FIRST () .
    
            e:BufferHandle:BUFFER-COPY (hTemplateBuffer) .
    
            FINALLY:
                GarbageCollectorHelper:DeleteObject (hDataset) .
            END FINALLY.
    
        END METHOD.

To use the GetInitialValues method to initialize a new record in Angular (SmartComponents NG2), implement set the use-initial-values property of the smart-data-source components.