-
Notifications
You must be signed in to change notification settings - Fork 4
PageController
The PageController is a web component that receives user action requests originating from a page in the web browser and returns appropriate responses. It is also linked to a session PageBean that serves as the primary value object that backs all the widget instances declared in the UPL page template bound to it. Parameters sent with browser requests are used to populate the PageBean properties of the page controller through binded UPL page elements. Requests are handled by a set of dedicated methods that are named to match the action part of the request URLs. Its within these methods that the PageController is expected to interact with business logic components, populate response data into any of the PageBean properties and then decide on which result mappings to route to.An action handling method accepts no parameters, returns a String object and is annotated with the @Action annotation.
Figure 1: Page Controller Components
A web client accesses a page controller action by constructing a correct client request URL string. A combination of the page controller name and the action name (the method name) form the trailing part of the request URL. For instance if we have a request URL “http://10.200.100.10/bankingapp/retail/accounts/openAccount” the system would retrieve a PageController with name “/retail/accounts” and invoke the controller method with name “openAccount”. As noted earlier, the openAccount() method must be marked with the @Action annotation and must have the correct signature.
Figure 2: URL Breakdown
A PageController is annotated with the @ResultMappings annotation that defines the mapping of the strings returned by the page controller action methods to specific responses. Every @ResultMapping has a unique name and one or more response declarations that determine the nature of data that is sent back to the client. Responses are represented by PageControllerResponse components and they generate the actual response to be sent back to the browser.
Used for generating a forward to path response that instructs the web client to forward to a new location determined by specified URL. The target URL is resolved from the path or pathBinding attribute of the component.
@ResultMapping(name = "forwardtoapplication",
response = { "!forwardresponse path:$s{/application/openPage}" }| Name | Required | Type | Description |
|---|---|---|---|
| path | false | String | Specifies the path to forward to. |
| pathBinding | false | String | Specifies the name of the PageBean property whose value is the path to forward to. Allows dynamic determination of forward path by changing the value of the PageBean property at runtime. |
Used for generating a hide popup response that instructs the web client to hide the current document’s popup if it is visible.
@ResultMapping(name = "searchdone", response = { "!hidepopupresponse" })Used for generating a hint user response that instructs the web client to display a message as a hint to the user. The message is fetched from the request context USER_HINT_LIST attribute which would have been previously set using any of the RequestContextUtil.hintUser() methods . There is no need to add this response to the response element list of your @ResultMapping annotation as the framework implicitly adds one.
@ResultMapping(name = “hintUser”, response = { "!hintuserresponse" })Used for generating a load entire page content response that instructs the web client to reload the entire contents of the page associated with the PageController. The page is loaded within the content element of the current document. A result mapping with name of string constant ResultMappingConstants.OPEN that maps to a LoadContentResponse is implicitly declared for every page controller instance. This mapping is used for handling the result of the AbstractPageController default implementation of the openPage() action method.
@ResultMapping(name = ResultMappingConstants.OPEN,
response = { "!loadcontentresponse" })Used for generating a load document response that instructs the web client to load the entire document associated with a PageController. The web client loads the entire document HTML, behavior scripts and the accompanying page assets like style sheets and Javascript resource files. A result mapping with name of string constant ResultMappingConstants.INDEX is implicitly declared for every page controller instance. This mapping is used for the handling the result of the AbstractPageController default implementation of the index() action method.
@ResultMapping(name = ResultMappingConstants.INDEX,
response = { "!loaddocumentresponse" })Used for generating a post to path response that instructs the web client to perform a post using a specific URL. The target URL is resolved from the path or pathBinding attribute of the response component.
@ResultMapping(name = "managemenuitems",
response = { "!postresponse path:$s{/system/menuitem/openPage}" })| Name | Required | Type | Description |
|---|---|---|---|
| path | false | String | Specifies the path to post to. |
| pathBinding | false | String | Specifies the name of the PageBean property whose value is the path to post to. Allows dynamic determination of post path by changing the value of the PageBean property at runtime. |
Used for generating a refresh panel response that instructs the web client to refresh the contents of one or more panels. The target panel list, a list of long names, is obtained from the component’s panels attribute. If the panels attribute is not set then the component fetches the target panel list from the request context REFRESH_PANEL_LONGNAMES attribute set using the RequestContextUtil.setResponseRefreshPanels() method.
@ResultMapping(name = "refreshmain",
response = { "!refreshpanelresponse panels:$l{mainBodyPanel}" })| Name | Required | Type | Description |
|---|---|---|---|
| panels | false | String[] | Specifies a list of long names of panels to refresh. |
Used for generating a show popup response that instructs the web client to show a particular panel in the document’s popup window. It has a popup attribute for specifying the short name of the target popup panel. If the popup attribute is not set then the component fetches the target panel from the request context REQUEST_POPUP_NAME attribute set using the RequestContextUtil.setRequestPopupName() method.
@ResultMapping(name = "showapplicationmessage",
response = { "!showpopupresponse popup:$s{messageBoxPopup}"})| Name | Required | Type | Description |
|---|---|---|---|
| popup | false | String | Specifies the short name of the panel to display in the popup window. |
Used for generating a switch panel response that makes a SwitchPanel page widget switch its view to a specific child panel and then instruct the web client to refresh the contents of the switch panel. A SwitchPanel is a special panel that contains multiple child panels but has just one visible at any time. We use the panels attribute to specify the child panels to switch to.
@ResultMapping(name = "switchchangepassword", response = {
"!switchpanelresponse panels:$l{loginSequencePanel.changePasswordBodyPanel}"})| Name | Required | Type | Description |
|---|---|---|---|
| panels | true | String[] | Secifies a list of long names of child panels to switch to. |
A PageController must be binded to a page-defining UPL template. A UPL template is a text file that contains descriptors that describe the user interface components - widgets - that constitute a page. It also describes how the user interface components are laid out, the various events, actions and input validations they are associated to.
We bind a page controller to a UPL template by annotating the controller with the @UplBinding annotation with its value element set to the relative path of the target UPL template file. UPL templates can also be binded through inheritance which applies when a page controller extends another page controller that already has a UPL binding. In this scenario, the resulting page definition of a page controller is a cummulative merge of all UPL templates bound to the page controller and all preceding super classes. Page elements defined in a subclass controller page definition automatically override similarly named elements in the page definitions bound to its super classes.
At runtime, Page object is created based on the resolved UPL definitions obtained from UPL templates binded to a page controller and its super classes. The Page object represents the state of the page presented on the client device. It contains instances of all user interface components as defined in the resolved UPL definitions. Also, the Page is a session object that resides in the user session context and its state can be manipulated by convenient methods when you extend the AbstractPageController class.
When implementing a PageController, it is recommended that you extend the AbstractPageController class using an appropriate implementation of a PageBean. The AbstractPageController class is a convenient base class with full implementation of the PageController interface. It provides a rich set of protected methods that allow for obtaining references to the session page bean, page elements, setting the visual state of page elements, setting document and page attributes, showing or hiding page popups, setting off user hints and handling basic request commands.
Figure 3: Simple calculator
Listing 1: Simple calculator page bean.
public class SimpleCalculatorPageBean extends AbstractPageBean {
private BigDecimal number1;
private BigDecimal number2;
private BigDecimal result;
private String message;
... (getters/setters)
}Listing 2 Simple calculator UPL
//Simple calculator UPL
!ui-document caption:$s{Simple Calculator} components:$c{basePanel}
!ui-panel:basePanel layout:$d{!ui-vertical style:$s{padding-left:4px;}}
components:$c{simpleCalculatorPanel actionPanel}
//Input and result panel
!ui-panel:simpleCalculatorPanel
layout:$d{!ui-vertical captionSuffix:$s{:} showCaption:true}
components:$c{number1 number2 result hint}
!ui-decimal:number1 caption:$s{First Number} binding:number1
focus:true
!ui-decimal:number2 caption:$s{Second Number} binding:number2
!ui-decimal:result caption:$s{Result} binding:result
!ui-label:hint style:$s{font-weight:bold;} binding:message
//Action panel
!ui-panel:actionPanel layout:$d{!ui-horizontal}
components:$c{addBtn subBtn}
!ui-button:addBtn caption:$s{Add}
eventHandler:$d{!ui-event event:onclick action:$c{addAct}}
!ui-button:subBtn caption:$s{Subtract}
eventHandler:$d{!ui-event event:onclick action:$c{subAct}}
//Actions
!ui-post:addAct path:$n{/add} components:$c{number1 number2}
!ui-post:subAct path:$n{/subtract} components:$c{number1 number2}
Listing 3: Simple calculator page controller.
@Component(name = "/simplecalculator")
@UplBinding("simplecalculator.upl")
@ResultMappings({
@ResultMapping(name = "refresh",
response = { "!refreshpanelresponse panels:$l{simpleCalculatorPanel}" }) })
public class SimpleCalculatorPageController
extends AbstractPageController<SimpleCalculatorPageBean> {
public SimpleCalculatorPageController() {
super(SimpleCalculatorPageBean.class);
}
@Action
public String add() throws UnifyException {
SimpleCalculatorPageBean pageBean = getPageBean();
// Perform addition
BigDecimal firstNumber = pageBean.getNumber1();
BigDecimal secondNumber = pageBean.getNumber2();
BigDecimal result = firstNumber.add(secondNumber);
// Set result
pageBean.setResult(result);
pageBean.setMessage("Added second number to first number.");
// Refresh calculator panel
return "refresh";
}
@Action
public String subtract() throws UnifyException {
SimpleCalculatorPageBean pageBean = getPageBean();
// Perform subtraction
BigDecimal firstNumber = pageBean.getNumber1();
BigDecimal secondNumber = pageBean.getNumber2();
BigDecimal result = firstNumber.subtract(secondNumber);
// Set result
pageBean.setResult(result);
pageBean.setMessage("Subtracted second number from first number.");
// Refresh calculator panel
return "refresh";
}
@Override
protected void onIndexPage() throws UnifyException {
// Set result field state to non-editable
setPageWidgetEditable("result", false);
}
}- Unify Container
- Unify Component
- Unify Page Language
- Core Components
-
Web Components
-
Basic Widgets
- AssignmentBox
- Button
- CheckBox
- CheckList
- DateField
- DecimalField
- DropdownCheckList
- DynamicField
- FileAttachment
- FileDownload
- FileUpload
- Image
- IntegerField
- Label
- MoneyField
- MultiDynamic
- MultiSelect
- NameField
- PasswordField
- Picture
- Rack
- RadioButtons
- SearchField
- SingleSelect
- Table
- TextArea
- TextField
- TimeField
- WordField
- Container Widgets
- Layout
-
Controllers
- PageController
- ResourceController
- RemoteCallController
- PlainController
-
Basic Widgets