We can use a similar pattern to use a drop dialog to update data on a record, the vehicle group in this case.
To do this, the contract and update classes are nearly identical to the earlier status change logic. We are simply updating the vehicle group. The steps required for this are similar as before, except that we will use a drop dialog form instead of menu items. It is not ideal to use menu items, as vehicle groups are defined in data. It is, therefore, far more natural to select the vehicle group with a drop-down list control.
We will be following the same pattern as before, so a summary of the first part of this task is listed as follows:
ConFMSVehicleGroupChangeContract
, adding the [DataContractAttribute]
decoration above classDeclaration
.classDeclaration
for the vehicleId
and vehicleGroupId
using their EDTs.[DataMemberAttribute]
decoration.construct
static method as usual.ConFMSVehicleGroupChange
, and use the following methods:public static ConFMSVehicleGroupChange construct()
public ConFMSVehicleGroupChangeContract parmContract(…)
public static ConFMSVehicleGroupChange newFromContract(..)
private void updateVehicle
public boolean validate()
public void run()
public void runContract(…)
There is a temptation to duplicate the vehicle status classes and then modify them for the new situation. This isn't necessarily a bad idea, but it is very vitally important to ensure that every part is modified appropriately. Failure to do this is one of the biggest causes of errors. AX's helpfulness in casting between EDTs of the same base type will allow us to use a vehicle group ID to check whether a record exists in the vehicle table. It will assume that we intended to cast the types. This is another benefit of using data contracts; we will not be allowed to cast between them.
The next step is to create the user interface—a drop dialog. This is done by the following steps:
ConFMSVehicleGroupChange
and drag this onto your project.classDeclaration
, we declare our contract as follows:public class FormRun extends ObjectRun { ConFMSVehicleGroupChangeContract contract; }
element
object (the instance of the form) contains an args
object, which we will use to construct the contract
class:public void init() { ConFMSVehicleTable callerVehicle; super(); switch(element.args().dataset()) { case tableNum(ConFMSVehicleTable): callerVehicle = element.args().record(); break; } if(callerVehicle.RecId == 0) { throw error("@SYS79604"); } contract = ConFMSVehicleGroupChangeContract::construct(); contract.vehicleId(callerVehicle.VehicleId); contract.vehicleGroupId(callerVehicle.VehicleGroupId); }
The this
variable has a different meaning in the context of forms. It means the element or control within the form that the current method is acting on. This could be the form, a data source, a field, or a control. The element
object always refers to the instance of the form. If we are in the Methods
node of the form, this
and element
are the same thing, but it is good practice to use element regardless when we are referring to the form instance.
edit
method that acts on a data source for the vehicle group drop-down control, but unlike before, we are using the contract
as our storage:public edit ConFMSVehicleGroupId editVehicleGroupId( boolean _set, ConFMSVehicleGroupId _vehicleGroupId) { if (_set) { contract.vehicleGroupId(_vehicleGroupId); } return contract.vehicleGroupId(); }
public boolean updateVehicle() { ConFMSVehicleGroupChange change; FormDataSource callerDS; change = ConFMSVehicleGroupChange::newFromContract(contract); if(change.validate()) { change.run(); if(element.args().record().isFormDataSource()) { callerDS = element.args().record().dataSource(); callerDS.research(true); return true; } } Return false; }
MainInstruction
control. We don't really need the SupplementalInstruction
, so we can delete this control.edit
method onto the DialogContent
group so that it is below the MainInstruction
.OKButton
and override its clicked
method.super()
method triggers several form events, one of which closes the form. We only need our updateVehicle
to be called, and we need to close the form only on success, allowing the user to correct any data entry uses without having to reopen the form:void clicked() { if(element.updateVehicle()) { super(); } }
ConFMSVehicleGroupChangeButton
.ConFMSVehicleGroupChange
.Finally, it is important to understand what is happening and feel comfortable with this pattern. To challenge yourself, try the preceding steps for the vehicle schedule, and consider what might happen to the existing vehicle service records.
3.144.47.218