In the following section, the tutorial provides instructions for building a simple mobile application based on the DeptEmpDC data control. The mobile application will have the following functionality when you are done:
- Browse departments data from the REST-JSON service and select a department
- Browse employees in the selected department from the REST-JSON service and select an employee for edit
- Edit a selected employee and write changes back to the database via the REST-JSON service
-
In JDeveloper, locate and open (double click) the maf-feature.xml file contained in the ViewController / META-INF folder.
-
Press the green plus icon
next to the Features header.
-
Set the Feature Name to DeptEmpRest.
Then, press OK to accept the default settings for the other input options.
-
Select the Content tab and click the green plus icon next to the File option .
-
Select the Task Flow menu option.
Then, enter deptEmp-task-flow.xml as the File Name and press OK.
In this part of the tutorial, you add view components and navigation rules to the existing application. You will create the pages for these components in the next section.
You now have the entry point to the mobile application and a task flow to define the business process.
In this section, refine the page and add data to browse a list of departments.
-
With the task flow diagram open (showing empty) choose Window > Components to open the JDeveloper components panel.
-
In the component window, select View from the Components subsection, and drag and drop the activity onto the task flow diagram.
-
Select the view1 activity and click into the name or press the F2-key (on Windows) to put the name into edit mode. Change the name of the view to BrowseDepartments.
-
Select the BrowseDepartments view activity with the right mouse button and select Create Page from the menu.
-
In the Create MAF AMX Page dialog, ensure the Header, Primary Action and Secondary Action page facets are selected, then click OK.
Note: in a real-world implementation the recommendation is to add (a) folder(s) under the public_html/ folder to categorize mobile pages by their functionality and/or type.
-
In the open page, find and change the outputText value.
<amx:outputText value="Header" id="ot1"/>
to
<amx:outputText value="Browse Departments" id="ot1"/>
-
Remove the two amx:commandButton tags in the primary and secondary facets.
-
Open the Data Controls window, expand the DeptEmpDC node and select the allDepartments collection.
-
Drag and drop the allDepartments collection into the page. Make sure you drop the collection before the start of the closing </amx:panelPage> tag.
-
Select MAF List View from the menu.
-
Press OK in the ListView Gallery dialog, accepting the default selection.
-
In the Edit ListView dialog, which will pop up next, set the value binding to departmentName from departmentId and press OK.
Note: The list view is a UI component that is commonly used in mobile user interfaces for scrolling value lists and selecting a list entry for further editing or navigation. -
On the BrowseDepartments page, select the Bindings tab at the bottom of the page source editor to switch to the MAF binding file associated with the BrowseDepartment page.
-
In the binding editor, select the allDepartments entry and press the pencil icon.
-
In the Edit Tree Binding dialog, select the departmentId item on the left and move it to the right by clicking the single arrow-right icon.
Note: Selecting the departmentId property adds this attribute to the properties that are accessible from expression language within the context of the list view.
Then click OK.
-
Back in the binding editor, press the Source tab at the bottom to switch back to the page source view.
-
With the page source view open, go to the Components window and expand the Operations category.
Drag the SetPropertyListener item from the Components panel (Operations subsection) and drop it into the amx:listItem tag.
-
With the amx:setPropertyListener tag selected, select Window > Properties from the JDeveloper menu to open the Property Inspector if it is not already open.
Then, set the SetPropertyListener tag properties as follows.From #{row.departmentId} To #{pageFlowScope.departmentIdVal} Type action Note: The amx:setPropertyListener writes the departmentId value of a selected list item into the departmentIdVal bounded task flow pageFlowScope attribute in memory. Note that in this tutorial we use the pageFlowScope attribute directly for brevity. In a real-world mobile application it is recommended that you save any value you want to share with activities and pages in a bounded task flow in a specialized managed bean configured in the pageFlowScope.
-
The mobile application is now ready for its first runtime test.
Ensure the Rest Service is still up and running in the integrated WebLogic server in JDeveloper.
If the service is not running yet, go back to Step 4: Explore and Test the REST Service on the first page of this tutorial to start it up.
-
Assuming the iOS or Android simulator is properly setup and working on your laptop or PC, select Application > Deploy from the JDeveloper menu, followed by selection the iOS1 or Android1 menu entry (depends on the operating system you are on, or the class of mobile OS that you want to test the sample application with).
-
In the deploy dialog, select Deploy application to Simulator (iOS) or Deploy application to Emulator (Android). Press Finish to deploy.
-
When the simulator or emulator comes up, find the MAFREST application icon and tap on it to start the application.
-
When the application starts, you should see a list of selectable department names.
Right under the image showing the Android emulator I notice the "red warning triangle" on the left upper corner. This is what you'll see because by default because this MAF application isrun in debug mode, not release mode. The triangle helps remind you that the application is running in debug mode, so you accidently go into production with the app set to debug mode.
What you've done so far: At this point you have created and tested a new AMX feature based on a bounded task flow. The first and only AMX view activity you have created so far contains a selectable list of department names queried from the remote REST-JSON service.
In a next step you are extending the application with a method activity that queries employees for a selected department to display on another view activity, the BrowseEmployees page.
The employee detail page – “BrowseEmployees” - serves different purposes: It lists the employees for a selected department and launches other mobile pages for editing a selected employee or for creating a new employee for the selected department.
-
In JDeveloper, open the task flow diagram for the deptEmp-task-flow.
In the Data Controls panel, find the DeptEmpDC > prepareEmployeesForDepartment(Integer) method and drag & drop it into the task flow diagram. -
In In the Edit Action Binding dialog, edit the departmentId parameter and set its value to #{pageFlowScope.departmentIdVal}.
Then click, OK. -
In the Components panel, select the Control Flow Case icon.
Click on the BrowseDepartments view activity. Next, click on the prepareEmployeesForDepartment method activity you just created, which automatically will create a line between the two activities.
Set the name of the control flow case to queryEmployees. The task flow diagram should now look like this (the relative positions of the activities are not important):
-
Open the BrowseDepartments page (if you closed it, just double click on the view activity in the task flow diagram).
-
Select the amx:listItem tag and open the Property Inspector.
Set the list item Action property to queryEmployees using the drop down list.Note: The action property setting initiates the navigation to the method call activity when the user selects a department from the list. At the same time the setPropertyListener will save the departmentId into the task flow pageFlowScope attribute for the method activity to read.
-
Switch back to the task flow diagram and save your work.
-
From the Components panel drag another View activity and drop it onto the task flow diagram.
Then, set the View activity name from view1 to BrowseEmployees. -
In the Components window, select the Control Flow Case icon and the click onto the prepareEmployeesForDepartment method call activity
Next, click onto the BrowseEmployees view activity to draw a control flow line between the two.
Keep the control flow case name. -
Create one more control flow case from the BrowseEmployees view to the BrowseDepartments view and name it browseDepartments.
-
Next, create the BrowseEmployees page by selecting the view activity with the right mouse button and select Create Page from the menu.
-
From In the page creation dialog, press OK, accepting all the default settings.
Then, save all your work -
Edit the amx:commandButton in the secondary facet and add a text property with the value Emp. The command button should look like in the image below.
-
Edit the amx:commandButton in the primary facet and set the Text attribute to Show Depts and the Action property to browseDepartments.
-
Change the value of the Output Text component value, in the header facet to Emp List .
-
From the Data Controls panel, select the allEmployees collection and drag and drop it into the BrowseEmployee page before the </amx:panelPage> tag.
From the menu, select MAF List View. -
Press OK in the ListView Gallery dialog to accept the default selection.
In the Edit List View dialog, set the value of the Value Binding field to lastName as shown in the image below and press OK.
-
In the BrowseEmployees page, select the Bindings tab at the bottom of the page source editor to switch to the MAF binding file associated with the BrowseEmployees page.
-
In the binding editor, select the allEmployees entry and press the pencil icon.
-
In the Edit Tree Binding dialog, select the firstName item on the left and move it to the right by clicking the single arrow-right icon.
Note: Selecting the lastName property adds this attribute to the properties that are accessible from expression language within the context of the list view.
Then click OK.
-
Back in the binding editor, press the Source tab at the bottom to switch back to the page source view.
-
Back in the page source editor for the Browse Employees page, add the firstName to the amx:listItem.
Note: don’t miss the comma “,” between the last name and first name attribute
-
Save your work.
-
Test the application, select Application > Deploy from the JDeveloper menu and then select the deployment profile you used before to deploy the application to the iOS simulator or Android emulator.
-
Start the application and select a department – for example “IT” – to navigate to the employee detail page.
-
Press the Depts command button to navigate back to the browse departments page.
What you've done so far: At this point you have enhanced the mobile application by implementing master-detail behavior between the “BrowseDepartments” and the “BrowseEmployees” page.
The selected department id is copied to the page flow scope where it is read by the method call activity that invoke the data control method that queries the employee detail rows.
In a next step you further extend the application with a page allowing you to edit employee rows and either cancel the edits or save the changes back to the remote REST service.
Unlike web applications, where form data needs to be submitted for update, on mobile clients data is changed when a user leaves the input field. The requirement in this tutorial is to allow users to cancel employee data changes applied in the employee edit form.
To isolate the selected employee data to edit from the employee data in the allEmployees collection that is displayed in the BrowseEmployees page, a copy of the selected employee is created and saved in a separate collection exposed on the POJO data control.
For this, the DeptEmpDC Java class exposes editableEmployee as a collection property that holds a single employee object to edit on an edit page.
In this section of the tutorial you will populate the editableEmployee collection with the employee that the user selects in the BrowseEmployees page. Later, upon employee select, navigation will be performed to the employee edit page you create in a next section.
Note: This section teaches three important concepts: i) how to use POJO data controls to not only proxy web service queries, ii) how to customize MAF component actions with custom a pre- and post- behavior and iii) how to use the data control to store object state between views in a MAF feature.
-
In the opened BrowseEmployees.amx page, select the amx:listItem child component within the amx:listView component and open the Property Inspector.
-
Expand the Behavior node. Move the mouse to the right of the Action Listener property, click the blue gear icon
and select Edit.
-
In the Edit Property: Action Listener dialog, press the New button to create a new managed bean to hold the action listener logic.
-
Use the following properties to complete the Create Managed Bean dialog.
Keep the default values for all settings not explicitly mentioned in the table above and press OK.Note: The managed bean doesn’t need to store state and therefore is configured in view scope, which is the smallest possible scope in MAF.
Bean Name browseEmployeesBean Class Name BrowseEmployeesBean Package maf.code.corner.hr.mobile.beans Scope view
-
Back in the Edit Property: Action Listener dialog, press the New button next to the Method field.
In the Create Method dialog add onEmployeeSelect as the Method Name and press OK.
-
Press OK again and save your work.
The page source should now look as in the image below.
-
In the JDeveloper Applications window, navigate to the managed bean you just created.
-
Double click onto the Java file using the left mouse button to open it in the Java code editor.
Set the cursor into the onEmployeeSelect method body and add the following code content.
Note: The BrowseEmployeesBean.txt file located in the tutorial’s DOC/CODE_TXT folder contains the code for you to copy and paste into your managed bean to save you from typing.
Allow all the imports to be included and then use <alt> + <Enter> to add the import for the BasicIterator.In this section you learned that there are two options for storing state information in MAF when transitioning between mobile pages: managed beans in pageFlow scope and POJO data controls.
Managed beans in view flow scope are good to hold client side UI state (for example style sheet information that is referenced from the UI component “rendered” property to either show or hide components).
The POJO data control can be used to hold data related state information like sort orders, filter criteria or – as in this tutorial – information about the selected data object in a collection.
If you are looking for guidance when to use which of the options, then a rule of thumb could be that any data related state that should be made available to other pages – without the pages to itself invoke a method to further filter data – should be saved in the POJO DC.
Managed beans ideally only save UI related state and for anything data related access the POJO data control.
The BrowseEmployeesBean managed bean is configured in view scope within the bounded task flow. The bean does not need to keep the selected employee object state so that that the smallest possible lifecycle scope can be used.
The Java code above accesses the current selected employee row in the MAF AMX iterator binding and passes the employee object (entity) to the setEditableEmployee method in the DeptEmpDC data control.
The next step is to create an edit form to edit selected employee data and link it to the BrowseEmployees page so navigation occurs when an employee in the list view is selected.
-
Switch to the task flow diagram view and drag another View activity from the component panel to the diagram.
Name the view activity EditEmployee. -
Create two control flows to include the new view activity.
Use the component and create a control flow case from the BrowseEmployees view activity to the EditEmployee view activity and name it editEmployee.
Create the second control flow case from EditEmployee to BrowseEmployees and name it browseEmployees.
-
Double click onto the EditEmployee view activity to bring up the Create MAF AMX Page dialog.
Deselect the Secondary Action page facet and click OK.
-
Change the value of the outputText component in the header facet to Edit Employee.
-
Set the Text property for the amx:commandButton in the Primary Facet to Employees.
-
Add an Action attribute and set its value to browseEmployees.
Hint: you can set the action property using the Property Inspector, which will provide you with a select list to choose the control flow case.
-
Select the editableEmployee collection in the Data Controls panel
Then, drag the editableEmployee collection to the EditEmployee page and drop it after the facets but before the </amx:panelPage> closing tag.
In the menu, select MAF Form.
-
Use the delete icon
and the blue arrow icons (
,
) to remove and rearrange the form attribute until the following list of attributes remain.
- firstName
- lastName
- email
- jobId
- managerId
- phoneNumber
- salary
Then click OK.
-
Open the Components window and expand the Layout category.
Then, drag the Panel Group Layout component from the Components window and drop it onto the EditEmployee page below the </amx:panelFormlayout> closing tag.
-
Set the amx:panelgroupLayout layout attribute to horizontal.
Then change the amx:panelGroupLayout tag as shown so its easier to create child components
-
From the Data Controls panel, select the updateEmployee method.
Then drag the updateEmployee method into the space between the amx:panelGroupLayout open and closing tags and drop it as a MAF Button.
-
In the Edit Action Binding dialog, double click into the Value field next to the emp argument to bring up the Show El Expression Builder menu option.
-
Click onto the Show El Expression Builder menu and select the ADF Bindings > bindings > editableEmployeeIterator > currentRow -> dataProvider entry.
-
Click OK to write the expression language back into the MAF method binding that will be created and invoked by the button’s ActionListener property.
Click OK again in the Edit Action Binding dialog.
The amx:panelGroupLayout should should have a new amx:commandButton child component.
-
Edit the amx:commandButton component and add the action attribute with a value of browseEmployees, which is the navigation case pointing back to the BrowseEmployees page.
Hint: you can use the Property Inspector to create the action attribute and select the control flow case from the select list.
Note: The command button invokes a method binding in the AMX page’s binding container that reads the current selected row of the iterator to pass the associated employee object to the data control method. The data control method then invokes the remote REST service to update the remote employee information with the change. Once done, the application navigates back to the BrowseEmployees page. -
Include a cancel button to navigate back to the BrowseEmployees page without committing the record.
Add an amx:spacer component (Layout category) and an amx:commandButton component (General Controls category) from the JDeveloper Components window so the page sources looks like the image below.
Add the text attribute to the amx:commandButton and with a value of Cancel.
Then add the action attribute with a value of browseEmployees.
Note: The cancel button only navigates back to the BrowseEmployees page without persisting the change to the allEmployees collection in the DeptEmpDC class..
-
Save all your work.
-
One last task to do for you is to link the BrowseEmployees page to the EditEmployee page so that selecting a list view item selects an employee and navigates to the EditEmployee page.
Open the BrowseEmployees page. -
Add an action attribute to the amx:listItem tag and set its value to editEmployee.
Note that editEmployee is the name of the control flow case you create earlier in the task flow diagram. Referencing the control flow in the amx:listItem will trigger page navigation whenever a user selects and employee.
Hint: Use the Property Inspector to add and configure the action attribute.
-
Save your work and test the application.
-
In the running application, select a department and then an employee.
Edit the employee and scroll to the bottom of the page and click the updateEmployee button or the Cancel button.
Clicking either button will take you back to the Emp List page.
-
add the action attribute with a value of browseEmployees.
-
add the action attribute with a value of browseEmployees.
-
add the action attribute with a value of browseEmployees.
An an optional exercise in this tutorial, add a page to create employees.
The DeptEmpDC data control class also exposes a method to create a new employee for a department. The input form can be created as a parameter form for the createEmployee(…) method shown in the MAF Data Control panel.
The information about the selected departmentId for which the new employee shall be created is available in a memory attribute.
Creating the employee page is left as an exercise for you to test what you’ve learned in this hands-on. Below are some hints & tips to guide you
-
Create a separate CreateEmployee page
-
Create the input form by dragging the createEmployee method as a parameter form onto the page.
-
Read the departmentId from #{pageFlowScope.departmentIdVal} memory property (don’t expose this on the parameter form).
-
Create two control flow cases: One going from the BrowseEmployees page to the CreateEmployee page and one going back from the CreateEmployee page to the BrowseEmployee page
-
Add two buttons to the CreateEmployee page.
Note: A button that submits the changes to the REST service (the button is created when dragging the createEmployee method as a parameter form).
A second button to simply navigates back to the BrowseEmployees page (it’s a cancel button). -
Finally, add button in the BrowseEmployee page to navigate to the employee creation page.
You have now successfully creating a simple Oracle Mobile Application Framework (MAF) application based on a REST-JSON web service.
![Bookmark](../_image/bookmark.png)
![Print](../_image/print_ena.png)