Difference between revisions of "JavaScript"
imported>Aeric |
imported>Aeric m (Text replace - '{{jQuery}}' to '{{^jQuery}}') |
||
Line 21: | Line 21: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Or, using {{jQuery}} functions to shorten the syntax: | Or, using {{^jQuery}} functions to shorten the syntax: | ||
:<syntaxhighlight lang="javascript" enclose="div"> | :<syntaxhighlight lang="javascript" enclose="div"> | ||
var val = $('input[name=item_quantity]').val(); | var val = $('input[name=item_quantity]').val(); | ||
Line 55: | Line 55: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Or, using {{jQuery}} functions to shorten the syntax: | Or, using {{^jQuery}} functions to shorten the syntax: | ||
:<syntaxhighlight lang="javascript" enclose="div"> | :<syntaxhighlight lang="javascript" enclose="div"> | ||
var val = $('input[name=related_to_customer.zip_code]').val(); | var val = $('input[name=related_to_customer.zip_code]').val(); | ||
</syntaxhighlight> | </syntaxhighlight> |
Latest revision as of 22:00, 16 July 2012
This page provides general notes on using JavaScript in the platform.
About JavaScript
JavaScript is an object-oriented language that allows for functional programming. It is the language that drives much of the world wide web.
Learn more:
- Douglas Crockford's Survey of JavaScript
- JavaScript: The Good Parts, by Douglas Crockford
Using JavaScript in the Platform
JavaScript can be used in a variety of ways:
- Field Scripting - Add JavaScript code to take actions on a Field (On Change or On Focus)
- Form Scripting - Add JavaScript code to a Form (On Load or On Save)
- Post Selection JavaScript - Perform validations on Lookup Fields using JavaScript
- Action buttons - Add action buttons when displaying a record
- Manage Related Information sections - Add action buttons to sections that display Related Records
- In a JSP/HTML Page - Make things happen on the client side to reduce the load on the server.
Accessing Record Variables
You access record data using the Document Object Model (DOM). In the Sample Order Processing System, you might access a field in an OrderItem record like this:
var val = document.getElementById("item_quantity").value;
Or, using jQuery functions to shorten the syntax:
var val = $('input[name=item_quantity]').val();
Reference Information
JavaScript Functions
These functions are available anywhere that JavaScript is running on the platform.
showTab
Display an object list view (list of object records) as a tab in the GUI.
- Syntax
showTab(key, tabTitle, url);
- Parameters
-
- key - Unique key that identifies the tab. Object ID is recommended.
- tabTitle - The tab label.
- url - The URL used to render the view, in the form: Service?t=499&object_id={id}
- Optionally, add &show_layout={viewId} to specify a particular view.
Learn more:
- Sample Usage
Here is the basic usage pattern:
<a href="javascript:top.showTab('{objectId}','{Tab title}', 'Service?t=499&object_id={objectId}');">{Link title}</a>
Show the default view of the Orders Object (ID=bd5b766236dd487c8cce3648bd5ffe64)
<a href="javascript:top.showTab('bd5b766236dd487c8cce3648bd5ffe64','Orders', 'Service?t=499&object_id=bd5b766236dd487c8cce3648bd5ffe64');">View Orders</a>
Show a specific view with ID de5dnnn8798, instead of the default view:
<a href="javascript:top.showTab('bd5b766236dd487c8cce3648bd5ffe64','Orders', 'Service?t=499&object_id=bd5b766236dd487c8cce3648bd5ffe6464 &show_layout=de5dnnn8798');">Orders</a>
showTabInIFrame
Display a record form as a tab in the GUI, using the form either to add a record to an object or to display record details.
- Syntax
showTabInIframe(key, tabTitle, url, preserveTabTitle);
- Parameters
-
- key - Unique key that identifies the tab. {objectId}-1 is recommended.
- When a new record is displayed using that key, the tab is reused. Adding a dash and a one differentiates the record tab from a view tab.
- Using the record ID for that purpose isn't recommended, because records in different objects could conceivably have the same record ID.
- To make every record open in a different tab, you could use {objectId}-{recordId}
- tabTitle - The tab label.
- When displaying a record, the label is overwritten with the Object name and the Record Identifier
- Standard practice in that case is to use it as a temporary label. For example: 'Loading...'
- url - The URL used to display the record: Service?t=498&object_id={id}
- Add &id=-1&a=add to add a new record
- Add &id={recordId}&a=view&policyaction=view to display an existing record
- displayTitle - Boolean value that determines whether or not the specified title is used.
- If true, the specified title is used for the tab label. (Must be true for a temporary label to be displayed, as well.)
- If false, the Object name is used, instead.
Learn more:
- Sample Usage
Here is the basic usage pattern:
<a href="javascript:top.showTabInIframe('{objectId}-1','{Tab title}', 'Service?t=498&id=-1&a={action}&object_id={objectId}', true);">{Link Title}</a>
This example opens a tab to add a record to the Orders Object (ID=bd5b766236dd487c8cce3648bd5ffe64):
<a href="javascript:top.showTabInIframe('bd5b766236dd487c8cce3648bd5ffe64-1', 'New Order','Service?t=498&id=-1&a=add&object_id=bd5b766236dd487c8cce3648bd5ffe64');"> Add Order</a>
This example opens a tab to display a record, where:
- objectID = 088d7ac50c4349b5b08d06cc8fa4e732
- recordID = 255796565
<a href="javascript:top.showTabInIframe('088d7ac50c4349b5b08d06cc8fa4e732-1', 'Loading...','Service?t=498&id=255796565&object_id=088d7ac50c4349b5b08d06cc8fa4e732 &a=view&policyaction=view', true);">Details</a>
lj_closeDialog
Close the current dialog. Typically used in conjunction with lj_refreshCurrentTab.
- Syntax
lj_refreshCurrentTab();
- Sample Usage
function closeDialog() { if ( $.browser.msie ) { top.lj_closeDialog() top.lj_refreshCurrentTab(); } else { top.getActiveTabWindow().lj_refreshTab(); top.lj_closeDialog(); } }
lj_printRecord
This function displays a customized print dialog for a record. Use it to set defaults, to limit the available choices, and to choose the Print Template which is used. (It is only available for Custom Objects.)
- Syntax
lj_printRecord('{option1}={value}&{option2}={value}&...');
- Parameters
Each option has two parameters: One to specify a default value, the other to determine whether it should be displayed so it can be overridden by the user.
By default, an option is always shown, unless explicitly hidden.
Parameter Description default_print_layout form (default) - use a Print Form
template - use a Print Templateshow_print_layout yes (default) - allows user to specify which kind of layout to use default_print_document The name of the form or template to pre-select in the list of possible choices. show_print_document yes - allows user to change the default choice print_immediately no (default) - The print dialog is shown. The user can then change any options that are displayed. Printing occurs when the user clicks the Print button).
yes - printing occurs immediately and the results are displayed in a new window. (It only works if both default_print_layout and default_print_document are specified.)default_page_orientation portrait (default) or landscape show_page_orientation yes - allows user to change page orientation default_pdf yes - otherwise, an HTML page is generated show_pdf yes - allows user to choose HTML or PDF
- Sample Usage
This code adds a [Custom Print] button to a Form, when placed in an On Load Form Script.
In this case, the goal is to restrict a user who has access to that form to a specific template. (The standard Print operation makes all templates available. A standard Action button, meanwhile, is present in every form. This code puts the button in a specific form, to restrict template access for users whose role causes it to be displayed.)
$("#print_button").remove(); $("#edit_button").parent().append( "<input type='button' id='customPrint' value='Custom Print' class='lj-button fg-button ui-state-default ui-corner-all' onClick=\"javascript:lj_printRecord('default_print_layout=template&show_print_layout=no&default_print_document=jsp&default_page_orientation=landscape&default_pdf=yes&show_pdf=no&print_immediately=yes');\">" );
- How the code works
-
- $("#print_button").remove()
- Remove the standard print button
- $("#edit_button").parent().append
- Finds the location of the edit button (present in every form), gets it's parent (the toolbar), and adds the new button to it.
- class='lj-button fg-button ui-state-default ui-corner-all'
- The standard CSS style elements for platform buttons.
- <input type='button' ...
- Define the button. (The entire string is one uninterrupted line.)
- onClick=\"javascript:lj_printRecord(...
- Specify the button's action
lj_refreshCurrentTab
Refresh the current tab. Typically used in conjunction with lj_closeDialog
- Syntax
lj_refreshCurrentTab();
- Sample Usage
function closeDialog() { if ( $.browser.msie ) { top.lj_closeDialog() top.lj_refreshCurrentTab(); } else { top.getActiveTabWindow().lj_refreshTab(); top.lj_closeDialog(); } }
lj_refreshTab
Refresh a specific tab. Typically used in conjunction with lj_closeDialog
- Syntax
{window}.lj_refreshTab();
- Sample Usage
function closeDialog() { if ( $.browser.msie ) { top.lj_closeDialog() top.lj_refreshCurrentTab(); } else { top.getActiveTabWindow().lj_refreshTab(); top.lj_closeDialog(); } }
lj_showDialog
This function displays a JSP/HTML Page as a dialog.
- Syntax
lj_showDialog(url, height, width, "dialog style", "title");
- Parameters
Parameter Description url A string that gives the URL of a JSP/HTML Page in the platform, in the form /networking/pages/SomePage.jsp with optional query parameters to pass data: ?param1=abc¶m2=xyz&... height The height of the dialog window, in pixels. width The width of the dialog window, in pixels. dialog style A string that specifies the display style. - popupdialogWithCloser - Displays the dialog with a close button.
- popupdialog - Displays the dialog without a close button.
- Note:
There is also no close icon in the corner, with this option.
When using it, add your own controls to close the dialog.
title Displayed in the banner of the dialog.
- Sample Usage
This sample displays a page at the specified URL in a popup dialog that has a close button.
var url = "/networking/pages/MyPage.jsp?recordId="+someValue + "&returnUrl="+encodeURIComponent(lj_window_src); top.lj_showDialog(url,300,350,"popupdialogWithCloser","My Page Title");
Global JavaScript Variables
The following JavaScript variables are global. They are available in all JavaScript code running on the platform.
- Considerations
-
- Variable names are case-sensitive
- In a Site, no one is logged in, and the page is not running on the platform, so the variables have no meaning in that context.
User Variables
- LJUserName
- Name of the (logged in) User
- LJPrimaryTeamName
- Name of the Primary Team (user is a member of this team)
- LJPrimaryTeamRoleName
- Role of the User in the Primary Team
Page Variables
- lj_window_src
- Contains the URL of the current page. (Needs to be URL encoded when used.)
- Sample Usage
encodeURIComponent(lj_window_src)
Template Variables for Actions and Components
About the Template Variable Tool
Use the Template Variable tool (shown below) to insert variables for:
Note: In some contexts, variable names uses braces - { }. In other cases, they don't. The Template Variable Tool lets you quickly determine the format used in your current context.
- Learn more: Template Variables
About Template Variables
AJAX and REST can be used to communicate with the platform, by writing JavaScript in an Action. The following implicit variables are available in the JavaScript:
- object_id
- A variable containing the identifier of the object
- selectedRecords
- An array containing one element - the identifier of the selected record
- Examples
- Identifier of the object that the user selected:
- alert("You have selected object : " + object_id);
- Dialog that shows the identifier of the first selected record:
- alert("You have selected Record : " + selectedRecords[0];
Lookup a Template Variable
- Choose a Category.
- Category
- Each category contains a number of fields. The list of categories depends on your context.
- Choose a field from the Category.
- Fields
- Contains the available fields from the selected category.
The Variable Field is populated with the syntax for your choice
- Copy the string and paste it into your work
- Variable field
- {$account.name}
Template Variables for Component Actions
The following template variables are available for use in Actions in Components. Some template variables are not evaluated when the action is executed. In the following table:
- "Yes" indicates that the template variable is evaluated when the action is executed
- "--" indicates that the template variable is not evaluated when the action is executed
- A warning message is displayed when a template variable is included that is of the not evaluated type.
Category Template Variable Single Record Group Action Both Single Record
Both Group Action
Object {$fieldname} Yes -- Yes -- $ObjectID {$object_id} Yes Yes Yes Yes $GROUP_ACTION {$GROUP_ACTION.ids} Yes Yes Yes Yes $CUSTOM_CONTROL {$CUSTOM_CONTROL.[ComponentName]} Yes Yes Yes Yes User {$user.today} Yes Yes Yes Yes {$user.full_name} Yes Yes Yes Yes {$user.first_name} Yes Yes Yes Yes {$user.last_name} Yes Yes Yes Yes {$user.email} Yes Yes Yes Yes {$user.phone} Yes Yes Yes Yes {$user.city} Yes Yes Yes Yes {$user.state} Yes Yes Yes Yes {$user.zip} Yes Yes Yes Yes {$user.country} Yes Yes Yes Yes {$user.title} Yes Yes Yes Yes {$user.division} Yes Yes Yes Yes {$user.fax} Yes Yes Yes Yes {$user.mobile} Yes Yes Yes Yes
Template Variables for Actions Using Execute JavaScript
The following JavaScript template variables are available for use in Actions using the Execute JavaScript option. Some template variables are not evaluated when the action is executed. In the following table:
- "Yes" indicates that the template variable is evaluated when the action is executed
- "--" indicates that the template variable is not evaluated when the action is executed.
- A warning message is displayed when a template variable is included that is of the not evaluated type.
Category Template Variable Single Record Group Action Both Single Record
Both Group Action
Object {$fieldname} Yes -- Yes -- $AppSessionID {$AppSessionID} Yes Yes Yes Yes User {$user.today} Yes Yes Yes Yes {$user.full_name} Yes Yes Yes Yes {$user.first_name} Yes Yes Yes Yes {$user.last_name} Yes Yes Yes Yes {$user.email} Yes Yes Yes Yes {$user.phone} Yes Yes Yes Yes {$user.city} Yes Yes Yes Yes {$user.state} Yes Yes Yes Yes {$user.zip} Yes Yes Yes Yes {$user.country} Yes Yes Yes Yes {$user.title} Yes Yes Yes Yes {$user.division} Yes Yes Yes Yes {$user.fax} Yes Yes Yes Yes {$user.mobile} Yes Yes Yes Yes
AJAX and REST
The combination of JavaScript and the platform's REST APIs lets you build a lot of power into a page that displays on a client-side browser.
About AJAX
AJAX is the name given to a set of JavaScript functions that let you connect to a server, get back data, and parse the data into something usable. It originally stood for "Asynchronous JavaScript and XML", but it can also use the JSON format for data interchange.
In fact, an arbitrary string can be passed to or from the server. It's just a matter of having a functions that can deal with the data in the string. The two most popular formats by far, however, are XML and JSON. The platform understands both, so you can choose the flavor you prefer.
Perhaps the best summary of AJAX comes from the w3c.schools tutorial:
- "AJAX is the art of exchanging data with a server, and updating parts of a web page, without reloading the whole page."
Note: When you create a Page in the platform, you are creating a JSP page. You can embed Java code in that page, and use it to directly interact with the platform. Or you can use AJAX and the REST APIs, whichever is easiest.
- Learn more:
- AJAX Tutorial: http://www.w3schools.com/ajax/
Basic AJAX Syntax
In this syntax description, xmlhttp is the communications object. You'll learn how to make one in the example that follows. For now, the focus is on the methods you use to interact with it.
xmlhttp.open(method, resource_url, async); xmlhttp.send(); // GET or DELETE xmlhttp.send("request data"); // POST or PUT
- where:
- method is GET, POST, PUT, or DELETE
- resource_url is the resource you are accessing
- async is a boolean.
- If true, you put processing code into an onreadystatechange function, and the page continues displaying itself while the request is being processed. Whenever the response from the server is received, it is integrated into the page. (That is the preferred way to do things.)
- If false, you put processing code after the send() statement. (You don't need a function, but the page may appear to hang while it is being rendered, so this procedure is not recommended.)
- Considerations
- Most often, you'll want to make asynchronous requests. They're slightly harder to write, because you have to add the onreadystatechange function. But the page won't hang while waiting for the server to respond.
- The platform's REST APIs return XML, by default. To get back JSON data, you append "?alt=JSON" to the URL.
- When a resource that responds to a GET request takes additional data, the data is included by appending a query string to the URL, in order to Specify Query Parameters.
- Platform GET (read), PUT (update), and DELETE requests return 200 on success.
- Platform POST (create) requests return 201 on success.
Tip: In Firefox, the Firebug plugin makes it possible to debug JavaScript. You can set breakpoints, see the content of variables, and review the structure of the internal DOM after elements have been dynamically added.
Example: Retrieving Data with a GET Request
This example shows AJAX code in a JSP page being used to get login status.
Of course, the example is trivial, since login status will always be "true". (Otherwise, you couldn't see the page at all.) But even this simple example displays a number of interesting characteristics, called out in the code that follows:
- Although this is a plain HTML page that doesn't contain any JSP code, it must have a .jsp extension, to be stored on the platform. (JSP code can then be added whenever desired.)
- As shown by the sample response, the data is returned in JSON format. That format works well in JavaScript, because the eval() function can be used to turn it into a set of objects, making it easy to retrieve the nested is_session_valid value in the next line.
- A query argument on the URL tells the platform to return the data in JSON format.
- The value we're interested in is contained in the JSON data. The is_session_valid value is in user, and user is in platform. So the path to access it that value is platform.user.is_session_valid.
<html> // #1 <head> <script type="text/javascript"> function getInfo() { // Create a communications object. var xmlhttp; if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); } else { // code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } // Configure the comms object with the function // that runs when a response is received. xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { // Success. Insert returned data into the page. text = "<pre>" + xmlhttp.responseText + "</pre>"; var reply = eval('(' + xmlhttp.responseText + ')'); // #2 result = reply.platform.user.is_session_valid; text += "Result: " + result; document.getElementById("myDiv").innerHTML=text; } } // Set up the request and send it to the server resource = "/networking/rest/user/isSessionValid?alt=json"; // #3 async = true; xmlhttp.open("GET", resource, async); xmlhttp.send(); } </script> </head> <body> <div id="myDiv"><h2>Click the button to check status.</h2></div> <button type="button" onclick="getInfo()">Ok</button> </body> </html>
Visiting the page and clicking the button echoes the response returned by server:
{"platform": { // #2 "message": { "code": "0", "description": "Success" }, "user": {"is_session_valid": "true"} // #4 }} Result: true
POST/PUT Syntax
When there is too much data to send using Query Parameters, a REST API will require you to send the data in a POST request (to add something new) or in a PUT request (to update something existing). You'll specify add a request header that tells the platform what form the data is in:
xmlhttp.open(method,resource_url,async); xmlhttp.setRequestHeader("Content-type","application/xml"); // or "application/json" xmlhttp.send("request data");
Example: Sending Data with a POST Request
This example adds a new entry to the ultra-simple Customers object in the Sample Order Processing System. To keep the example as simple as possible, the data is hard-wired into the script.
- Considerations
-
- In this case, we'll use a synchronous request, because we don't want the rest of the page to render until after the attempted POST has completed.
- A unique key has been defined for the Customer object, so only the first POST should succeed. Subsequent POSTs should fail.
- POST requests return 201 when successful (unlike other REST requests, which return 200).
<html> <head> <script type="text/javascript"> function createNewCustomer() { // Create the communications object. var xmlhttp; if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); } else { // code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } // Set up the request to send XML data to the server. // Make it synchronous, so we know how page rendering should proceed async = false; resource = "/networking/rest/record/customer?alt=json"; data = "<platform> \ <record> \ <customer_name>Ian</customer_name> \ <company_address>SoHo</company_address> \ </record> \ </platform>"; xmlhttp.open("POST", resource, async); xmlhttp.setRequestHeader("Content-type", "application/xml"); // or "application/json" xmlhttp.send(data); var text = ""; //text = "<pre>" + xmlhttp.responseText + "</pre>"; //For debugging // Echo the return value. Success = 201 var reply = eval('(' + xmlhttp.responseText + ')'); if (xmlhttp.readyState==4) { if (xmlhttp.status==201) { text += "Customer added successfully.<br/>"; text += "Record ID: " + reply.platform.message.id; } else { text += "Customer add failed.<br/>"; text += "HTTP Status = " + xmlhttp.status + "<br/>"; text += "Platform Status = " + reply.platform.message.code + "<br/>"; text += reply.platform.message.description; } } document.getElementById("myDiv").innerHTML=text; } </script> </head> <body> <div id="myDiv"><h2>Click the button to create a new customer.</h2></div> <button type="button" onclick="createNewCustomer()">Ok</button> </body> </html>
The result of a successful POST looks like this:
Customer added successfully. Record ID: 313913951
Accessing Additional Lookup Variables in a Form
When you have a Lookup field in a Form, you can select additional fields from the targeted record, and have them displayed in the Form.
For example, in the Sample Order Processing System, Order records have a lookup to the Customer that placed the order. The Lookup field shows the customer's name, by default. But you could specify additional fields to display in the form: The customer's address and contact information, for example.
When you write JavaScript for Field Scripting, Form Scripting, or Post-Selection JavaScript that JavaScript can use "dot notation" to access the values in the additional fields, by following this pattern:
{current_record_lookup_field}.{target_record_field}
For example, In an Order record, then, you might access the Customer's zip code to calculate a shipping charge, like this:
var val = document.getElementById("related_to_customer.zip_code").value;
Or, using jQuery functions to shorten the syntax:
var val = $('input[name=related_to_customer.zip_code]').val();