Step 2. Add Logic to the Web Page

In this step, you will add logic to the web page to load departments, employees and employee notes to the list.

For this web page, you want to load all departments, employees and employee note data from the server initially. You will do this by invoking a LoadData method from the web page CreateInstance event routine, which runs before the page data is displayed. The LoadData method will invoke routines which get department, employee and employee note data from the server, before then populating the list.

1.  Copy and paste these working list definitions into your web page:

a.  Copy xDepartmentsList from the server module iiixDepartmentsDataServer.

b.  Copy xEmployeeList from server module iiixEmployeeDataServer

c.  Copy xEmployeeNotesList from server module iiixEmployeeNotesDataServer

2.  Create a LoadData method routine. This will retrieve a list of departments and then invoke a GetEmployees method routine. The routine should perform the following:

Define a component for iiixDepartmentsDataServer, FindAll srvroutine, named GetDepts

Execute GetDepts asynchronously, exchanginging list xDepartmentsList

Within an event routine for GetDepartments.Completed

Invoke GetEmployees

End routine

     Your code should look like the following:

Mthroutine Name(LoadData)

Define_Com Class(#iiixDepartmentsDataServer.findall) Name(#GetDepts)

#GetDepts.executeasync( #xDepartmentsList )

Evtroutine Handling(#GetDepts.Completed)

#COM_SELF.GetEmployees

Endroutine

Endroutine

3.  Create a GetEmployees method routine which performs the following:

Define a component for iiixEmployeeDataServer, FindAll, named GetEmployees

Execute GetEmployees asynchronously, exchanging #xEmployeeList

Within an event routine for GetEmployees.Completed

Invoke GetNotes

End routine

     Your code should look like the following:

Mthroutine Name(GetEmployees)

Define_Com Class(#iiixEmployeeDataServer.findall) Name(#GetEmployees)

#GetEmployees.ExecuteAsync( #xEmployeeList )

Evtroutine Handling(#GetEmployees.Completed)

#COM_SELF.GetNotes

Endroutine

Endroutine

4.  Create a GetNotes method routine, to perform the following:

Define a component for iiixEmployeeNotesDataServer, FindAll srvroutine, named GetNotes

Execute GetNotes asynchronously, exchanging list xEmployeeNotesList

Within an event routine for GetNotes.Completed

Invoke LoadDepts

End Routine

     Your code should look like the following:

Mthroutine Name(GetNotes)

Define_Com Class(#iiixEmployeeNotesDataServer.findall) Name(#GetNotes)

#GetNotes.EXECUTEASYNC( #xEmployeeNotesList )

Evtroutine Handling(#GetNotes.Completed)

#COM_SELF.LoadDepts

Endroutine

Endroutine

     The LoadDepts routine is not yet created.

5.  In this step you will create an AddEntry method which will add entries to the list for each of the three levels. The method AddEntry will be invoked by routines which load all departments, load employees for each department and load notes for each employee to the list.

     As well as the data to populate the three columns, the routine will be passed a reference to an image component for each level and a reference to the parent list item for each level. For example, a department is parent to employee entries for that department.

Create a method routine, with the name AddEntry and private access.

Define three maps for input of class STD_OBJ, STD_DESC and DESCL with names Column1, Column2 and Column3.

Make Column2 and Column3 optional by giving them a Mandatory(" ") keyword. Maps with a mandatory keyword, are optional parameters for the method.

Define a map for input of class prim_bmp (a basic graphic) with name Image, with a null mandatory value and to be passed by reference.

Define a map for input of class prim_list.ListItem (a primitive list item) with the name ParentItem, a null mandatory value to be passed by reference.

Define a map for result, class prim_list.ListItem, name Result and a null mandatory value.

     Your code should look like the following:

Mthroutine Name(AddEntry) Access(*private)

Define_Map For(*Input) Class(#std_obj) Name(#Column1)

Define_Map For(*Input) Class(#std_desc) Name(#Column2) Mandatory("")

Define_Map For(*Input) Class(#std_descl) Name(#Column3) Mandatory("")

Define_Map For(*Input) Class(#prim_bmp) Name(#Image) Mandatory(*null) Pass(*by_reference)

Define_Map For(*Input) Class(#Prim_list.ListItem) Name(#ParentItem) Mandatory(*null) Pass(*by_reference)

Define_Map For(*Result) Class(#Prim_list.ListItem) Name(#Result) Mandatory(*null) Pass(*by_reference)

Endroutine

 

6.  Extend the AddEntry method routine to perform the following:

Assign the input parameters Column1, Column2 and Column3 values to the list columns, std_obj, std_desc and std_descl respectively.

Add an entry to the list component, named List.

Set a reference to the List current item, ParentItem property to the reference passed as ParentItem.

Set a reference to the List current item, Image property to the reference passed as Image.

Set a reference to Result from List.CurrentItem

     Your code should now look like the following. New code is shown highlighted.

Mthroutine Name(AddEntry) Access(*private)

Define_Map For(*Input) Class(#std_obj) Name(#Column1)

Define_Map For(*Input) Class(#std_desc) Name(#Column2) Mandatory("")

Define_Map For(*Input) Class(#std_descl) Name(#Column3) Mandatory("")

Define_Map For(*Input) Class(#prim_bmp) Name(#Image) Mandatory(*null) Pass(*by_reference)

Define_Map For(*Input) Class(#Prim_list.ListItem) Name(#ParentItem) Mandatory(*null) Pass(*by_reference)

Define_Map For(*Result) Class(#Prim_list.ListItem) Name(#Result) Mandatory(*null) Pass(*by_reference)

#std_obj := #Column1

#std_desc := #Column2

#std_descl := #Column3

Add_Entry To_List(#List)

#List.Currentitem.ParentItem <= #ParentItem

#List.Currentitem.image <= #Image

#Result <= #List.Currentitem

Endroutine

 

7.  Create a method routine with the name LoadDepts, to perform the following:

Read the working list Departments in a Selectlist/Endselect loop.

For each entry:

Invoke AddEntry passing values xDepartmentCode, xDepartmentDescription, "" and xImageDepartment32

Invoke LoadEmployees passing values xDepartmentCode and List.CurrentItem

End Read

     Note: xImageDepartment32 is an image component in the Repository.

     Your code should look like the following. The LoadEmployees method is not yet written.

Mthroutine Name(LoadDepts)

Selectlist Named(#xDepartmentsList)

#COM_SELF.AddEntry( #xDepartmentCode #xDepartmentDescription "" #xImageDepartment32 )

#COM_SELF.LoadEmployees( #xDepartmentCode #List.CurrentItem )

Endselect

Endroutine 

8.  Create a LoadEmployees method routine to perform the following:

Define a map for input of class xDepartmentCode with the name DeptCode

Define a map for input of class Prim_List.ListItem with the name Parent, passed by reference

Read the working list xEmployeeList in a selectlist/endselect loop, where DeptCode is equal to xDepartmentCode

For each entry:

Invoke Addentry passing values xEmployeeIdentification, xEmployeeSurname, xEmployeeGivenNames, xImageEmployee32 and Parent

Invoke LoadNotes passing values xEmployeeIdentification and List.CurrentItem

     LoadNotes is not yet written.

     Your code should look like the following:

Mthroutine Name(LoadEmployees)

Define_Map For(*INPUT) Class(#xDepartmentCode) Name(#DeptCode)

Define_Map For(*INPUT) Class(#prim_list.listitem) Name(#parent) Pass(*BY_REFERENCE)

Selectlist Named(#xEmployeeList) Where(#DeptCode = #xDepartmentCode)

#COM_SELF.AddEntry( #xEmployeeIdentification #xEmployeeSurname #xEmployeeGivenNames #xImageEmployee32 #parent )

#COM_SELF.LoadNotes( #xEmployeeIdentification #List.CurrentItem )

Endselect

Endroutine 

9.  Create a LoadNotes method routine to perform the following:

Define a map for input of class xEmployeeIdentification with the name EmployID

Define a map for input of class Prim_List.ListItem with the name Parent, passed by reference

Read the working list xEmployeeNotesList in a Selectlist/endselect loop where EmployID is equal to xEmployeeIdentification

For each entry:

Invoke Addentry passing values xEmployeeNoteCreateUpdate as display string, xEmployeeNote, "", xImageDetails32 and Parent

 

     Your code should look like the following:

Mthroutine Name(LoadNotes)

Define_Map For(*INPUT) Class(#xEmployeeIdentification) Name(#EmployID)

Define_Map For(*INPUT) Class(#prim_list.listitem) Name(#parent) Pass(*BY_REFERENCE)

 

Selectlist Named(#xEmployeeNotesList) Where(#EmployID = #xEmployeeIdentification)

 

#COM_SELF.AddEntry( #xEmployeeNoteCreateUpdate.AsDisplayString #xEmployeeNote.AsNativeString.trim "" #xImageDetails32 #parent )

Endselect

Endroutine 

10. Create a CreateInstance event routine for the web page. Add code to invoke LoadData.

Evtroutine Handling(#com_owner.createInstance)

#com_self.Loaddata

Endroutine

 

11. Compile your web page.

12. Test your web page. Since the web page is loading all departments, employees and employee notes initially, you will notice a few seconds delay while this happens. Each entry in the list is automatically given a small arrow icon indicating it has children and may be expanded. When you expand an entry, there will be no delay since all tree entries were added to the list control initially.