AgileApps Support Wiki Pre Release

Difference between revisions of "Pages"

From AgileApps Support Wiki
imported>Aeric
imported>Aeric
Β 
(161 intermediate revisions by the same user not shown)
Line 1: Line 1:
<noinclude>
<noinclude><!--Fails when transcluded into category page-->__NUMBEREDHEADINGS__</noinclude>
<!--Doesn't work when transcluded into a category page-->
'''[[File:GearIcon.png]] > Customization > Developer Resources > Pages'''
__NUMBEREDHEADINGS__
Β 
</noinclude>'''Designer > Logic > Pages'''
Pages can be used to create highly customized user interface elements as well as completely independent tabs.
Β 
==About Pages==
A Page is a standard [http://www.java-tips.org/java-ee-tips/javaserver-pages/an-example-of-a-simple-jsp-page.html JSP page] (JavaServer Page) that can contain HTML and Java code.
Β 
Pages gives you a way to customize the user's interactions with the platform. They can be:
:* accessed directly via their URL
:* used in a [[Dashboard]]
:* used to display or enter data in lieu of a standard object Form
:* display a message in a dialog
:* used in a [[Site]]
Β 
Pages that contain platform header files generally communicate with the platform through a Java controller class that does data retrieval and storage. For details, see [[Working with Pages and Classes]]. Pages without headers operate as standard HTML pages that provide information, add styling, and give the user links to other pages.
Β 
====About Header Files====


A Page is a standard [http://www.java-tips.org/java-ee-tips/javaserver-pages/an-example-of-a-simple-jsp-page.html JSP page] (JavaServer Page). It can be used to create highly customized user interface elements as well as completely independent tabs.
All JSP pages have access to the platform's [[Tag Library]], and all can be displayed in a [[Web Tab]] or [[Dashboard]], or accessed by their URL. (When displayed as part of the platform UI, the page is displayed in an {{^iFrame}}--a sandbox, of sorts, the isolates the page from the rest of the platform UI.) In addition, JSP pages can use the [[Java APIs]] to access and update platform data (or use a [[Controller Class]] for that purpose).
:''Learn more: [[Developer_Suite#Pages|Pages in the Developer Suite]]''


In most cases, a page communicates with a worker [[Classes|class]] through a controller class. For details, see [[Working with Pages and Classes]].
When the platform's header files are included in a page:
:* The platform's standard CSS and JavaScript files are included.
:* The page has access to the platform's [[JavaScript Functions]].
:* The page has access to the platform's {{^jQuery}} library.
:* The functions and libraries can be used to create a sophisticated interface for data retrieval and storage.


{{permissions|Customize Objects|add, edit or delete pages}}
If the header files are not included, the page becomes a "vanilla" HTML page:
:* CSS styling defined in the page is honored (with headers included, CSS styles defined in the page are ignored)
:* Links to other pages work (with headers included, they fail).
:* The page can be displayed in a dialog, using the [[JavaScript Functions#showDialog|showDialog]] function.
:* The page can be used in a [[Site]].
:* A {{^jQuery}} library (or other library) can be referenced, but it must first be uploaded as a [[Static Resource]].


==Designing Pages==
===Designing Pages===
Use HTML to create the look you want, you use a variety of dynamic display-and-interaction technologies to create the feel you want:
Use HTML and CSS to create the look you want, and use a variety of dynamic display-and-interaction technologies to create the feel you want:
:* Use [[Java API]]s to access and interact with the platform.
:* Use [[Java API]]s to access and interact with the platform.
:* Use features from the [http://jquery.com/ jQuery] library (javascript components, stylesheets, themes, effects, etc).
:* Use features from the [http://jquery.com/ jQuery] library (JavaScript components, stylesheets, themes, effects, etc).
:* Add your own JavaScript code for forms and other options. Β 
:* Add your own [[JavaScript]] code for forms and other options. Β 
:* Use [[AJAX and REST]] to communicate with the platform in JavaScript code.
:* Use [[AJAX and REST]] to communicate with the platform in JavaScript code.
:* Upload other javascript libraries and CSS files as [[Static Resources]] and reference them in your JSP pages.
:* Upload other JavaScript libraries and CSS files as [[Static Resources]] and reference them in your JSP pages.
Β 
==Using APIs==
Β 
In general, the [[Java API]]s and [[REST API]]s provide equivalent functionality. But there are some differences, as well. So while the Java APIs are generally more convenient to use in a JSP page, you may also want to review the functionality listed in the [[REST API:REST API CheatSheet|REST API CheatSheet]].


The following Java API classes are implicitly imported into pages:
===Using APIs===
::* [[Support_Classes_and_Objects#Result_Class|Result]]
{{:Common:Using APIs}}
::* [[Support_Classes_and_Objects#Parameters_Class|Parameters]]
::* [[Support_Classes_and_Objects#ParametersIterator_Class|ParametersIterator]]
::* [[Support_Classes_and_Objects#HttpConnection_Class|HttpConnection]]


Other considerations:
==Working with Pages==
:* You cannot make a database connection. (Use the Java [[Java API:Record Handling|Record Handling]] APIs, instead.)
Pages can be Added, Edited or Deleted. Β 
:* By default, the maximum number of loop iterations is 10000. (The actual value, along with other restrictions, are set using platform [[Governors]].)


==Managing Pages==
{{permissionRef|Customize Objects|add, edit or delete pages}}
Pages can be Added, Edited or Deleted. Before editing, a page must be checked out ([[#Checkout a Page|Checkout]]), and should be checked in ([[#Commit a Page|Commit]]) after Editing.


=== Add a Page ===
=== Add a Page ===
To add a page:
To add a page:
# Click '''Designer > Logic > Pages'''
# Click the '''[New Page]''' button, and complete the following information:
# Click the [New Page] button, and complete the following information:
#;Title:Enter the filename for the page.
#;Title:Enter a title for the page
#: A Page that includes platform headers compiles to a Java class, so the page name must be a valid Java class name. And it must end with a <tt>.jsp</tt> extension.
#:<tt>*.jsp</tt> extension is required
#:The same naming rules apply to a page that does not include platform headers, even though it becomes a vanilla HTML page--because headers can always be added later.
#;Display with Tab Header:Checkbox
#:
#:If checked, display the page with a tab header
#;Include [[#About Header Files|Header Files]]:Checkbox Β 
# Enter the code in the text area
#: Β 
# Enter the code for the page in the text area:
#* Typically, you'll use Java APIs and JSTL tags to access data (described later), and then insert the data into the page using <tt><%=''fieldName''%></tt>
#* If there is any doubt at all about the integrity of your data (particularly when data comes from external users via [[Web Forms]]), be sure to ''encode'' the data before displaying it
#: ''Learn more:'' [[HowTo:Protect Your Users by Ensuring that Data Never Executes as Code]]
# Click '''[Save]'''
# Click '''[Save]'''


=== Edit a Page ===
=== Edit a Page ===
Before editing a page, the page must be checked out.
To edit a page:
To edit a page:
# Click '''Designer > Logic > Pages'''
# Click '''[[File:GearIcon.png]] > Customization > Developer Resources > Pages'''
# Click the name of the page to edit
# Click the name of the page to edit
# Click the [Edit] button
# Click the '''[Edit]''' button
# Edit the code in the text area
# Edit the code in the text area
# Click '''[Save]'''
# Click '''[Save]'''


===Checkout a Page===
=== Delete a Page ===
Before editing a page, the page must be checked out.
To delete a page:
:''Learn more: [[Metadata_Repository#Version_Control|Version Control]]''
# Click '''[[File:GearIcon.png]] > Customization > Developer Resources > Pages'''
# Click the name of the page to delete
# Click the '''[Delete]''' button


To checkout a page:
=== Managing Pages in Eclipse ===
# Click '''Designer > Logic > Pages'''
Use the [[Eclipse Plug-In]] to add, edit, and delete pages.
# Click the name of the page to edit
# Click the [Checkout] button
The following actions can be taken on a page that is checked out:
:*Edit
:*Delete
:*Commit
:*Back (Cancel)


The following information is displayed when a page is checked out:
== Using Pages ==
;Page Information:
:;Title:pagetitle.jsp
:;Display with Tab Header:Yes
;Version Information:
:;Version:4
:;Locked:No
:;Last Commit By:Elaine Yoder
:;Last Commit Date:01/13/2010 10:55 AM
:;Last Checkout By:Elaine Yoder
:;Last Checkout Date:


===Commit a Page===
=== Display a Page as a Web Tab ===
After editing a page, the changes should be committed to the working copy.
To make a Page available as a web tab:
To commit a page: Β 
#Click '''[[File:GearIcon.png]] > Customization > Developer Resources > Web Tabs'''
#After editing a page, click '''[Save]'''
#Click the '''[New Web Tab]''' button:
#Click '''[Commit]'''
#*Enter a Name
#:The Item Type and Name cannot be modified
#*For the Web Tab Type, select Page
#:Add Comments about the changes
#* Choose the page you created
#::The following ''Commit Details'' are displayed:
#Choose which roles can see the tab
#::;Item Type:Page
#::;Item Name:pagename.jsp
#::;Comment:Description of the changes to the page
#Click '''[Save]'''
#Click '''[Save]'''
#Refresh your browser to see the new tab


=== Delete a Page ===
:''Learn more:'' [[Web Tabs#Displaying a Web Tab|Displaying a Web Tab]]
To delete a page:
# Click '''Designer > Logic > Pages'''
# Click the name of the page to delete
# Click the [Delete] button to continue
Β 
== Managing Pages in Eclipse ==
Use the [[Eclipse Plug-In]] to add, edit, and delete pages.


== Invoking a Page from an Action ==
=== Display a Page from a Form Action ===
# Click Designer > Data > Objects'''.
# Click [[File:GearIcon.png]] > Customization > Objects'''.
# Click an object
# Click an object
# Click the ''Actions'' tab
# Click the ''Actions'' tab
# Click the [Add Action] button
# Click the '''[Add Action]''' button
# Enter a title
# Enter a title
# Specify Invoke Custom Page as the '''Type'''
# For '''Type''', select ''Invoke Custom Page''
# Select a page you have defined
# Select a page you have defined
# Click '''[Save]'''
# Click '''[Save]'''
:''Learn more:'' [[Custom Form Actions]]


== Invoking a Page from a URL ==
=== Display a Page by Visiting a URL ===


If you have written your page in a way that does not require a controller to display it, you can directly invoke it using:
If you have written your page in a way that does not require a controller to display it, you can directly invoke it using:
Line 127: Line 120:


For more about controllers, see see [[Working with Pages and Classes]].
For more about controllers, see see [[Working with Pages and Classes]].
=== Making an Application Help Page ===
An application help page is simply a JSP page without the platform's header files. Such pages can include CSS, and can link to other pages.
''Learn more:''
:* [[Pages#About Header Files|About Header Files]]
:* [[Application Help Tab]] (example)


== Advanced Techniques ==
== Advanced Techniques ==
=== Create a Tab using Pages ===
See [[Web Tabs]] for information on creating tabs using pages.
===Use Static Resources in Pages===
See [[Static Resources]] for information on how to load image files, stylesheets, JavaScript files or compressed files as Page resources.


===Share Common Libraries===
===Share Common Libraries===
Line 140: Line 135:
<%@ include file="/pages/common.JSP"%>
<%@ include file="/pages/common.JSP"%>
</syntaxhighlight>
</syntaxhighlight>
A new library can then be added to every page, simply by adding it <tt>common.JSP</tt>.
A new library can then be added to every page, simply by adding it to <tt>common.JSP</tt>.
Β 
===Access Implicit JSTL Objects===
The ''implicit objects'' built into JSP pages give you a great deal of power, with negligible additional work. To access them, include this line near the top of your JSP page:
:<syntaxhighlight lang="java" enclose="div">
<%@ taglib uri="/c" prefix="c" %>
</syntaxhighlight>
Β 
That tag references the JSTL core library. (Since that library is built into the platform, the typically long URI is replaced by "/c".)
Β 
The JSTL ''Expression Language'' provides a nice way to access those objects. For example, to access a named parameter sent to the page in an HTTP request, you can use this syntax.
:<syntaxhighlight lang="java" enclose="div">
${param.someParameterName}
</syntaxhighlight>
Β 
Using the implicit objects, you can store and retrieve data for a request, a page, a session, or an application. For example, see the [[JSTL pageContext]] properties.
Β 
In addition to the pageContext properties, you can access these implicit objects:
:* cookie - Client data, accessed by cookie name
:* header - Request header value, accessed by name
:* headerValues - List of header values
:* initParam - Initialization parameter, accessed by name
:* param - Request parameter, accessed by name
:* paramValues - List of parameter values
:* pageScope - Page attribute, accessed by name.
:* requestScope - Request attribute, accessed by name.
:* sessionScope - Session attribute, accessed by name.
:* applicationScope - Application attribute, accessed by name.
''Learn More:''
:* [https://jstl.java.net/ JSP Standard Tag Library]
:* [http://www.roseindia.net/jstl/jstl-el.shtml JSTL Expression Language]
:* [http://www.informit.com/articles/article.aspx?p=30946&seqNum=7 Implicit Objects]
Β 
===Read the HttpServlet Request Stream===
You can access the servlet input stream from the <tt>request</tt> object in the JSP page.<br>Here's sample code that uses it to build a string:
:<syntaxhighlight lang="java" enclose="div">
<%
Β  StringBuilder sb = new StringBuilder();Β 
Β 
Β  // Read the input stream
Β  java.io.InputStream is = request.getInputStream();
Β  String line = null;
Β  // Convert to String
Β  java.io.BufferedReader br =
Β  Β  Β  new java.io.BufferedReader(new java.io.InputStreamReader(is));
Β  while ((line = br.readLine()) != null) {
Β  Β  Β  sb.append(line);
Β  }
%>
</syntaxhighlight>
Β 
===Access CSS Files and JavaScript Libraries===
In a page, you can access files uploaded as static resources.
Β 
''Learn more:'' [[Static Resources#Accessing Static Resources in a JSP Page]]


==Print Templates Using Pages==
== Encode Data Before Displaying It! ==
Print templates in pages can be used to print records in any object. See [[Print Templates]] for an overview of print templates in the user interface.
{{:HowTo:Protect Your Users by Ensuring that Data Never Executes as Code|Ensure Data is Never Executed}}
Β 
==Document Templates Using Pages==
Print templates in pages can be used to print records in any object. See [[Document Templates]] for an overview of Document Templates in the user interface.


'''Examples'''
'''Examples'''
*Create an Expense Report to be used in expense management application
:*Create an Expense Report to be used in expense management application
*Print an Employee Benefit Form
:*Print an Employee Benefit Form


Using print templates in pages is a two-step process:
Using Document Templates in pages is a two-step process:
#[[#Create a Page|Create a Page]] that includes the desired print formatting
#[[#Create a Page|Create a Page]] that includes the desired print formatting
#[[#Create a Print Template|Create a Print Template]] using a Page as the template type
#[[#Create a Document Template|Create a Document Template]] using a Page as the template type


===Create a Page===
===Create a Page===
#Click '''Designer > Logic > Pages'''
#Click '''[[File:GearIcon.png]] > Customization > Developer Resources > Pages'''
#Click the [New Page] button
#Click the '''[New Page]''' button
#Click the [Edit] Button
#Click the '''[Edit]''' Button
#Enter a Title (filename) for the print template; Include .jsp as the file extension
#Enter a Title (filename) for the Document Template; Include .jsp as the file extension
#Uncheck the Display with Tab Header checkbox
#Uncheck the Display with Tab Header checkbox
#Add appropriate code, as shown in the next section.
#Add appropriate code, as shown in the next section.
Line 165: Line 219:
{{:Get Object and Record ID from the Request Object}}
{{:Get Object and Record ID from the Request Object}}


===Create a Print Template===
===Create a Document Template===
This print template uses Page as the type of template, instead of HTML
This Document Template uses Page as the type of template, instead of HTML
#Click '''Designer > Data > Objects > {object}'''
#Click '''[[File:GearIcon.png]] > Customization > Objects > {object}'''
#Add a new Print Template, select Page type and select the .jsp print template file
#Add a new Document Template, select Page type and select the <tt>.jsp</tt> Document Template file
#:[[Image:Printtemplate-page.gif|none|thumb]]
Β 
==Example: Add a Contact using a Page and a Class==
Β 
This example describes how to [[Manage_Contacts#Add_Contact|Add a Contact]] using a Page and Class.
Β 
===Create a Page===
#To create a page, follow the instructions at [[#Adding a Page|Adding a Page]]
#Copy and paste the following code into the page, and name it <tt>AddContact.jsp</tt>
:{| border="0" cellpadding="5" cellspacing="0"
|
<syntaxhighlight lang="java" enclose="div">
Β 


<body>
==Page and Controller Examples==


<formΒ  name = "mainForm" action="/networking/controller/com/platform/demo/samples/AddContact" method="POST">
===Example: Add a Contact using a Page and a Class===
<table width="100%" border="10" cellspacing="0" cellpadding="0">
This example describes how to add a Contact using a Page and Class.
Β  <tr>
Β  Β  <td><table width="50%" border="0" cellspacing="0" cellpadding="2">
Β  Β  Β  <tr>
Β  Β  Β  Β  <LABEL for="addFirstName">Β  Β  First Name: </LABEL>
Β  Β  Β  Β  Β  Β  Β  <INPUT type="text" id="addFirstName" name="addFirstName" value="CPFirst"><BR>
Β  Β  Β  Β  <LABEL for="addLastName">Β  Last Name: </LABEL>
Β  Β  Β  Β  Β  Β  Β  <INPUT type="text" id="addLastName" name="addLastName" value="CPLast"><BR>
Β  Β 
Β  Β  Β  Β  <INPUT type="submit" value="Add"> <INPUT type="reset">Β  Β  Β  Β 
Β  Β  Β  </tr>
Β  Β  </table>
Β  Β  </form>
Β  Β  </td>
Β  </tr>
</body>
</html>
</syntaxhighlight>
|}


===Create a Class===
====Create the Class====
#To create a class, follow the instructions at [[Classes#Adding_a_Class|Adding a Class]]
#Create a class, following the instructions at [[Classes#Adding_a_Class|Adding a Class]]
#Copy and paste the following code into the class, and name it <tt>AddContact</tt>
#Copy and paste the following code into the class, and name it <tt>AddContact</tt>
::<syntaxhighlight lang="java" enclose="div">
::<syntaxhighlight lang="java" enclose="div">
import java.util.*;
import java.util.*;
import com.platform.api.*;
import com.platform.api.*;


public class AddContact implements Controller
public class AddContact implements Controller
Line 223: Line 244:
Β Β  Β  Β  if(action == null || action.equals(""))
Β Β  Β  Β  if(action == null || action.equals(""))
Β Β  Β  Β  {
Β Β  Β  Β  {
Β Β  Β  Β  Β  Β  Functions.debug("Action - null?");Β  Β  Β  Β  Β  Β  Β 
Β Β  Β  Β  Β  Β  Logger.info("Action - null?", "AddContact");Β  Β  Β  Β  Β  Β  Β 
Β Β  Β  Β  Β  Β  action = "Add";
Β Β  Β  Β  Β  Β  action = "Add";
Β Β  Β  Β  }
Β Β  Β  Β  }
Β Β  Β  Β  if(action.equals("Add"))
Β Β  Β  Β  if(action.equals("Add"))
Β Β  Β  Β  {
Β Β  Β  Β  {
Β Β  Β  Β  Β  Β  Functions.debug("Action - not null?" + action);
Β Β  Β  Β  Β  Β  Logger.info("Action - not null?" + action, "AddContact");
Β Β  Β  Β  Β  Β  return addContact(params);
Β Β  Β  Β  Β  Β  return addContact(params);
Β Β  Β  Β  }
Β Β  Β  Β  }
Line 247: Line 268:
Β Β  Β  Β  {
Β Β  Β  Β  {
Β Β  Β  Β  Β  Parameters addOptions = Functions.getParametersInstance();
Β Β  Β  Β  Β  Parameters addOptions = Functions.getParametersInstance();
Β Β  Β  Β  Β  addOptions.add("object_id", "CONTACT");
Β Β  Β  Β  Β  addOptions.add("object_id", "Contacts");
Β Β  Β  Β  Β  String addFirstName = (String)params.get("addFirstName");
Β Β  Β  Β  Β  String addFirstName = (String)params.get("addFirstName");
Β Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β 
Β Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β 
Line 265: Line 286:
Β Β  Β  Β  Β  Β  addOptions.add("account_id", "1593373443");
Β Β  Β  Β  Β  Β  addOptions.add("account_id", "1593373443");
Β Β  Β  Β  Β  } Β 
Β Β  Β  Β  Β  } Β 
Β Β  Β  Β  Β  result = Functions.addRecord("CONTACT", addOptions);
Β Β  Β  Β  Β  result = Functions.addRecord("Contacts", addOptions);
Β Β  Β  Β  Β  Functions.debug("Message:" + result.getMessage());
Β Β  Β  Β  Β  Logger.info("Message:" + result.getMessage(), "AddContact");
Β Β  Β  Β  Β  cr.setData(result);
Β Β  Β  Β  Β  cr.setData(result);
Β Β  Β  Β  Β  cr.setTargetPage("AddContact.jsp");
Β Β  Β  Β  Β  cr.setTargetPage("AddContact.jsp");
Line 275: Line 296:
Β Β  Β  Β  Β  cr.setMessage(e.getMessage());
Β Β  Β  Β  Β  cr.setMessage(e.getMessage());
Β Β  Β  Β  Β  Β  Β  Β  Β  Β 
Β Β  Β  Β  Β  Β  Β  Β  Β  Β 
Β Β  Β  Β  Β  Functions.debug("Message:");Β  Β  Β  Β  Β  Β 
Β Β  Β  Β  Β  Logger.info("Message:", "AddContact");Β  Β  Β  Β  Β  Β 
Β Β  Β  Β  }
Β Β  Β  Β  }
Β Β  Β  Β  return cr;
Β Β  Β  Β  return cr;
Β Β  }
Β Β  }
}
}
</syntaxhighlight>
====Create the Page====
#Create a page, following the instructions at [[#Adding a Page|Adding a Page]]
#Copy and paste the following code into the page, and name it <tt>AddContact.jsp</tt>
::<syntaxhighlight lang="java" enclose="div">
<body>
<formΒ  name = "mainForm" action="/networking/controller/com/platform/demo/samples/AddContact" method="POST">
<table width="100%" border="10" cellspacing="0" cellpadding="0">
Β  <tr>
Β  Β  <td><table width="50%" border="0" cellspacing="0" cellpadding="2">
Β  Β  Β  <tr>
Β  Β  Β  Β  <LABEL for="addFirstName">Β  Β  First Name: </LABEL>
Β  Β  Β  Β  Β  Β  Β  <INPUT type="text" id="addFirstName" name="addFirstName" value="CPFirst"><BR>
Β  Β  Β  Β  <LABEL for="addLastName">Β  Last Name: </LABEL>
Β  Β  Β  Β  Β  Β  Β  <INPUT type="text" id="addLastName" name="addLastName" value="CPLast"><BR>
Β  Β 
Β  Β  Β  Β  <INPUT type="submit" value="Add"> <INPUT type="reset">Β  Β  Β  Β 
Β  Β  Β  </tr>
Β  Β  </table>
Β  Β  </form>
Β  Β  </td>
Β  </tr>
</body>
</html>
</syntaxhighlight>
</syntaxhighlight>


Now the page is ready to be invoked from browser or web tab.
Now the page is ready to be invoked from browser or web tab.


==Pages in Lookup Fields==
===Example: Submit Data that Includes a File Attachment===
[[Lookup]] fields can be based on Pages, which display customized [[Lookup Window]]s. These pages are launched in the usual way, with the lookup [[File:lookupicon.gif]] icon, from within a record.
This example uploads a file selected by a user.
Β 
====Create the Class====
#Create a class, following the instructions at [[Classes#Adding_a_Class|Adding a Class]]
#Copy and paste the following code into the class (minus the footnotes), and name it <tt>SampleController</tt>
::<syntaxhighlight lang="java" enclose="div">
package com.platform.{yourNamespace}.{yourPackage};Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  --[1]


When a Lookup Window search is successful, these parameters are used to identify and return Lookup Fields in Pages:
import java.util.*;
import com.platform.beans.*;
import com.platform.api.*;
Β 
public class SampleController implements Controller
{
Β  public ControllerResponse execute(HashMap parameters) throws Exception
Β  {
Β  Β  Β  ControllerResponse response = new ControllerResponse();
Β 
Β  Β  Β  // Or extract the parameter into a PlatformFileBean for use elsewhere
Β  Β  Β  Parameters params = Functions.getParametersInstance();
Β  Β  Β  Β  /* ... add additional parameters, as required... */
Β  Β  Β  PlatformFileBean fileBean = (PlatformFileBean)parameters.get("attached_file");Β  --[2]
Β  Β  Β  params.add("someFieldName", fileBean);
Β  Β  Β  Functions.addRecord("SomeOtherObject",params);
Β  Β 
Β  Β  Β  // Set the target page and return
Β  Β  Β  response.setTargetPage("target.jsp");
Β  Β  Β  return response;
Β  }
}
</syntaxhighlight>
:;Notes:
:# Fill in your organization's namespace and the package in which you are creating the class
:# The name of the incoming field is "attached_file", in the form you'll create next.<br>''Learn more:'' [{{DOCHOST}}/javadocs/com/platform/beans/PlatformFileBean.html PlatformFileBean javadocs]


:{| border="1" cellpadding="5" cellspacing="0"
====Create the Page====
!Paramter Name
#Create a page, following the instructions at [[#Adding a Page|Adding a Page]]
!Description
#Copy and paste the following code into the page (minus the footnotes).
|-
#Fill in your organization's namespace and the package in which you created the class.
|<tt>object_id</tt>||[[Object Type Identifier]]
::<syntaxhighlight lang="java" enclose="div">
|-
<%@taglib prefix="lj" uri="/LJTagLib"%> Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  --[1]
|<tt>keyword</tt>||String value, entered by the user in the lookup field.
<html>
If the user types ''ABC'' in the lookup field, then the <tt>keyword</tt> is ''ABC''.
<head></head> Β 
|-
<body> Β 
|<tt>target_field</tt>||Used to store the [[Record Identifier]]
<form name="mainForm"
|-
Β  enctype="multipart/form-data"Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  --[2]
|<tt>target_name_field</tt>||Used to store the contents of the field (text string format, contents of the field)
Β  action="/networking/multipartController/com/platform/{ns}/{pkg}/SampleController"Β  --[3]
|}
Β  method="POST">


:The Lookup Field is rendered using two HTML elements:
Β  <lj:file name="attached_file" id="attached_file" size="15" value=""/>Β  Β  Β  Β  Β  Β  Β  --[4]
:*<tt>target_field</tt>
Β  Β  Β 
:*<tt>target_name_field</tt>
Β  <!-- other form fields -->
:See the .jsp sample code files for more information.
Β  Β  Β 
Β  <input type="submit" name="action" value="upload" /> Β 
</form>
</body> Β 
</html> Β 
</syntaxhighlight>


;Considerations:
:;Notes:
*[[Lookup#Lookup_Record_Selection_Criteria|Lookup Record Selection Criteria]] is not supported.
:# Include the platform's [[Tag Library]]
* Auto-Completion for Lookup Fields is not supported.
:# Specify the encoding type as a multi-part form
:# Specify the platform's multipartController handler for the class.<br>Fill in your organization's namespace and the package in which you created the class.
:# Use the Tag Library's [[Tag Library#File Tag|file]] tag to allow the user to browse for a file, and to submit the resulting selection as multi-part data.


===Lookup Examples===
==Lookup Examples==


====Search based on Lastname====
===Search based on Lastname===


This example performs a search action in a lookup window based on "Lastname" as the [[Record_Locator#Record_Identifier_Fields|Record Identifier Field in Record Locator]]:
This example performs a search action in a lookup window based on "Lastname" as the [[Record_Locator#Search_Fields|Record Locator]]:


Add a Page:
Add a Page:
#From the [[Account]] object, [[#Pages#Adding_a_Page|Add a Page]]
#[[#Pages#Adding_a_Page|Add a Page]]
#Use this file name: <tt>AccountPopup.jsp</tt>
#Use this file name: <tt>AccountPopup.jsp</tt>
#Use this code sample: [[AccountPopup.jsp]]
#Use this code sample: [[AccountPopup.jsp]]


Add a <tt>AccountPopup.java</tt> Class:
Add a <tt>AccountPopup.java</tt> Class:
#From the [[Account]] object, [[Classes#Adding_a_Class|Add a Class]]
#[[Classes#Adding_a_Class|Add a Class]]
#Use this file name: <tt>AccountPopup.java</tt>
#Use this file name: <tt>AccountPopup.java</tt>
#Use this code sample: [[AccountPopup.java]]
#Use this code sample: [[AccountPopup.java]]


Add a <tt>AccountPopupController.java</tt> Class:
Add a <tt>AccountPopupController.java</tt> Class:
#From the [[Account]] object, [[Classes#Adding_a_Class|Add a Class]]
#[[Classes#Adding_a_Class|Add a Class]]
#Use this file name: <tt>AccountPopupController.java</tt>
#Use this file name: <tt>AccountPopupController.java</tt>
#Use this code sample: [[AccountPopupController.java]]
#Use this code sample: [[AccountPopupController.java]]


Β 
===Search based on multiple fields===
====Search based on multiple fields====
This example performs a search action in a lookup window using [[#Multiple Fields in the Record Locator|Multiple Fields in the Record Locator]]:
This example performs a search action in a lookup window using [[#Multiple Fields in the Record Locator|Multiple Fields in the Record Locator]]:


Prerequisite: In the Directory object, define the Record Identifier field to include "First name" and "Last name".
'''Prerequisite:''' In the Directory object, define the [[Record_Locator#Search_Fields|Record Locator]] fields to include "First name" and "Last name".
Β 


;Add a Page:
;Add a Page:
Line 354: Line 438:
#Use this file name: <tt>DirectoryPopupController.java</tt>
#Use this file name: <tt>DirectoryPopupController.java</tt>
#Use this code sample: [[DirectoryPopupController.java]]
#Use this code sample: [[DirectoryPopupController.java]]


===Multiple Fields in the Record Locator===
===Multiple Fields in the Record Locator===


If the [[Record_Locator#Record_Identifier_Fields|Record Identifier Field in Record Locator]] is a combination fields, then the the Record Locator must be created by concatenating the field names.
If the [[Record_Locator#Search_Fields|Record Locator]] is a combination of fields, then it must be created by concatenating the field names.


For example, the record locator for the Employee object is a combination of First name, Last name. Then the record locator value is formed as: <tt>[First name value][space][-][space][Last name value]</tt>
For example, the record locator for the Employee object is a combination of First name, Last name. Then the record locator value is formed as: <tt>[First name value][space][-][space][Last name value]</tt>
Line 373: Line 456:
|}
|}


{{#if: {{ShowIsvInfo}} {{ShowMspInfo}} |
==Global Pages==
==Global Pages==


[[ISV]]s and [[MSP]]s can create custom pages at global level for distribution to [[Tenants]]. This feature gives [[Service Provider]]s the ability to design and build pages once, then make the custom work available to multiple tenants, as the default [[Home Page]] for Tenants, or added as [[Web Tabs]].
[[ISV]]s can create custom pages at the global level for distribution to [[Tenants]]. This feature gives [[Service Provider]]s the ability to design and build pages once, then make the custom work available to multiple tenants, as the default [[Dashboard]] for Tenants, or added as [[Web Tabs]].


;Global Page access:
;Global Page access:
Global Page access is defined by {namespace}, as shown in this URI:
Global Page access is defined by {namespace}, as shown in this URL:
:<tt><nowiki>http://{domain}.com/networking/isv/{namespace}/{globalpage.jsp}</nowiki></tt>
:<tt><nowiki>https://{{domain}}/networking/isv/{namespace}/{globalpage.jsp}</nowiki></tt>
:where:
:where:
::{domain} is the Service Domain of the [[Service Provider]]
::{{domain}} is the Service Domain of the [[Service Provider]]
::{namespace} is the namespace of the Service Provider, defined in [[Company Information]]
::{namespace} is the namespace of the Service Provider, defined in [[Company Information]]
::{globalpage.jsp} is the the name of the [[Page]]
::{globalpage.jsp} is the the name of the [[Page]]
;Considerations:
*Usage is hierarchical, meaning that:
:*ISVs can create Global Pages, which can be used by MSPs and Tenants of that ISV
:*MSPs can create Global Pages, which can be used by Tenants of that MSP


===Create a Global Page===
===Create a Global Page===
# Click '''Designer > Logic > Pages'''
# Click '''[[File:GearIcon.png]] > Customization > Developer Resources > Pages'''
# Click the [New Page] button, and complete the following information:
# Click the [New Page] button, and complete the following information:
#;Title:Enter a title for the page, for example: <tt>pagename.jsp</tt>
#;Title:Enter a title for the page, for example: <tt>pagename.jsp</tt>
Line 403: Line 479:


===Using Global Pages===
===Using Global Pages===
*To select a Global Page as the [[Home Page]] for tenants, see: [[Service_Provider_Settings#Application_Container_URL|Application Container URL]]
*To select a Global Page as the [[Dashboard]] for tenants, see: [[Service_Provider_Settings#Application_Container_URL|Application Container URL]]


*To use a Global Page as a [[Web Tab]]:
*To use a Global Page as a [[Web Tab]]:
Line 409: Line 485:
#Choose URL as the ''Web Tab Type''
#Choose URL as the ''Web Tab Type''
#Paste the Global Page URI into the edit area: Β 
#Paste the Global Page URI into the edit area: Β 
#::<tt><nowiki>http://{domain}.com/networking/isv/{namespace}/{globalpage.jsp}</nowiki></tt>
#::<tt><nowiki>https://{{domain}}.com/networking/isv/{namespace}/{globalpage.jsp}</nowiki></tt>
#::Remember to substitute actual values for the <tt><nowiki>{arguments}</nowiki></tt>
#::Remember to substitute actual values for the <tt><nowiki>{arguments}</nowiki></tt>
}}
<noinclude>
<noinclude>


[[Category:Develop| 30]]
[[Category:Logic| 2]]
[[Category:Tools and API]]
[[Category:Pages]]
[[Category:Pages]]
</noinclude>
</noinclude>

Latest revision as of 10:50, 8 May 2018

GearIcon.png > Customization > Developer Resources > Pages

Pages can be used to create highly customized user interface elements as well as completely independent tabs.

1 About Pages

A Page is a standard JSP page (JavaServer Page) that can contain HTML and Java code.

Pages gives you a way to customize the user's interactions with the platform. They can be:

  • accessed directly via their URL
  • used in a Dashboard
  • used to display or enter data in lieu of a standard object Form
  • display a message in a dialog
  • used in a Site

Pages that contain platform header files generally communicate with the platform through a Java controller class that does data retrieval and storage. For details, see Working with Pages and Classes. Pages without headers operate as standard HTML pages that provide information, add styling, and give the user links to other pages.

1.1 About Header Files

All JSP pages have access to the platform's Tag Library, and all can be displayed in a Web Tab or Dashboard, or accessed by their URL. (When displayed as part of the platform UI, the page is displayed in an iFrame--a sandbox, of sorts, the isolates the page from the rest of the platform UI.) In addition, JSP pages can use the Java APIs to access and update platform data (or use a Controller Class for that purpose).

When the platform's header files are included in a page:

  • The platform's standard CSS and JavaScript files are included.
  • The page has access to the platform's JavaScript Functions.
  • The page has access to the platform's jQuery library.
  • The functions and libraries can be used to create a sophisticated interface for data retrieval and storage.

If the header files are not included, the page becomes a "vanilla" HTML page:

  • CSS styling defined in the page is honored (with headers included, CSS styles defined in the page are ignored)
  • Links to other pages work (with headers included, they fail).
  • The page can be displayed in a dialog, using the showDialog function.
  • The page can be used in a Site.
  • A jQuery library (or other library) can be referenced, but it must first be uploaded as a Static Resource.

1.2 Designing Pages

Use HTML and CSS to create the look you want, and use a variety of dynamic display-and-interaction technologies to create the feel you want:

  • Use Java APIs to access and interact with the platform.
  • Use features from the jQuery library (JavaScript components, stylesheets, themes, effects, etc).
  • Add your own JavaScript code for forms and other options.
  • Use AJAX and REST to communicate with the platform in JavaScript code.
  • Upload other JavaScript libraries and CSS files as Static Resources and reference them in your JSP pages.

1.3 Using APIs

In general, the Java APIs and REST APIs provide equivalent functionality. But there are some differences, as well. So while the Java APIs are generally more convenient to use in a JSP page, you may also want to review the functionality listed in the REST API CheatSheet.

The following Java API classes are implicitly imported into JSP Pages:

Other considerations:

  • You cannot make a database connection. (Use the Java Record Handling APIs, instead.)
  • The maximum number of loop iterations, along with other restrictions, is determined by the configuration of the platform Governors.)

2 Working with Pages

Pages can be Added, Edited or Deleted.

Lock-tiny.gif

Users that have the Customize Objects permission can add, edit or delete pages. 

2.1 Add a Page

To add a page:

  1. Click the [New Page] button, and complete the following information:
    Title
    Enter the filename for the page.
    A Page that includes platform headers compiles to a Java class, so the page name must be a valid Java class name. And it must end with a .jsp extension.
    The same naming rules apply to a page that does not include platform headers, even though it becomes a vanilla HTML page--because headers can always be added later.
    Include Header Files
    Checkbox
  2. Enter the code for the page in the text area:
    • Typically, you'll use Java APIs and JSTL tags to access data (described later), and then insert the data into the page using <%=fieldName%>
    • If there is any doubt at all about the integrity of your data (particularly when data comes from external users via Web Forms), be sure to encode the data before displaying it
    Learn more: HowTo:Protect Your Users by Ensuring that Data Never Executes as Code
  3. Click [Save]

2.2 Edit a Page

To edit a page:

  1. Click GearIcon.png > Customization > Developer Resources > Pages
  2. Click the name of the page to edit
  3. Click the [Edit] button
  4. Edit the code in the text area
  5. Click [Save]

2.3 Delete a Page

To delete a page:

  1. Click GearIcon.png > Customization > Developer Resources > Pages
  2. Click the name of the page to delete
  3. Click the [Delete] button

2.4 Managing Pages in Eclipse

Use the Eclipse Plug-In to add, edit, and delete pages.

3 Using Pages

3.1 Display a Page as a Web Tab

To make a Page available as a web tab:

  1. Click GearIcon.png > Customization > Developer Resources > Web Tabs
  2. Click the [New Web Tab] button:
    • Enter a Name
    • For the Web Tab Type, select Page
    • Choose the page you created
  3. Choose which roles can see the tab
  4. Click [Save]
  5. Refresh your browser to see the new tab
Learn more: Displaying a Web Tab

3.2 Display a Page from a Form Action

  1. Click GearIcon.png > Customization > Objects.
  2. Click an object
  3. Click the Actions tab
  4. Click the [Add Action] button
  5. Enter a title
  6. For Type, select Invoke Custom Page
  7. Select a page you have defined
  8. Click [Save]
Learn more: Custom Form Actions

3.3 Display a Page by Visiting a URL

If you have written your page in a way that does not require a controller to display it, you can directly invoke it using:

https://www.longjump.com/networking/pages/MyJSP.jsp

If your page depends on a controller to display it, you can use this type of URL:

https://www.longjump.com/networking/controller/com/platform/{namespace}/{package}/MyService?action=doSomething

where com.platform.{namespace}.{package}.MyService is a class that implements the Controller interface and action is a parameter that you can use in the controller.

For more about controllers, see see Working with Pages and Classes.

3.4 Making an Application Help Page

An application help page is simply a JSP page without the platform's header files. Such pages can include CSS, and can link to other pages.

Learn more:

4 Advanced Techniques

4.1 Share Common Libraries

The standard technique for including common libraries is to create a JSP that references them, for example, common.JSP, and then include that page in every other page:

<syntaxhighlight lang="java" enclose="div">

<%@ include file="/pages/common.JSP"%> </syntaxhighlight> A new library can then be added to every page, simply by adding it to common.JSP.

4.2 Access Implicit JSTL Objects

The implicit objects built into JSP pages give you a great deal of power, with negligible additional work. To access them, include this line near the top of your JSP page:

<syntaxhighlight lang="java" enclose="div">

<%@ taglib uri="/c" prefix="c" %> </syntaxhighlight>

That tag references the JSTL core library. (Since that library is built into the platform, the typically long URI is replaced by "/c".)

The JSTL Expression Language provides a nice way to access those objects. For example, to access a named parameter sent to the page in an HTTP request, you can use this syntax.

<syntaxhighlight lang="java" enclose="div">

${param.someParameterName} </syntaxhighlight>

Using the implicit objects, you can store and retrieve data for a request, a page, a session, or an application. For example, see the JSTL pageContext properties.

In addition to the pageContext properties, you can access these implicit objects:

  • cookie - Client data, accessed by cookie name
  • header - Request header value, accessed by name
  • headerValues - List of header values
  • initParam - Initialization parameter, accessed by name
  • param - Request parameter, accessed by name
  • paramValues - List of parameter values
  • pageScope - Page attribute, accessed by name.
  • requestScope - Request attribute, accessed by name.
  • sessionScope - Session attribute, accessed by name.
  • applicationScope - Application attribute, accessed by name.

Learn More:

4.3 Read the HttpServlet Request Stream

You can access the servlet input stream from the request object in the JSP page.
Here's sample code that uses it to build a string:

<syntaxhighlight lang="java" enclose="div">

<%

  StringBuilder sb = new StringBuilder();  
  // Read the input stream
  java.io.InputStream is = request.getInputStream();
  String line = null;

  // Convert to String
  java.io.BufferedReader br = 
     new java.io.BufferedReader(new java.io.InputStreamReader(is));
  while ((line = br.readLine()) != null) {
     sb.append(line);
  }

%> </syntaxhighlight>

4.4 Access CSS Files and JavaScript Libraries

In a page, you can access files uploaded as static resources.

Learn more: Static Resources#Accessing Static Resources in a JSP Page

5 Encode Data Before Displaying It!

A Cross-Site Scripting (XSS) attack is one in which a script is entered into the data stream. Then, when the data is displayed, the script executes. This guide explains how an XSS attack works, and shows you how to guard against it.

In general, the idea is to encode incoming data, so that it is displayed when accessed, rather than executing. That encoding is done automatically when data is entered into a Form that is running in the platform. But when you create an external Web Form, you need to do it yourself.

5.1 Executing a Script Stored as "Data"

To see how XSS works, you'll create an object with a data field and put a tiny script into that field. Then, when you display the data, you'll see that the script executes in the browser.

Here's the process:

  1. Create a TestObject with one textfield, TestData.
  2. Create a record in that object.
  3. In the field, store the following data: <script>alert("You have been hacked!");</script>
    That code is a script that opens a dialog and displays a simple message--but it could conceivably do much more, like opening a cookie on the user's system and sending its information elsewhere.
  4. Now create a JSP Page, TestPage.jsp to display the data in that field. For example:
    <syntaxhighlight lang="java" enclose="div">

<html> <%@ taglib uri="/c" prefix="c" %> <head>

 <title>Test Page</title>

</head> <body> Here is the data from the first and only record: <%

 // Get all records that have testfield data.
 Result results = Functions.searchRecords("TestObject", "testfield", "testfield != BLANK");
 String data = null;
 // Get the data from the first record. 
 ParametersIterator iterator = results.getIterator();
 while(iterator.hasNext())
 {
    Parameters recordParams = iterator.next();
    data = recordParams.get("testfield");
    break;
 }

%> <%=data%>. </body> </html> </syntaxhighlight>

  1. Next, visit that page, at https://{yourDomain}/networking/pages/TestPage.jsp
    When you go there, you encounter the dialog box generated by the script that was stored as "data".

Although it is possible to enter the script using the platform interface, as we have done here, the most likely scenario for XSS is in the form of data that originates from an external source, submitted to the system in a Web Form. For example, the script could be part of a comment on a blog post. Anyone who displays the comments then unknowingly executes the script.

Such problems are prevented by encoding user data, before it is displayed. You can do that using either Java APIs or JavaScript APIs, discussed in the sections that follow.

Warn.png

Warning: It is never a good idea to "double encode" data. You can store data in encoded form, or display it that way. You never want to do both. (Since encoding the data takes additional space, it is typically desirable to do the encoding when the data is displayed.) Similarly, make sure that the data runs through only one encoding process before it is displayed.

5.2 Using Java APIs to Encode Displayed Data

Protecting users in such scenarios is a matter of ensuring that such "data" is always displayed, rather than executed. To do that, you encode the data, so the browser sees &lt;script&gt;, for example, rather than <script>. (When it sees <script> it goes into execution mode. But it when it sees &lt;script&gt;, it substitutes the left- and right-angle brackets, and then simply displays the resulting string.

The methods you need to encode displayed data are available in the com.platform.api.XSSEncoder class:

  • encodeForHTML - Encode data for display in an HTML page
  • encodeForHTMLAttribute - Encode data for display in an HTMLAttribute
  • encodeForJavaScript - Encode data before inserting it into JavaScript code

Here's the JSP page, rewritten to encode the data. When you run it now, you no longer see the dialog box. Instead, you see the code that would have generated it, had it been allowed to run.

<syntaxhighlight lang="java" enclose="div">

<html> <%@ taglib uri="/c" prefix="c" %> <head>

 <title>Test Page</title>

</head> <body> Here is the data from the first and only record: <%

 // Get all records that have testfield data.
 Result results = Functions.searchRecords("TestObject", "testfield", "testfield != BLANK");
 String data = null;
 // Get the data from the first record. 
 ParametersIterator iterator = results.getIterator();
 while(iterator.hasNext())
 {
    Parameters recordParams = iterator.next();
    data = recordParams.get("testfield");
    // **** ADD THIS LINE ****
    data = com.platform.api.XSSEncoder.encodeForHTML(data);
    // ***********************
    break;
 }

%> <%=data%>. </body> </html> </syntaxhighlight>

5.3 Using JavaScript APIs to Encode Displayed Data

In JavaScript, use the jQuery Encoder APIs:

  • encodeForHTML - Encode data for display in an HTML page
  • encodeForHTMLAttribute - Encode data for display in an HTMLAttribute
  • encodeForJavascript - Encode data before inserting it into JavaScript code
  • encodeForURL - Encode data for use in a URL
Considerations
  • When the JSP/Html Page is set to include headers, the jQuery Encoder APIs are automatically included in the page.
  • When the JSP/Html page does not include platform headers, load the jQuery-encoder library as a Static Resource, and use it in your page

6 Document Templates Using Pages

Print templates in pages can be used to print records in any object. See Document Templates for an overview of Document Templates in the user interface.

Examples

  • Create an Expense Report to be used in expense management application
  • Print an Employee Benefit Form

Using Document Templates in pages is a two-step process:

  1. Create a Page that includes the desired print formatting
  2. Create a Document Template using a Page as the template type

6.1 Create a Page

  1. Click GearIcon.png > Customization > Developer Resources > Pages
  2. Click the [New Page] button
  3. Click the [Edit] Button
  4. Enter a Title (filename) for the Document Template; Include .jsp as the file extension
  5. Uncheck the Display with Tab Header checkbox
  6. Add appropriate code, as shown in the next section.
  7. Click [Save]

6.2 Get Object and Record ID from the Request Object

When a JSP Page is launched from a context that is associated with a particular object record, the request object available in the JSP page contains the identifiers needed to obtain additional information from the record, using either the REST record Resource or the Java record handling APIs.

To get all of the parameters available in the request object, and their values:

<syntaxhighlight lang="java" enclose="div">

<%

 String[] params = request.getParameterValues();
 for (int i=0; i<params.length; i++)
 {
   String paramName = params[i];
   String paramValue = request.getParameter( paramName );
 }

%> </syntaxhighlight>

To obtain a record identifier from a request object sent by the platform:

With the object ID and record ID, use the getRecord API to retrieve the record.
<syntaxhighlight lang="java" enclose="div">

<%

 String object_id = request.getParameter("object_id");
 String record_id = request.getParameter("record_id");

%> </syntaxhighlight>

Notepad.png

Note: Although the object_id is alphanumeric, it can be used in any API that requires an object name.

To obtain a record identifier from a request object sent by a Custom Action button:

This code gets the record IDs and uses the searchRecords API to retrieve the records:
<syntaxhighlight lang="java" enclose="div">

<%

 // Get the object ID and the comma separated list of record IDs
 String object_id = request.getParameter("object_id");
 String selectedRecords = request.getParameter("selectedRecords"); 
 // Break the comma-separated list into record IDs. 
 // Join them with "OR" operands for use when searching for the records
 String filterCriteria = "";
 if (selectedRecords != null)
 {
   StringTokenizer st = new StringTokenizer(selectedRecords,",");
   while (st.hasMoreTokens())
   {
     if ( !"".equals(filterCriteria.trim()))
     {
        // Criteria string isn't empty, and we're adding another expression
        // Prefix the new expression with a boolean OR operator
        filterCriteria += " OR "
     }
     filterCriteria += "record_id = "+ st.nextToken();
   }
 }
 // Use the filter criteria to fetch the selected records
 // Here, we ask for the record_id and name fields
 Result results;
 results = Functions.searchRecords(object_id , "record_id,name", filterCriteria);
 int resultCode = results.getCode();
 if (resultCode < 0)
 {
    // Error occurred
 }
 else if (resultCode == 0)
 {
   // No records found. (This situation should never occur.)
 }
 else
 {
   // Records retrieved successfully
   // Process them here
   ParametersIterator iterator = results.getIterator();
   while(iterator.hasNext())
   {
     Parameters params = iterator.next();
     String recordID = params.get("record_id");
     String recordName = params.get("name");
     // Take additional action according to your business logic
   }
 }

%> </syntaxhighlight>

6.3 Create a Document Template

This Document Template uses Page as the type of template, instead of HTML

  1. Click GearIcon.png > Customization > Objects > {object}
  2. Add a new Document Template, select Page type and select the .jsp Document Template file

7 Page and Controller Examples

7.1 Example: Add a Contact using a Page and a Class

This example describes how to add a Contact using a Page and Class.

7.1.1 Create the Class

  1. Create a class, following the instructions at Adding a Class
  2. Copy and paste the following code into the class, and name it AddContact
<syntaxhighlight lang="java" enclose="div">

import java.util.*; import com.platform.api.*;

public class AddContact implements Controller {

 public ControllerResponse execute(HashMap params) throws Exception
 {
     String action = (String)params.get("action");
     if(action == null || action.equals(""))
     {
         Logger.info("Action - null?", "AddContact");            
         action = "Add";
     }
     if(action.equals("Add"))
     {
          Logger.info("Action - not null?" + action, "AddContact");
          return addContact(params);
     }
     else
     {
                             
     }
     return null;
 }
 private ControllerResponse addContact(HashMap params) 
   throws Exception
 {
     ControllerResponse cr = new ControllerResponse();
     Result result = null;
                               
     try
     {
       Parameters addOptions = Functions.getParametersInstance();
       addOptions.add("object_id", "Contacts");
       String addFirstName = (String)params.get("addFirstName");
                   
       String addLastName = (String)params.get("addLastName");
                           
       if(addLastName != null && !addLastName.equals("") 
             && addFirstName != null && !addFirstName.equals(""))
       {
           addOptions.add("first_name", addFirstName);
                     
           addOptions.add("last_name", addLastName);
       }
       else
       {
          addOptions.add("first_name", "CPfirst"+new Date());
          addOptions.add("last_name", "CPLast" + new Date());
          addOptions.add("account_id", "1593373443");
       } 
       result = Functions.addRecord("Contacts", addOptions);
       Logger.info("Message:" + result.getMessage(), "AddContact");
       cr.setData(result);
       cr.setTargetPage("AddContact.jsp");
     }
     catch(Exception e)
     {
        cr.setTargetPage("AddContact.jsp");
        cr.setMessage(e.getMessage());
               
        Logger.info("Message:", "AddContact");          
     }
     return cr;
 }

} </syntaxhighlight>

7.1.2 Create the Page

  1. Create a page, following the instructions at Adding a Page
  2. Copy and paste the following code into the page, and name it AddContact.jsp
<syntaxhighlight lang="java" enclose="div">

<body>

<form name = "mainForm" action="/networking/controller/com/platform/demo/samples/AddContact" method="POST">

</body> </html> </syntaxhighlight> Now the page is ready to be invoked from browser or web tab.

7.2 Example: Submit Data that Includes a File Attachment

This example uploads a file selected by a user.

7.2.1 Create the Class

  1. Create a class, following the instructions at Adding a Class
  2. Copy and paste the following code into the class (minus the footnotes), and name it SampleController
<syntaxhighlight lang="java" enclose="div">

package com.platform.{yourNamespace}.{yourPackage}; --[1]

import java.util.*; import com.platform.beans.*; import com.platform.api.*;

public class SampleController implements Controller {

  public ControllerResponse execute(HashMap parameters) throws Exception 
  { 
     ControllerResponse response = new ControllerResponse(); 
     // Or extract the parameter into a PlatformFileBean for use elsewhere
     Parameters params = Functions.getParametersInstance(); 
        /* ... add additional parameters, as required... */
     PlatformFileBean fileBean = (PlatformFileBean)parameters.get("attached_file");  --[2]
     params.add("someFieldName", fileBean); 
     Functions.addRecord("SomeOtherObject",params); 
    
     // Set the target page and return
     response.setTargetPage("target.jsp"); 
     return response; 
  } 

} </syntaxhighlight>

Notes
  1. Fill in your organization's namespace and the package in which you are creating the class
  2. The name of the incoming field is "attached_file", in the form you'll create next.
    Learn more: PlatformFileBean javadocs

7.2.2 Create the Page

  1. Create a page, following the instructions at Adding a Page
  2. Copy and paste the following code into the page (minus the footnotes).
  3. Fill in your organization's namespace and the package in which you created the class.
<syntaxhighlight lang="java" enclose="div">

<%@taglib prefix="lj" uri="/LJTagLib"%> --[1] <html> <head></head> <body> <form name="mainForm"

  enctype="multipart/form-data"                                                      --[2]
  action="/networking/multipartController/com/platform/{ns}/{pkg}/SampleController"  --[3]
  method="POST"> 
  <lj:file name="attached_file" id="attached_file" size="15" value=""/>              --[4]
     
     
  <input type="submit" name="action" value="upload" /> 

</form> </body> </html> </syntaxhighlight>

Notes
  1. Include the platform's Tag Library
  2. Specify the encoding type as a multi-part form
  3. Specify the platform's multipartController handler for the class.
    Fill in your organization's namespace and the package in which you created the class.
  4. Use the Tag Library's file tag to allow the user to browse for a file, and to submit the resulting selection as multi-part data.

8 Lookup Examples

8.1 Search based on Lastname

This example performs a search action in a lookup window based on "Lastname" as the Record Locator:

Add a Page:

  1. Add a Page
  2. Use this file name: AccountPopup.jsp
  3. Use this code sample: AccountPopup.jsp

Add a AccountPopup.java Class:

  1. Add a Class
  2. Use this file name: AccountPopup.java
  3. Use this code sample: AccountPopup.java

Add a AccountPopupController.java Class:

  1. Add a Class
  2. Use this file name: AccountPopupController.java
  3. Use this code sample: AccountPopupController.java

8.2 Search based on multiple fields

This example performs a search action in a lookup window using Multiple Fields in the Record Locator:

Prerequisite: In the Directory object, define the Record Locator fields to include "First name" and "Last name".

Add a Page
  1. From the Directory object, Add a Page
  2. Use this file name: DirectoryPopup.jsp
  3. Use this code sample: DirectoryPopup.jsp
Add a DirectoryPopup.java Class
  1. From the Directory object, Add a Class
  2. Use this file name: DirectoryPopup.java
  3. Use this code sample: DirectoryPopup.java
Add a DirectoryPopupController.java Class
  1. From the Directory object, Add a Class
  2. Use this file name: DirectoryPopupController.java
  3. Use this code sample: DirectoryPopupController.java

8.3 Multiple Fields in the Record Locator

If the Record Locator is a combination of fields, then it must be created by concatenating the field names.

For example, the record locator for the Employee object is a combination of First name, Last name. Then the record locator value is formed as: [First name value][space][-][space][Last name value]

<LABEL for="addFirstName"> First Name: </LABEL> <INPUT type="text" id="addFirstName" name="addFirstName" value="CPFirst">
<LABEL for="addLastName"> Last Name: </LABEL> <INPUT type="text" id="addLastName" name="addLastName" value="CPLast">
<INPUT type="submit" value="Add"> <INPUT type="reset">
   </form>
First name Last Name Record Locator Value
John Smith John - Smith
Peter Peter -
Jones - Jones

9 Global Pages

ISVs can create custom pages at the global level for distribution to Tenants. This feature gives Service Providers the ability to design and build pages once, then make the custom work available to multiple tenants, as the default Dashboard for Tenants, or added as Web Tabs.

Global Page access

Global Page access is defined by {namespace}, as shown in this URL:

https://{{domain}}/networking/isv/{namespace}/{globalpage.jsp}
where:
{yourDomain} is the Service Domain of the Service Provider
{namespace} is the namespace of the Service Provider, defined in Company Information
{globalpage.jsp} is the the name of the Page

9.1 Create a Global Page

  1. Click GearIcon.png > Customization > Developer Resources > Pages
  2. Click the [New Page] button, and complete the following information:
    Title
    Enter a title for the page, for example: pagename.jsp
    '.jsp' extension is required
    Display with Tab Header
    Checkbox
    Uncheck the Display with Tab Header option
  3. Enter the code in the text area
  4. Click [Save]

9.2 Using Global Pages

  1. Create a New Web Tab
  2. Choose URL as the Web Tab Type
  3. Paste the Global Page URI into the edit area:
    https://{{domain}}.com/networking/isv/{namespace}/{globalpage.jsp}
    Remember to substitute actual values for the {arguments}