Working with Pages and Classes

From AgileApps Support Wiki

In most cases, when you work with Pages and Classes, you want to separate the code that handles the user interface from the code that handles the data. In the platform, you do this by following the Model-View-Controller design pattern and creating two classes and a page.

Learn More:

How it Works

This section describes how a request flows from a page to the controller to the worker and how the result is displayed in the page.

Notepad.png

Note:
The code samples are presented here for illustration, and should not be used to build actual pages or classes. See Practical Example below for more on working code samples.

In this example, a page displays a search form for Directory object which is a built-in Object available to every account. The user can select the criteria to search the directory entries and then enter the string to search for.

<form name="mainForm" action="/networking/controller/com/platform/demo/samples/DirectoryController" method="POST">
  <input type="hidden" name="action" value="search" />
  <table>
      <tr>
          <!-- ... -->
          <td>Search</td>
          <td>
              <select name="searchType">
                  <option value="first_name">First Name</option>
                  <option value="name1">Last Name</option>
                  <option value="address">Address</option>
                  <!-- ... -->
              </select>
          </td>
          <td> for </td>
          <td><input type="text" name="searchString" value="<%=searchString%>" 
              />
          </td>
          <td><input type="submit" name="submit" value="Search" /></td>
      </tr>
  </table>
</form>

The action attribute of the <form> tag specifies the URL of the class that you wrote that implements the Controller interface (DirectoryController in this example).

When the user clicks the Search button, the form is submitted to the DirectoryController's execute method, shown below.

execute Method

import com.platform.api.*;

import java.util.HashMap;

public class DirectoryController implements Controller
{

  public ControllerResponse execute(HashMap params) throws Exception
  {
    String action = (String)params.get("action");
    
    // ...

    ControllerResponse cr = new ControllerResponse();
    Directory directory = new Directory();
    Result result = null;

    if(action.equals("search"))
    {
      result = directory.search(params);
      cr.setTargetPage("directory.jsp");
    }
    // ...
    params.put("opResult", result);
    // ...
    cr.setData(params);
    return cr;
  }
}

This code:

  • Gets the value of the action key passed in params
  • Creates instances of the predefined classes ControllerResponse and Result
  • Creates an instance of the worker class Directory (shown below)
  • Calls the search method (shown below) in the worker class, if the action is "search", passing it params; also sets the next JSP name
  • Puts the result of the method call in params using the key opResult
  • Calls the setData method in ControllerResponse, specifying params as the argument
  • Returns the instance of ControllerResponse

search Method

Here is the search method in the Directory worker class.

import com.platform.api.*;


public class Directory
{
  // ...
  public Result search(HashMap params) throws Exception
  {
        Parameters addParams = Functions.getParametersInstance();
        addParams.add(params);

        String searchType = (String)params.get("searchType");
        String searchString = (String)params.get("searchString");

        Result result = null;
        if(searchType != null && !searchType.equals(""))
        {
          // Inspect the object in the GUI to get its name
          String object_name = "directory";
          result = 
            Functions.searchRecords(object_name,
                "record_id,first_name,address,city,state,zip,direct_phone,email",
                searchType + " contains '" + searchString + "'");
        }
        return result;
  }
  // ...
}

This code:

  • Creates an instance of Parameters and adds params to it
  • Gets the values of the searchType and searchString keys from params
  • Creates an instance of Result
  • Calls searchRecords, passing in the searchType and searchString and setting the Result object with the returned value
  • Returns the Result object

Displaying the Results

So, the search request originated in the page, went to the controller, and finally to the worker. Now we look at how the search results get displayed in the page.

This example:

  • Gets the opResult value from params and puts it into result
  • Iterates through result, creating a table row for each set of data

In the Page, here is the code that gets the search results:

<%
  java.util.HashMap params = (java.util.HashMap)controllerResponse.getData();

  String searchType = params.get("searchType") == null ? "" : (String) params.get("searchType");
  String searchString = params.get("searchString") == null ? "" : (String) params.get("searchString");
  String message = params.get("message") == null ? "" : (String) params.get("message");
%>

The HTML and code below puts the search results into table rows.

<%
Result result = (Result)params.get("opResult");
if(result != null)
{
%>
<table>
    <tr>
        <td colspan="5">Search Results:</td>
    </tr>
    <!-- ... -->        
    <%
    ParametersIterator iter = result.getIterator();
    while(iter.hasNext())
    {
        Parameters row = iter.next();
    %>
    <tr>
        <!-- ... -->
        <td><%=row.get("first_name")%></td>
        <td><%=row.get("address")%></td>
        <!-- ... -->
    </tr>
    <%
    }
}
    %>
</table>

Practical Example

JSP Pages are used to develop the UI to suit any custom requirements in an organization. The logic on how to perform the various operations on the server is present in the classes (Java code).

To try out the concepts of Pages and Classes, follow this tutorial to add real code to platform elements and build a .jsp page that can be used in a web browser.

Overview

In this guide, you create a JSP Page and a Controller Class that interact to:

  • Add records to a Mailing List object
  • Do a SQL search for (one or more) records
  • Update records

Sample Scenario

A sample interaction scenario might look like this:

Jsp controller scenario.png
  • The arrows going to the controller show the value of the action variable that is passed from the JSP Page.
  • The arrows going to the JSP Page show the value of the control variable that is passed from the controller.
(The names of the variables are determined by convention. They could be anything.)

Communication Mechanisms

This diagram shows how the interactions between the JSP Page and the controller Class take place:

Jsp controller interactions.png
  • An HTML Form designates the location to go to when a button is pressed.
  • In this case, the Form targets a Class.
    The platform instantiates an object when the class page is visited.
  • All contents of the form are passed to the controller as name/value pairs, in the params argument, including:
- Fields with data the user supplies: <input type="input" ...
- Hidden data fields: <input type="hidden" value="<%=SomeVariable%>"...
- The button that was pressed: <input type="submit" name="..." value="..." ...
(The value is displayed as the button label, and passed as the value associated with the name.)
  • The controller's execute method returns a ControllerResponse object
  • The ControllerResponse object designates the page to go to next
  • You use its setData method to load a HashMap with values to send to the page

Prerequisites

  • A "Mailing List" object must be created, with two fields: contact_name and contact_email

Developing the Application

Create the Java class

  1. Follow the instructions at Add a Class to create AddUpdateController_YOURNAME
  2. Copy and paste the contents of AddUpdateController.java into the Class
  3. Modify the class, supplying your package namespace and name:
    PersonalizeController.png
  4. Save the class

Create the JSP Page

  1. Follow the instructions at Add a Page to create AddUpdateYOURNAME.jsp
  2. Copy and paste the contents of AddUpdate.jsp
  3. Customize the JSP Page with your package namespace and name:
    PersonalizeJSP.png
  4. Save the JSP page

Try it Out

To test the project you created, visit the URL for your page, substituting your platform address for "{yourDomain}":

https://{yourDomain}/pages/AddUpdateYOURNAME.jsp
(A valid username and password is required to log in to the platform.)

MVC

MVC: Model-View-Controller

  • A worker class that retrieves, updates, and deletes data (the Model)
  • A page that handles the user interface (the View)
  • A class that creates an instance of the worker class, call its methods, and sets the next page to display (the Controller)

The controller is a special class that implements the Controller interface. The Controller interface requires you to implement the execute method:

ControllerResponse execute(HashMap params)

This method returns an instance of the ControllerResponse class. The platform uses the ControllerResponse class to send the appropriate response to the browser.

The argument params in the execute method contains the POST and GET data in the HTTP Request. If an HTML form is being submitted to the controller, the params HashMap contains all the <input> fields in the page. For each field:

  • The key of params is the name attribute of the <input> tag
  • The value of params is the value attribute of the <input> tag

Call these ControllerResponse methods to set the return value of the execute method:

  • setData: set the data to be made available to the next page
  • setTargetPage: set the name of the next page to display

In the controller, you create an instance of a worker class and call its methods to perform operations.

For details, see Controller Interface and ControllerResponse Class.

In a page, you have an implicit object called controllerResponse:

  • You call its getData method to get the data that was set by the controller
  • You can set any Java object in controllerResponse by calling its setData method