Example 3 – Linking Multiple Visualizations

Having a created a dynamic picklist for Department, it is not unreasonable that a picklist might also be required for Section and subsequently employee.

The code following can be used for Section.  As with the previous example, the Load method populates the picklist.  However, as Section needs to be linked to Deptment at run time the reusable part also implements iMonitorSubject.

Function Options(*DIRECT)

Begin_Com Role(*EXTENDS #PRIM_OBJT *implements #Prim_dc.iDynamicPicklist #Prim_dc.iMonitorSubject)

Mthroutine Name(Load) Options(*redefine)

#Picklist.RemoveAll

Select Fields(*all) From_File(Sectab) With_Key(#Deptment)

#Picklist.Add( #Section #Secdesc )

Endselect

Endroutine

Mthroutine Name(ApplyMonitoredValue) Options(*Redefine)

#Deptment := #MonitorSubject.GetValue

Endroutine

End_Com

The form following makes use of both the Deptment and Section visualizations.  A monitor is defined with a source of Deptment and a target of Section.  When Deptment changes, the ApplyMonitorValue method in the Section visualization is run.   A reference to the source object is received allowing the GetValue method to be called to obtain the value.

Immediately after the ApplyMonitorValue has finished, the Load method will be run.

Function Options(*DIRECT)

Begin_Com Role(*EXTENDS #PRIM_FORM) Clientheight(304) Clientwidth(589) Left(277) Top(135) Width(605)

Define_Com Class(#Deptment.VisualPicklist) Name(#Deptment) Displayposition(1) Left(8) Parent(#COM_OWNER) Tabposition(1) Top(8) Width(401)

Define_Com Class(#Section.VisualPicklist) Name(#Section) Displayposition(2) Left(8) Parent(#COM_OWNER) Tabposition(2) Top(32) Width(401)

Define_Com Class(#prim_lm) Name(#DepartmentSection) Source(#Deptment) Target(#Section)

Evtroutine Handling(#Deptment.Changed)

* Ensure the Section is valid after a department change

#Section := *null

Select Fields(#Section) From_File(sectab) With_Key(#Deptment)

Leave

Endselect

Endroutine

End_Com

Note how it is still necessary to ensure that the variable values in the form are maintained.  When Deptment changes the user must ensure that section is changed to a reasonable value, in this case, the first section in the table for the new department value.

The code following is for a dynamic picklist for EMPNO.

Function Options(*DIRECT)

Begin_Com Role(*EXTENDS #PRIM_OBJT *implements #Prim_dc.iDynamicPicklist #Prim_dc.iMonitorSubject)

Mthroutine Name(Load) Options(*redefine)

#Picklist.RemoveAll

Select Fields(*all) From_File(pslmst1) With_Key(#Deptment #Section)

#Picklist.Add( #Empno ("&1 &2 (&3)").Substitute( #Givename #Surname #Empno ) )

Endselect

Endroutine

Mthroutine Name(ApplyMonitoredValue) Options(*Redefine)

Case ((#MonitorSubject *As #Prim_objt).ComponentPatternName)

When (= Deptment)

#Deptment := #MonitorSubject.GetValue

When (= Section)

#Section := #MonitorSubject.GetValue

Endcase

Endroutine

End_Com

This is much the same, in concept, as the code for section.  However, note the change to ApplyMonitorValueEmpno needs to know the value of both Deptment and Section.  As the iMonitorSubject received is a reference to the source component, you can use the ComponentPatternName to determine which variable has been changed.
Note that the ComponentPatternName will return the field identifier, so please take care when using this code for fields with names longer than 9 characters, or if the Identifer is different to the Field Name.

If Empno is then added to the form, as following, a further two monitors are required to inform Empno of changes to Deptment and Section.

Function Options(*DIRECT)

Begin_Com Role(*EXTENDS #PRIM_FORM) Clientheight(304) Clientwidth(589) Left(277) Top(135) Width(605)

Define_Com Class(#Deptment.VisualPicklist) Name(#Deptment) Displayposition(1) Left(8) Parent(#COM_OWNER) Tabposition(1) Top(8) Width(401)

Define_Com Class(#Section.VisualPicklist) Name(#Section) Displayposition(2) Left(8) Parent(#COM_OWNER) Tabposition(2) Top(32) Width(401)

Define_Com Class(#EMPNO.VisualPicklist) Name(#Empno) Displayposition(3) Left(8) Parent(#COM_OWNER) Tabposition(3) Top(56) Width(401)

Define_Com Class(#prim_lm) Name(#DepartmentSection) Source(#Deptment) Target(#Section)

Define_Com Class(#prim_lm) Name(#SectionEmployee) Source(#Section) Target(#Empno)

Define_Com Class(#prim_lm) Name(#DepartmentEmployee) Source(#Deptment) Target(#Empno)

Evtroutine Handling(#Deptment.Changed)

* Ensure the Section and Empno are valid after a department change

#Com_owner.GetDefaultSection

#Com_owner.GetDefaultEmpno

Endroutine

Evtroutine Handling(#Section.Changed)

* Ensure the Empno is valid after a department change

#Com_owner.GetDefaultEmpno

Endroutine

Mthroutine Name(GetDefaultSection) Access(*private)

#Section := *null

Select Fields(#Section) From_File(sectab) With_Key(#Deptment)

Leave

Endselect

Endroutine

Mthroutine Name(GetDefaultEmpno) Access(*private)

#Empno := *null

Select Fields(#Empno) From_File(pslmst1) With_Key(#Deptment #Section)

Leave

Endselect

Endroutine

End_Com