How to do it...

First, we will create the settings table for the fields that we want to allow defaults for. To do so, follow these steps:

  1. Create a new table named ConWHSVehicleTableDefaults.
This particular sample will be fixed to the vehicle table, but you should be able to extend this to work with any table you desire.
  1. Locate the Extended data types (EDT) RefFieldName, and RefFieldLabel in the Application Explorer and drag them to the Fields node of the table. Make the RefFieldLabel field read-only.
  2. Drag the EDT String255 to the Fields node and rename the field to DefaultValueStr. Create a label for Default value, and set the Label property to it.

The pattern for this type of table would normally continue by adding a field for each base type, and the form would use a handler to show the relevant field base on the field's base type. In this case, we will stop at string, so as to not detract from the main focus of this recipe.

  1. Create field groups, as shown in the following table:

Group name

Label

Fields

Overview

@ConWHS:Overview

RefFieldName

RefFieldLabel

DefaultValue

@SYS40175

DefaultValueStr

  1. Create a unique index for RefFieldName and make it the table's Clustered index.
  2. Complete the table properties, as shown in the following table:

Property

Fields

Label

New label

Vehicle table defaults

Title Field 1

RefFieldLabel

Title Field 2

DefaultValueStr

Cache Lookup

EntireTable

Clustered Index

FieldNameIdx

Table Group

Group

<Tracking fields>

As desired, it may be useful to know who last changed it.

  1. Create a standard Find and Exist method, as shown in the following code:
public static boolean Exist( 
RefFieldName _fieldName)
{
ConWHSVehicleTableDefaults table;

if(_fieldName != '')
{
select firstonly RecId from table
where table.RefFieldName == _fieldName;
}
return (table.RecId != 0);
}
public static ConWHSVehicleTableDefaults Find(
RefFieldName _fieldName,
boolean _forUpdate)
{
ConWHSVehicleTableDefaults table;

if(_fieldName != '')
{
table.selectForUpdate(_forUpdate);
select table
where table.RefFieldName == _fieldName;
}
return table;
}
  1. The RefFieldName field will be a field name from the ConWHSVehicleTable; since we work with IDs, it is useful to have a helper function that returns this ID. Create the following method:
private RefFieldId GetFieldId( 
RefFieldName _fieldName = this.RefFieldName)
{
return fieldName2Id(tableNum(ConWHSVehicleTable),
_fieldName);
}

We will allow the field name to be passed so that we can get the field ID for a name not currently updated to the current record.

  1. Next, create a new method that sets RefFieldLabel from the field's metadata, as shown in the following code:
public void InitFromFieldName() 
{
RefFieldId fieldId = this.GetFieldId();
if(fieldId == 0)
{
this.RefFieldName = '';
this.RefFieldLabel = '';
return;
}
DictField dField = new DictField(
tableNum(ConWHSVehicleTable), fieldId);
if(dField)
{
this.RefFieldLabel = dField.label();
}
}
  1. Now, insert and override the method for modifiedField to call the InitFromFieldName method as follows:
public void modifiedField(FieldId _fieldId) 
{
super(_fieldId);
switch (_fieldId)
{
case fieldNum(ConWHSVehicleTableDefaults,
RefFieldName):
this.InitFromFieldName();
break;
}
}
  1. The field selected must exist, be of type String, and be editable on create. To make the code easier to read, we should create a check function for this, which is written as follows:
public boolean CheckRefFieldName( 
RefFieldName _fieldName = this.RefFieldName,
boolean _silent = false)
{
boolean ok = true;
ErrorMsg msg = '';

RefFieldId fieldId = this.GetFieldId(_fieldName);
If (fieldId == 0)
{
ok = false;
//Field %1 does not exist in table %2
msg = strFmt("@SYS75684",
this.RefFieldName,
tableStr(ConWHSVehicleTable));
}

DictField dField = new DictField(
tableNum(ConWHSVehicleTable), fieldId);
if (dField)
{
if(dField.baseType() != Types::String)
{
ok = false;
// Type is not supported %1
msg = strFmt("@SYS73815", dField. baseType ());
}
if(!dField.allowEditOnCreate())
{
ok = false;
//The field %1 cannot be selected.
msg = strFmt("@SYS70689", this.RefFieldName);
}
}
If (!ok && !_silent)
{
return checkFailed(msg);
}
return ok;
}

The method accepts the _silent parameter as we will want to use the same logic to build the lookup later.

  1. We will now call the check method in the preceding code to the validateField form triggered event. Override the validateField method, as shown here:
public boolean validateField(FieldId _fieldIdToCheck) 
{
boolean ret;

ret = super(_fieldIdToCheck);
switch (_fieldIdToCheck)
{
case fieldNum(ConWHSVehicleTableDefaults,
RefFieldName):
ret = this.CheckRefFieldName();
break;
}
return ret;
}
  1. Finally, we will need a lookup function that only allows the user to select fields that are valid. The code is as follows:
public static void LookupFieldName( 
FormStringControl _control)
{
FormRun formRun;
Args args;
Map fieldmap;

DictTable dTable;
Counter idx;
RefFieldId fieldId;
ConWHSVehicleTableDefaults defaultsRecord;

defaultsRecord = _control.dataSourceObject().cursor();

fieldMap = new Map(Types::String, Types::String);
dTable = new DictTable(tableNum(ConWHSVehicleTable));
for (idx = 1; idx <= dTable.fieldCnt(); idx ++)
{
fieldId = dTable.fieldCnt2Id(idx);
RefFieldName fieldName = fieldId2Name(dTable.id(),
fieldId);
if (defaultsRecord.CheckRefFieldName(fieldName,
true))
{
fieldMap.insert(fieldName, fieldName);
}
}

args = new Args(formStr(SysPick));
args.parmEnumType(enumNum(SysPickListType));
args.parmEnum(enum2int(SysPickListType::Simple));
Args.parmObject(fieldMap);
formRun = classfactory.formRunClass(args);

_control.performFormLookup(formRun);
formRun.wait();
}
  1. Next, create a new form named ConWHSVehicleTableDefaults and drag the new table to its Data Sources node.
    1. Complete the design of the form based on the Simple List and Details - List Grid form pattern.
    1. Complete the form as per the pattern requirements, using the Overview group for NavigationListGroup. The completed design should look like the following screenshot:
    Remember to name the controls after the template name, as this makes the design easier to work with. The template will make the wrong assumptions about which control matches the template section until all the template sections have matching controls.
    1. We will now need to override the lookup for the field name, expand the Data Sources node, and locate the RefFieldName field under the ConWHSVehicleTableDefaults data source's Fields node.
      1. Right-click on the field's Methods node and select Override | lookup.
        1. In the code editor that opens, remove the line super(_formControl, _filterStr); and replace it with the following line:
        ConWHSVehicleTableDefaults::LookupFieldName(_formControl); 
        
        1. Create a display menu item and add it to the Setup submenu of ConWHSVehicleManagement.
          1. Finally, complete the Form Ref property of the ConWHSVehicleTableDefaults table and build the project, including database synchronization as we have added a new table.

          We have now completed the set up table and form, we can now create a handler so that the table's defaults are set. To do this, follow these steps:

          1. Create a new class named ConWHSVehicleTableDefaultingEngine.
            1. Write the following lines of code to initialize the instance:
            private ConWHSVehicleTable  vehicle; 

            public ConWHSVehicleTable Vehicle(
            ConWHSVehicleTable _vehicle = vehicle)
            {
            vehicle = _vehicle;
            return vehicle;
            }

            public static ConWHSVehicleTableDefaultingEngine
            NewFromVehicleTable(ConWHSVehicleTable _vehicle)
            {
            ConWHSVehicleTableDefaultingEngine engine;
            engine = new ConWHSVehicleTableDefaultingEngine();
            engine.Vehicle(_vehicle);
            return engine;
            }
            1. Then, write the methods that perform the update, which are as follows:
            private void ProcessDefaults() 
            {
            ConWHSVehicleTableDefaults defaults;
            while select defaults
            {
            RefFieldId fieldId = fieldName2Id(
            vehicle.TableId,
            defaults.RefFieldName);
            if(fieldId)
            {
            DictField dField;
            dField = new DictField(vehicle.TableId,
            fieldId);
            switch (dField.baseType())
            {
            case Types::String:
            vehicle.(fieldId) =
            defaults.DefaultValueStr;
            break;
            }
            if(vehicle.validateField(fieldId))
            {
            vehicle.modifiedField(fieldId);
            }
            else
            {
            switch (dField.baseType())
            {
            case Types::String:
            vehicle.(fieldId) = '';
            break;
            }
            }
            }
            }
            }

            public boolean Validate()
            {
            if(vehicle.RecId != 0)
            {
            //Cannot default records that already exist
            return checkFailed("@ConWHS:ConWHS61");
            }
            return true;
            }

            public void Run()
            {
            if(!this.Validate())
            {
            return;
            }
            this.ProcessDefaults();
            }
            1. The final method is the data event handler, which will trigger when the record is being initialized, and it is written as follows:
            [DataEventHandlerAttribute(tableStr(ConWHSVehicleTable), 
            DataEventType::InitializingRecord)]
            public static void InitValueEventHandler(
            Common _record,
            DataEventArgs _eventArgs)
            {
            ConWHSVehicleTableDefaultingEngine engine;
            engine = ConWHSVehicleTableDefaultingEngine::
            NewFromVehicleTable(_record);
            engine.Run();
            }
            1. Finally, build and run the project. Test the code by creating a set of defaults in the new Vehicle table default values form, and then create a new vehicle using the Vehicles form.
              1. Try adding the Vehicle group as a default with a value that doesn't exist; you should get an error when a new record is created: The value 'invalid value' in field 'Vehicle group' is not found in the related table 'Vehicle groups'.
              ..................Content has been hidden....................

              You can't read the all page of ebook, please click here login for view all page.
              Reset
              3.136.22.50